From e3244501184f2c0b6e422f6d566f8853fd6d27f1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Apr 2014 09:02:58 +0200 Subject: [PATCH 001/121] replaced return value of DocumentManager::addDocument with a signal --- apps/opencs/CMakeLists.txt | 4 ++-- apps/opencs/editor.cpp | 18 +++++++++------- apps/opencs/editor.hpp | 2 ++ apps/opencs/model/doc/documentmanager.cpp | 4 ++-- apps/opencs/model/doc/documentmanager.hpp | 25 +++++++++++++++-------- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index cbe90b1d3..1db922afa 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -5,11 +5,11 @@ opencs_units (. editor) set (CMAKE_BUILD_TYPE DEBUG) opencs_units (model/doc - document operation saving + document operation saving documentmanager ) opencs_units_noqt (model/doc - documentmanager stage savingstate savingstages + stage savingstate savingstages ) opencs_hdrs_noqt (model/doc diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 87660a60b..de6809839 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -37,6 +37,9 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) mNewGame.setLocalData (mLocal); mFileDialog.setLocalData (mLocal); + connect (&mDocumentManager, SIGNAL (documentAdded (CSMDoc::Document *)), + this, SLOT (documentAdded (CSMDoc::Document *))); + connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ())); @@ -150,9 +153,8 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath) foreach (const QString &path, mFileDialog.selectedFilePaths()) files.push_back(path.toUtf8().constData()); - CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false); + mDocumentManager.addDocument (files, savePath, false); - mViewManager.addView (document); mFileDialog.hide(); } @@ -166,9 +168,8 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath) files.push_back(mFileDialog.filename().toUtf8().constData()); - CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true); + mDocumentManager.addDocument (files, savePath, true); - mViewManager.addView (document); mFileDialog.hide(); } @@ -178,9 +179,7 @@ void CS::Editor::createNewGame (const boost::filesystem::path& file) files.push_back (file); - CSMDoc::Document *document = mDocumentManager.addDocument (files, file, true); - - mViewManager.addView (document); + mDocumentManager.addDocument (files, file, true); mNewGame.hide(); } @@ -287,3 +286,8 @@ std::auto_ptr CS::Editor::setupGraphics() return factory; } + +void CS::Editor::documentAdded (CSMDoc::Document *document) +{ + mViewManager.addView (document); +} \ No newline at end of file diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 164398fb7..53afee048 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -85,6 +85,8 @@ namespace CS void showSettings(); + void documentAdded (CSMDoc::Document *document); + private: QString mIpcServerName; diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 3ff75c9c1..3f19269e7 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -27,14 +27,14 @@ CSMDoc::DocumentManager::~DocumentManager() delete *iter; } -CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, +void CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { Document *document = new Document (mConfiguration, files, savePath, mResDir, new_); mDocuments.push_back (document); - return document; + emit documentAdded (document); } bool CSMDoc::DocumentManager::removeDocument (Document *document) diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index b969862e9..e41c49029 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -6,6 +6,8 @@ #include +#include + namespace Files { class ConfigurationManager; @@ -15,8 +17,10 @@ namespace CSMDoc { class Document; - class DocumentManager + class DocumentManager : public QObject { + Q_OBJECT + std::vector mDocuments; const Files::ConfigurationManager& mConfiguration; @@ -29,20 +33,23 @@ namespace CSMDoc ~DocumentManager(); - Document *addDocument (const std::vector< boost::filesystem::path >& files, - const boost::filesystem::path& savePath, - bool new_); - ///< The ownership of the returned document is not transferred to the caller. - /// - /// \param new_ Do not load the last content file in \a files and instead create in an + void addDocument (const std::vector< boost::filesystem::path >& files, + const boost::filesystem::path& savePath, bool new_); + ///< \param new_ Do not load the last content file in \a files and instead create in an /// appropriate way. bool removeDocument (Document *document); ///< \return last document removed? + void setResourceDir (const boost::filesystem::path& parResDir); - - private: + + private: + boost::filesystem::path mResDir; + + signals: + + void documentAdded (CSMDoc::Document *document); }; } From dbb192f084c53be4ebb475ae63692b5a73a7128f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 24 Apr 2014 15:09:25 +0200 Subject: [PATCH 002/121] moved loading to a separate thread --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/doc/document.cpp | 86 ++++++++++------------- apps/opencs/model/doc/document.hpp | 7 +- apps/opencs/model/doc/documentmanager.cpp | 32 ++++++++- apps/opencs/model/doc/documentmanager.hpp | 16 +++++ apps/opencs/model/doc/loader.cpp | 66 +++++++++++++++++ apps/opencs/model/doc/loader.hpp | 55 +++++++++++++++ 7 files changed, 210 insertions(+), 54 deletions(-) create mode 100644 apps/opencs/model/doc/loader.cpp create mode 100644 apps/opencs/model/doc/loader.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 1db922afa..f1d50467b 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -5,7 +5,7 @@ opencs_units (. editor) set (CMAKE_BUILD_TYPE DEBUG) opencs_units (model/doc - document operation saving documentmanager + document operation saving documentmanager loader ) opencs_units_noqt (model/doc diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 3ef14ee7e..20a355d48 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2219,68 +2219,32 @@ void CSMDoc::Document::createBase() } } -CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_) - : mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), - mProjectPath ((configuration.getUserDataPath() / "projects") / - (savePath.filename().string() + ".project")), - mSaving (*this, mProjectPath) +CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, + const std::vector< boost::filesystem::path >& files, + const boost::filesystem::path& savePath, const boost::filesystem::path& resDir) +: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), + mProjectPath ((configuration.getUserDataPath() / "projects") / + (savePath.filename().string() + ".project")), + mSaving (*this, mProjectPath) { - if (files.empty()) + if (mContentFiles.empty()) throw std::runtime_error ("Empty content file sequence"); - if (new_ && files.size()==1) - createBase(); - else - { - std::vector::const_iterator end = files.end(); - - if (new_) - --end; - - load (files.begin(), end, !new_); - } - - if (new_) - { - mData.setDescription (""); - mData.setAuthor (""); - } - - bool filtersFound = false; - - if (boost::filesystem::exists (mProjectPath)) - { - filtersFound = true; - } - else + if (!boost::filesystem::exists (mProjectPath)) { boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath()); locCustomFiltersPath /= "defaultfilters"; - if (boost::filesystem::exists(locCustomFiltersPath)) + if (boost::filesystem::exists (locCustomFiltersPath)) { boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath); - filtersFound = true; } else { - boost::filesystem::path filters(mResDir); - filters /= "defaultfilters"; - - if (boost::filesystem::exists(filters)) - { - boost::filesystem::copy_file(filters, mProjectPath); - filtersFound = true; - } + boost::filesystem::copy_file (mResDir / "defaultfilters", mProjectPath); } } - if (filtersFound) - getData().loadFile (mProjectPath, false, true); - - addOptionalGmsts(); - addOptionalGlobals(); - connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool))); connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); @@ -2289,13 +2253,39 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int))); connect (&mSaving, SIGNAL (reportMessage (const QString&, int)), - this, SLOT (reportMessage (const QString&, int))); + this, SLOT (reportMessage (const QString&, int))); } CSMDoc::Document::~Document() { } +void CSMDoc::Document::setupData (bool new_) +{ + if (new_ && mContentFiles.size()==1) + createBase(); + else + { + std::vector::const_iterator end = mContentFiles.end(); + + if (new_) + --end; + + load (mContentFiles.begin(), end, !new_); + } + + if (new_) + { + mData.setDescription (""); + mData.setAuthor (""); + } + + getData().loadFile (mProjectPath, false, true); + + addOptionalGmsts(); + addOptionalGlobals(); +} + QUndoStack& CSMDoc::Document::getUndoStack() { return mUndoStack; diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 201fb4342..c7d87e16a 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -72,12 +72,13 @@ namespace CSMDoc public: Document (const Files::ConfigurationManager& configuration, - const std::vector< boost::filesystem::path >& files, - const boost::filesystem::path& savePath, - const boost::filesystem::path& resDir, bool new_); + const std::vector< boost::filesystem::path >& files, + const boost::filesystem::path& savePath, const boost::filesystem::path& resDir); ~Document(); + void setupData (bool new_); + QUndoStack& getUndoStack(); int getState() const; diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 3f19269e7..51774e4ff 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -19,10 +19,24 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con if (!boost::filesystem::is_directory (projectPath)) boost::filesystem::create_directories (projectPath); + + mLoader.moveToThread (&mLoaderThread); + mLoaderThread.start(); + + connect (&mLoader, SIGNAL (documentLoaded (Document *)), + this, SLOT (documentLoaded (Document *))); + connect (&mLoader, SIGNAL (documentNotLoaded (Document *, const std::string&)), + this, SLOT (documentNotLoaded (Document *, const std::string&))); + connect (this, SIGNAL (loadRequest (Document *, bool)), + &mLoader, SLOT (loadDocument (Document *, bool))); } CSMDoc::DocumentManager::~DocumentManager() { + mLoaderThread.quit(); + mLoader.hasThingsToDo().wakeAll(); + mLoaderThread.wait(); + for (std::vector::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter) delete *iter; } @@ -30,11 +44,13 @@ CSMDoc::DocumentManager::~DocumentManager() void CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - Document *document = new Document (mConfiguration, files, savePath, mResDir, new_); + Document *document = new Document (mConfiguration, files, savePath, mResDir); mDocuments.push_back (document); - emit documentAdded (document); + emit loadRequest (document, new_); + + mLoader.hasThingsToDo().wakeAll(); } bool CSMDoc::DocumentManager::removeDocument (Document *document) @@ -54,3 +70,15 @@ void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& par { mResDir = boost::filesystem::system_complete(parResDir); } + +void CSMDoc::DocumentManager::documentLoaded (Document *document) +{ + emit documentAdded (document); +} + +void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::string& error) +{ + removeDocument (document); + /// \todo report error + /// \todo handle removeDocument returning true +} \ No newline at end of file diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index e41c49029..c30c83c06 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -7,6 +7,9 @@ #include #include +#include + +#include "loader.hpp" namespace Files { @@ -23,6 +26,8 @@ namespace CSMDoc std::vector mDocuments; const Files::ConfigurationManager& mConfiguration; + QThread mLoaderThread; + Loader mLoader; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); @@ -47,9 +52,20 @@ namespace CSMDoc boost::filesystem::path mResDir; + private slots: + + void documentLoaded (Document *document); + ///< The ownership of \a document is not transferred. + + void documentNotLoaded (Document *document, const std::string& error); + ///< Document load has been interrupted either because of a call to abortLoading + /// or a problem during loading). In the former case error will be an empty string. + signals: void documentAdded (CSMDoc::Document *document); + + void loadRequest (Document *document, bool _new); }; } diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp new file mode 100644 index 000000000..722e90364 --- /dev/null +++ b/apps/opencs/model/doc/loader.cpp @@ -0,0 +1,66 @@ + +#include "loader.hpp" + +#include + +#include "document.hpp" + +CSMDoc::Loader::Loader() +{ + QTimer *timer = new QTimer (this); + + connect (timer, SIGNAL (timeout()), this, SLOT (load())); + timer->start (1000); +} + +QWaitCondition& CSMDoc::Loader::hasThingsToDo() +{ + return mThingsToDo; +} + +void CSMDoc::Loader::load() +{ + if (mDocuments.empty()) + { + mMutex.lock(); + mThingsToDo.wait (&mMutex); + mMutex.unlock(); + return; + } + + std::vector >::iterator iter = mDocuments.begin(); + + Document *document = iter->first; + bool new_ = iter->second; + + mDocuments.erase (iter); + + try + { + document->setupData (new_); + emit documentLoaded (document); + } + catch (const std::exception& e) + { + emit documentNotLoaded (document, e.what()); + } +} + +void CSMDoc::Loader::loadDocument (Document *document, bool new_) +{ + mDocuments.push_back (std::make_pair (document, new_)); +} + +void CSMDoc::Loader::abortLoading (Document *document) +{ + for (std::vector >::iterator iter = mDocuments.begin(); + iter!=mDocuments.end(); ++iter) + { + if (iter->first==document) + { + mDocuments.erase (iter); + emit documentNotLoaded (document, ""); + break; + } + } +} \ No newline at end of file diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp new file mode 100644 index 000000000..eae0c8001 --- /dev/null +++ b/apps/opencs/model/doc/loader.hpp @@ -0,0 +1,55 @@ +#ifndef CSM_DOC_LOADER_H +#define CSM_DOC_LOADER_H + +#include + +#include +#include +#include + +namespace CSMDoc +{ + class Document; + + class Loader : public QObject + { + Q_OBJECT + + QMutex mMutex; + QWaitCondition mThingsToDo; + std::vector > mDocuments; + + public: + + Loader(); + + QWaitCondition& hasThingsToDo(); + + private slots: + + void load(); + + public slots: + + void loadDocument (Document *document, bool new_); + ///< The ownership of \a document is not transferred. + /// \param new_ Do not load the last content file in the files list specified in + /// \a document and instead create it in an appropriate way. + + void abortLoading (Document *document); + ///< Abort loading \a docuemnt (ignored if \a document has already finished being + /// loaded). Will result in a documentNotLoaded signal, once the Loader has finished + /// cleaning up. + + signals: + + void documentLoaded (Document *document); + ///< The ownership of \a document is not transferred. + + void documentNotLoaded (Document *document, const std::string& error); + ///< Document load has been interrupted either because of a call to abortLoading + /// or a problem during loading). In the former case error will be an empty string. + }; +} + +#endif From ddb0496dca76d7aa357f20feabc857abc74dc151 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 26 Apr 2014 13:11:27 +0200 Subject: [PATCH 003/121] replaced return value of removeDocument with a signal --- apps/opencs/editor.cpp | 7 +++++++ apps/opencs/editor.hpp | 2 ++ apps/opencs/model/doc/documentmanager.cpp | 8 ++++---- apps/opencs/model/doc/documentmanager.hpp | 6 ++++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index de6809839..f13c85e73 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -39,6 +39,8 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) connect (&mDocumentManager, SIGNAL (documentAdded (CSMDoc::Document *)), this, SLOT (documentAdded (CSMDoc::Document *))); + connect (&mDocumentManager, SIGNAL (lastDocumentDeleted()), + this, SLOT (lastDocumentDeleted())); connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); @@ -290,4 +292,9 @@ std::auto_ptr CS::Editor::setupGraphics() void CS::Editor::documentAdded (CSMDoc::Document *document) { mViewManager.addView (document); +} + +void CS::Editor::lastDocumentDeleted() +{ + exit (0); } \ No newline at end of file diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 53afee048..d1825e5af 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -87,6 +87,8 @@ namespace CS void documentAdded (CSMDoc::Document *document); + void lastDocumentDeleted(); + private: QString mIpcServerName; diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 51774e4ff..b8372eb4c 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -53,17 +53,18 @@ void CSMDoc::DocumentManager::addDocument (const std::vector::iterator iter = std::find (mDocuments.begin(), mDocuments.end(), document); if (iter==mDocuments.end()) - throw std::runtime_error ("removing invalid document"); + throw std::runtime_error ("removing invalid document"); mDocuments.erase (iter); delete document; - return mDocuments.empty(); + if (mDocuments.empty()) + emit lastDocumentDeleted(); } void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& parResDir) @@ -80,5 +81,4 @@ void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std:: { removeDocument (document); /// \todo report error - /// \todo handle removeDocument returning true } \ No newline at end of file diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index c30c83c06..1af18a148 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -43,8 +43,8 @@ namespace CSMDoc ///< \param new_ Do not load the last content file in \a files and instead create in an /// appropriate way. - bool removeDocument (Document *document); - ///< \return last document removed? + void removeDocument (Document *document); + ///< Emits the lastDocumentDeleted signal, if applicable. void setResourceDir (const boost::filesystem::path& parResDir); @@ -66,6 +66,8 @@ namespace CSMDoc void documentAdded (CSMDoc::Document *document); void loadRequest (Document *document, bool _new); + + void lastDocumentDeleted(); }; } From 853abb65c3e7b87bcaced7225bebe9d7ea358644 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 29 Apr 2014 11:19:19 +0200 Subject: [PATCH 004/121] added new, later common, base for the regionmap and the table --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/tablemimedata.cpp | 2 +- apps/opencs/model/world/tablemimedata.hpp | 2 +- apps/opencs/view/world/dragrecordtable.cpp | 21 ++++++++++ apps/opencs/view/world/dragrecordtable.hpp | 36 ++++++++++++++++ apps/opencs/view/world/regionmap.cpp | 7 +++- apps/opencs/view/world/regionmap.hpp | 2 + apps/opencs/view/world/table.cpp | 49 ++++++++-------------- apps/opencs/view/world/table.hpp | 7 +++- 9 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 apps/opencs/view/world/dragrecordtable.cpp create mode 100644 apps/opencs/view/world/dragrecordtable.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index cbe90b1d3..7a9320904 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap + scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable ) opencs_units (view/render diff --git a/apps/opencs/model/world/tablemimedata.cpp b/apps/opencs/model/world/tablemimedata.cpp index d7b7728a5..93810a252 100644 --- a/apps/opencs/model/world/tablemimedata.cpp +++ b/apps/opencs/model/world/tablemimedata.cpp @@ -11,7 +11,7 @@ mDocument(document) mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str()); } -CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) : +CSMWorld::TableMimeData::TableMimeData (const std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) : mUniversalId (id), mDocument(document) { for (std::vector::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it) diff --git a/apps/opencs/model/world/tablemimedata.hpp b/apps/opencs/model/world/tablemimedata.hpp index adcb147c1..9ca712801 100644 --- a/apps/opencs/model/world/tablemimedata.hpp +++ b/apps/opencs/model/world/tablemimedata.hpp @@ -33,7 +33,7 @@ namespace CSMWorld public: TableMimeData(UniversalId id, const CSMDoc::Document& document); - TableMimeData(std::vector& id, const CSMDoc::Document& document); + TableMimeData(const std::vector& id, const CSMDoc::Document& document); ~TableMimeData(); diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp new file mode 100644 index 000000000..4aa13308a --- /dev/null +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -0,0 +1,21 @@ +#include + +#include "../../model/world/tablemimedata.hpp" +#include "dragrecordtable.hpp" + +void CSVWorld::DragRecordTable::startDrag (const CSVWorld::DragRecordTable& table) +{ + CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (table.getDragedRecords(), mDocument); + + if (mime) + { + QDrag* drag = new QDrag (this); + drag->setMimeData (mime); + drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str())); + drag->exec (Qt::CopyAction); + } +} + +CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document) : +mDocument(document) +{} diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp new file mode 100644 index 000000000..4e5389f06 --- /dev/null +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -0,0 +1,36 @@ +#ifndef CSV_WORLD_REGIONMAP_H +#define CSV_WORLD_REGIONMAP_H + +#include + +class QAction; + +namespace CSMDoc +{ + class Document; +} + +namespace CSMWorld +{ + class UniversalId; +} + +namespace CSVWorld +{ + class DragRecordTable : public QTableView + { + protected: + CSMDoc::Document& mDocument; + + public: + DragRecordTable(CSMDoc::Document& document); + + virtual std::vector getDragedRecords() const = 0; + + protected: + void startDrag(const DragRecordTable& table); + }; +} + +#endif + diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 738de89ae..bfce1fce4 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -17,6 +17,7 @@ #include "../../model/world/idtable.hpp" #include "../../model/world/commands.hpp" #include "../../model/world/columns.hpp" +#include "../../model/world/tablemimedata.hpp" void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event) { @@ -343,4 +344,8 @@ void CSVWorld::RegionMap::viewInTable() hint << ")"; emit editRequest (CSMWorld::UniversalId::Type_Cells, hint.str()); -} \ No newline at end of file +} + +void CSVWorld::RegionMap::mouseMoveEvent (QMouseEvent* event) +{ +} diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index c3757fe45..d894fd9cc 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -50,6 +50,8 @@ namespace CSVWorld void setRegion (const std::string& regionId); ///< Set region Id of selected cells. + void mouseMoveEvent(QMouseEvent *event); + public: RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 712b8f556..d700d5f2e 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -189,7 +189,7 @@ std::vector CSVWorld::Table::listDeletableSelectedIds() const CSVWorld::Table::Table (const CSMWorld::UniversalId& id, bool createAndDelete, bool sorting, CSMDoc::Document& document) : mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0), - mDocument (document) + DragRecordTable(document) { mModel = &dynamic_cast (*mDocument.getData().getTableModel (id)); @@ -512,37 +512,8 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event) { if (event->buttons() & Qt::LeftButton) { - QModelIndexList selectedRows = selectionModel()->selectedRows(); - - if (selectedRows.size() == 0) - { - return; - } - - QDrag* drag = new QDrag (this); - CSMWorld::TableMimeData* mime = NULL; - - if (selectedRows.size() == 1) - { - mime = new CSMWorld::TableMimeData (getUniversalId (selectedRows.begin()->row()), mDocument); - } - else - { - std::vector idToDrag; - - foreach (QModelIndex it, selectedRows) //I had a dream. Dream where you could use C++11 in OpenMW. - { - idToDrag.push_back (getUniversalId (it.row())); - } - - mime = new CSMWorld::TableMimeData (idToDrag, mDocument); - } - - drag->setMimeData (mime); - drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str())); - drag->exec(Qt::CopyAction); + startDrag(*this); } - } void CSVWorld::Table::dragEnterEvent(QDragEnterEvent *event) @@ -598,4 +569,18 @@ std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column } } return titles; -} \ No newline at end of file +} + +std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDragedRecords() const +{ + + QModelIndexList selectedRows = selectionModel()->selectedRows(); + std::vector idToDrag; + + foreach (QModelIndex it, selectedRows) //I had a dream. Dream where you could use C++11 in OpenMW. + { + idToDrag.push_back (getUniversalId (it.row())); + } + + return idToDrag; +} diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 4231a4a43..926ba0e95 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -9,6 +9,7 @@ #include "../../model/filter/node.hpp" #include "../../model/world/columnbase.hpp" +#include "dragrecordtable.hpp" class QUndoStack; class QAction; @@ -24,6 +25,7 @@ namespace CSMWorld class UniversalId; class IdTableProxyModel; class IdTable; + class TableMimeData; } namespace CSVWorld @@ -31,7 +33,7 @@ namespace CSVWorld class CommandDelegate; ///< Table widget - class Table : public QTableView + class Table : public DragRecordTable { Q_OBJECT @@ -49,7 +51,6 @@ namespace CSVWorld CSMWorld::IdTable *mModel; bool mEditLock; int mRecordStatusDisplay; - CSMDoc::Document& mDocument; private: @@ -82,6 +83,8 @@ namespace CSVWorld std::vector getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const; + virtual std::vector getDragedRecords() const; + signals: void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); From 18fc8acc71c5d8839668c1cadc2555fdc6b4b438 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 29 Apr 2014 12:27:26 +0200 Subject: [PATCH 005/121] able to drag existing cells from the regionmap --- apps/opencs/view/world/dragrecordtable.cpp | 5 +++-- apps/opencs/view/world/dragrecordtable.hpp | 9 +++++---- apps/opencs/view/world/regionmap.cpp | 17 ++++++++++++++++- apps/opencs/view/world/regionmap.hpp | 11 +++++++++-- apps/opencs/view/world/table.hpp | 2 -- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp index 4aa13308a..f962f6f10 100644 --- a/apps/opencs/view/world/dragrecordtable.cpp +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -16,6 +16,7 @@ void CSVWorld::DragRecordTable::startDrag (const CSVWorld::DragRecordTable& tabl } } -CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document) : -mDocument(document) +CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document, QWidget* parent) : +mDocument(document), +QTableView(parent) {} diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp index 4e5389f06..7a2b51743 100644 --- a/apps/opencs/view/world/dragrecordtable.hpp +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -1,8 +1,9 @@ -#ifndef CSV_WORLD_REGIONMAP_H -#define CSV_WORLD_REGIONMAP_H +#ifndef CSV_WORLD_DRAGRECORDTABLE_H +#define CSV_WORLD_DRAGRECORDTABLE_H #include +class QWidget; class QAction; namespace CSMDoc @@ -23,7 +24,7 @@ namespace CSVWorld CSMDoc::Document& mDocument; public: - DragRecordTable(CSMDoc::Document& document); + DragRecordTable(CSMDoc::Document& document, QWidget* parent = NULL); virtual std::vector getDragedRecords() const = 0; @@ -33,4 +34,4 @@ namespace CSVWorld } #endif - + diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index bfce1fce4..85b79c3f2 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -181,7 +181,7 @@ void CSVWorld::RegionMap::setRegion (const std::string& regionId) CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, QWidget *parent) -: QTableView (parent), mEditLock (false), mDocument (document) +: mEditLock (false), DragRecordTable(document, parent) { verticalHeader()->hide(); horizontalHeader()->hide(); @@ -348,4 +348,19 @@ void CSVWorld::RegionMap::viewInTable() void CSVWorld::RegionMap::mouseMoveEvent (QMouseEvent* event) { + startDrag(*this); +} + +std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDragedRecords() const +{ + QModelIndexList selected = getSelectedCells(); + std::vector ids; + foreach (QModelIndex it, selected) + { + ids.push_back( + CSMWorld::UniversalId + (CSMWorld::UniversalId::Type_Cell, + model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData())); + } + return ids; } diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index d894fd9cc..596ddfaed 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -1,8 +1,14 @@ #ifndef CSV_WORLD_REGIONMAP_H #define CSV_WORLD_REGIONMAP_H +#include +#include + +#include #include +#include "./dragrecordtable.hpp" + class QAction; namespace CSMDoc @@ -17,7 +23,7 @@ namespace CSMWorld namespace CSVWorld { - class RegionMap : public QTableView + class RegionMap : public DragRecordTable { Q_OBJECT @@ -30,7 +36,6 @@ namespace CSVWorld QAction *mViewAction; QAction *mViewInTableAction; bool mEditLock; - CSMDoc::Document& mDocument; std::string mRegionId; private: @@ -59,6 +64,8 @@ namespace CSVWorld void setEditLock (bool locked); + virtual std::vector getDragedRecords() const; + signals: void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 926ba0e95..30b487ce8 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -4,7 +4,6 @@ #include #include -#include #include #include "../../model/filter/node.hpp" @@ -25,7 +24,6 @@ namespace CSMWorld class UniversalId; class IdTableProxyModel; class IdTable; - class TableMimeData; } namespace CSVWorld From 5f1d2f72f6bf052f142485ba6cb5c1f7733ab40d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Apr 2014 14:17:25 +0200 Subject: [PATCH 006/121] added basic loading GUI --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/doc/documentmanager.cpp | 7 ++-- apps/opencs/model/doc/documentmanager.hpp | 5 ++- apps/opencs/model/doc/loader.cpp | 2 +- apps/opencs/model/doc/loader.hpp | 2 +- apps/opencs/view/doc/loader.cpp | 44 ++++++++++++++++++++++ apps/opencs/view/doc/loader.hpp | 46 +++++++++++++++++++++++ apps/opencs/view/doc/viewmanager.cpp | 7 ++++ apps/opencs/view/doc/viewmanager.hpp | 3 ++ 9 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 apps/opencs/view/doc/loader.cpp create mode 100644 apps/opencs/view/doc/loader.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index f1d50467b..e19242e09 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -44,7 +44,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc viewmanager view operations operation subview startup filedialog newgame - filewidget adjusterwidget + filewidget adjusterwidget loader ) diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index b8372eb4c..4658667c3 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -27,8 +27,8 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con this, SLOT (documentLoaded (Document *))); connect (&mLoader, SIGNAL (documentNotLoaded (Document *, const std::string&)), this, SLOT (documentNotLoaded (Document *, const std::string&))); - connect (this, SIGNAL (loadRequest (Document *, bool)), - &mLoader, SLOT (loadDocument (Document *, bool))); + connect (this, SIGNAL (loadRequest (CSMDoc::Document *, bool)), + &mLoader, SLOT (loadDocument (CSMDoc::Document *, bool))); } CSMDoc::DocumentManager::~DocumentManager() @@ -75,10 +75,11 @@ void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& par void CSMDoc::DocumentManager::documentLoaded (Document *document) { emit documentAdded (document); + emit loadingStopped (document, true, ""); } void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::string& error) { +// emit loadingStopped (document, false, error); removeDocument (document); - /// \todo report error } \ No newline at end of file diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 1af18a148..63ee5eb68 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -65,9 +65,12 @@ namespace CSMDoc void documentAdded (CSMDoc::Document *document); - void loadRequest (Document *document, bool _new); + void loadRequest (CSMDoc::Document *document, bool _new); void lastDocumentDeleted(); + + void loadingStopped (CSMDoc::Document *document, bool completed, + const std::string& error); }; } diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 722e90364..53827deb0 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -46,7 +46,7 @@ void CSMDoc::Loader::load() } } -void CSMDoc::Loader::loadDocument (Document *document, bool new_) +void CSMDoc::Loader::loadDocument (CSMDoc::Document *document, bool new_) { mDocuments.push_back (std::make_pair (document, new_)); } diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index eae0c8001..af266d52b 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -31,7 +31,7 @@ namespace CSMDoc public slots: - void loadDocument (Document *document, bool new_); + void loadDocument (CSMDoc::Document *document, bool new_); ///< The ownership of \a document is not transferred. /// \param new_ Do not load the last content file in the files list specified in /// \a document and instead create it in an appropriate way. diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp new file mode 100644 index 000000000..f840ab717 --- /dev/null +++ b/apps/opencs/view/doc/loader.cpp @@ -0,0 +1,44 @@ + +#include "loader.hpp" + +#include "../../model/doc/document.hpp" + +CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) +{ + setWindowTitle (("Loading " + document->getSavePath().filename().string()).c_str()); + show(); +} + + +CSVDoc::Loader::Loader() +{ + +} + +CSVDoc::Loader::~Loader() +{ + for (std::map::iterator iter (mDocuments.begin()); + iter!=mDocuments.end(); ++iter) + delete iter->second; +} + +void CSVDoc::Loader::add (CSMDoc::Document *document, bool new_) +{ + mDocuments.insert (std::make_pair (document, new LoadingDocument (document))); +} + +void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed, + const std::string& error) +{ + if (completed || error.empty()) + { + for (std::map::iterator iter (mDocuments.begin()); + iter!=mDocuments.end(); ++iter) + if (iter->first==document) + { + delete iter->second; + mDocuments.erase (iter); + break; + } + } +} \ No newline at end of file diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp new file mode 100644 index 000000000..4aa497482 --- /dev/null +++ b/apps/opencs/view/doc/loader.hpp @@ -0,0 +1,46 @@ +#ifndef CSV_DOC_LOADER_H +#define CSV_DOC_LOADER_H + +#include + +#include +#include + +namespace CSMDoc +{ + class Document; +} + +namespace CSVDoc +{ + class LoadingDocument : public QWidget + { + Q_OBJECT + + public: + + LoadingDocument (CSMDoc::Document *document); + }; + + class Loader : public QObject + { + Q_OBJECT + + std::map mDocuments; + + public: + + Loader(); + + virtual ~Loader(); + + public slots: + + void add (CSMDoc::Document *document, bool new_); + + void loadingStopped (CSMDoc::Document *document, bool completed, + const std::string& error); + }; +} + +#endif diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 4a4dbc124..3ca52c452 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -86,6 +86,13 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) connect (&CSMSettings::UserSettings::instance(), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)), this, SLOT (slotUpdateEditorSetting (const QString &, const QString &))); + + connect (&mDocumentManager, SIGNAL (loadRequest (CSMDoc::Document *, bool)), + &mLoader, SLOT (add (CSMDoc::Document *, bool))); + + connect ( + &mDocumentManager, SIGNAL (loadingStopped (CSMDoc::Document *, bool, const std::string&)), + &mLoader, SLOT (loadingStopped (CSMDoc::Document *, bool, const std::string&))); } CSVDoc::ViewManager::~ViewManager() diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 01f495186..cddc1b235 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -5,6 +5,8 @@ #include +#include "loader.hpp" + namespace CSMDoc { class Document; @@ -29,6 +31,7 @@ namespace CSVDoc CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories; bool mExitOnSaveStateChange; bool mUserWarned; + Loader mLoader; // not implemented ViewManager (const ViewManager&); From 8dc6ad505937ad3f9aa80ddc405db703d439976e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Apr 2014 14:27:44 +0200 Subject: [PATCH 007/121] moved new flag from setupData function to Document constructor --- apps/opencs/model/doc/document.cpp | 19 ++++++++++++------- apps/opencs/model/doc/document.hpp | 8 ++++++-- apps/opencs/model/doc/documentmanager.cpp | 8 ++++---- apps/opencs/model/doc/documentmanager.hpp | 2 +- apps/opencs/model/doc/loader.cpp | 7 +++---- apps/opencs/model/doc/loader.hpp | 4 +--- apps/opencs/view/doc/loader.cpp | 2 +- apps/opencs/view/doc/loader.hpp | 2 +- apps/opencs/view/doc/viewmanager.cpp | 4 ++-- 9 files changed, 31 insertions(+), 25 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 20a355d48..25b48a3c9 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2220,9 +2220,9 @@ void CSMDoc::Document::createBase() } CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, - const std::vector< boost::filesystem::path >& files, + const std::vector< boost::filesystem::path >& files, bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir) -: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), +: mSavePath (savePath), mContentFiles (files), mNew (new_), mTools (mData), mResDir(resDir), mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), mSaving (*this, mProjectPath) @@ -2260,21 +2260,21 @@ CSMDoc::Document::~Document() { } -void CSMDoc::Document::setupData (bool new_) +void CSMDoc::Document::setupData() { - if (new_ && mContentFiles.size()==1) + if (mNew && mContentFiles.size()==1) createBase(); else { std::vector::const_iterator end = mContentFiles.end(); - if (new_) + if (mNew) --end; - load (mContentFiles.begin(), end, !new_); + load (mContentFiles.begin(), end, !mNew); } - if (new_) + if (mNew) { mData.setDescription (""); mData.setAuthor (""); @@ -2317,6 +2317,11 @@ const std::vector& CSMDoc::Document::getContentFiles() return mContentFiles; } +bool CSMDoc::Document::isNew() const +{ + return mNew; +} + void CSMDoc::Document::save() { if (mSaving.isRunning()) diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index c7d87e16a..e19efd04e 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -39,6 +39,7 @@ namespace CSMDoc boost::filesystem::path mSavePath; std::vector mContentFiles; + bool mNew; CSMWorld::Data mData; CSMTools::Tools mTools; boost::filesystem::path mProjectPath; @@ -72,12 +73,12 @@ namespace CSMDoc public: Document (const Files::ConfigurationManager& configuration, - const std::vector< boost::filesystem::path >& files, + const std::vector< boost::filesystem::path >& files, bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir); ~Document(); - void setupData (bool new_); + void setupData(); QUndoStack& getUndoStack(); @@ -89,6 +90,9 @@ namespace CSMDoc ///< \attention The last element in this collection is the file that is being edited, /// but with its original path instead of the save path. + bool isNew() const; + ///< Is this a newly created content file? + void save(); CSMWorld::UniversalId verify(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 4658667c3..ae6f1103f 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -27,8 +27,8 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con this, SLOT (documentLoaded (Document *))); connect (&mLoader, SIGNAL (documentNotLoaded (Document *, const std::string&)), this, SLOT (documentNotLoaded (Document *, const std::string&))); - connect (this, SIGNAL (loadRequest (CSMDoc::Document *, bool)), - &mLoader, SLOT (loadDocument (CSMDoc::Document *, bool))); + connect (this, SIGNAL (loadRequest (CSMDoc::Document *)), + &mLoader, SLOT (loadDocument (CSMDoc::Document *))); } CSMDoc::DocumentManager::~DocumentManager() @@ -44,11 +44,11 @@ CSMDoc::DocumentManager::~DocumentManager() void CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - Document *document = new Document (mConfiguration, files, savePath, mResDir); + Document *document = new Document (mConfiguration, files, new_, savePath, mResDir); mDocuments.push_back (document); - emit loadRequest (document, new_); + emit loadRequest (document); mLoader.hasThingsToDo().wakeAll(); } diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 63ee5eb68..4adc9726c 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -65,7 +65,7 @@ namespace CSMDoc void documentAdded (CSMDoc::Document *document); - void loadRequest (CSMDoc::Document *document, bool _new); + void loadRequest (CSMDoc::Document *document); void lastDocumentDeleted(); diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 53827deb0..dbaa2b4d5 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -31,13 +31,12 @@ void CSMDoc::Loader::load() std::vector >::iterator iter = mDocuments.begin(); Document *document = iter->first; - bool new_ = iter->second; mDocuments.erase (iter); try { - document->setupData (new_); + document->setupData(); emit documentLoaded (document); } catch (const std::exception& e) @@ -46,9 +45,9 @@ void CSMDoc::Loader::load() } } -void CSMDoc::Loader::loadDocument (CSMDoc::Document *document, bool new_) +void CSMDoc::Loader::loadDocument (CSMDoc::Document *document) { - mDocuments.push_back (std::make_pair (document, new_)); + mDocuments.push_back (std::make_pair (document, false)); } void CSMDoc::Loader::abortLoading (Document *document) diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index af266d52b..4e3db1815 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -31,10 +31,8 @@ namespace CSMDoc public slots: - void loadDocument (CSMDoc::Document *document, bool new_); + void loadDocument (CSMDoc::Document *document); ///< The ownership of \a document is not transferred. - /// \param new_ Do not load the last content file in the files list specified in - /// \a document and instead create it in an appropriate way. void abortLoading (Document *document); ///< Abort loading \a docuemnt (ignored if \a document has already finished being diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index f840ab717..15296d616 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -22,7 +22,7 @@ CSVDoc::Loader::~Loader() delete iter->second; } -void CSVDoc::Loader::add (CSMDoc::Document *document, bool new_) +void CSVDoc::Loader::add (CSMDoc::Document *document) { mDocuments.insert (std::make_pair (document, new LoadingDocument (document))); } diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index 4aa497482..cb154b13e 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -36,7 +36,7 @@ namespace CSVDoc public slots: - void add (CSMDoc::Document *document, bool new_); + void add (CSMDoc::Document *document); void loadingStopped (CSMDoc::Document *document, bool completed, const std::string& error); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 3ca52c452..c18cca809 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -87,8 +87,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) connect (&CSMSettings::UserSettings::instance(), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)), this, SLOT (slotUpdateEditorSetting (const QString &, const QString &))); - connect (&mDocumentManager, SIGNAL (loadRequest (CSMDoc::Document *, bool)), - &mLoader, SLOT (add (CSMDoc::Document *, bool))); + connect (&mDocumentManager, SIGNAL (loadRequest (CSMDoc::Document *)), + &mLoader, SLOT (add (CSMDoc::Document *))); connect ( &mDocumentManager, SIGNAL (loadingStopped (CSMDoc::Document *, bool, const std::string&)), From 7d990abd376891c91c233410c4e06e66ae926eff Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 29 Apr 2014 22:46:55 +1000 Subject: [PATCH 008/121] OpenCS changes to allow compilation with MSVC 11.0. --- apps/opencs/model/settings/usersettings.cpp | 6 +++--- apps/opencs/view/world/dialoguesubview.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 2f8e8098d..fa89fceee 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -195,13 +195,13 @@ CSMSettings::UserSettings::~UserSettings() void CSMSettings::UserSettings::loadSettings (const QString &fileName) { mUserFilePath = QString::fromUtf8 - (mCfgMgr.getUserConfigPath().c_str()) + fileName.toUtf8(); + (mCfgMgr.getUserConfigPath().string().c_str()) + fileName.toUtf8(); QString global = QString::fromUtf8 - (mCfgMgr.getGlobalPath().c_str()) + fileName.toUtf8(); + (mCfgMgr.getGlobalPath().string().c_str()) + fileName.toUtf8(); QString local = QString::fromUtf8 - (mCfgMgr.getLocalPath().c_str()) + fileName.toUtf8(); + (mCfgMgr.getLocalPath().string().c_str()) + fileName.toUtf8(); //open user and global streams QTextStream *userStream = openFilestream (mUserFilePath, true); diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index abdc33103..d03bf3f80 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -183,7 +183,7 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS { delegate = CommandDelegateFactoryCollection::get().makeDelegate ( display, mUndoStack, mParent); - mDelegates.insert(std::make_pair(display, delegate)); + mDelegates.insert(std::make_pair(display, delegate)); } else { delegate = delegateIt->second; From d376efe30bba36ebb427b3503cb9a387566b3bf5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 29 Apr 2014 15:46:36 +0200 Subject: [PATCH 009/121] handle dragging not-existing records --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/tablemimedata.cpp | 8 +++++++- apps/opencs/model/world/universalid.cpp | 1 + apps/opencs/model/world/universalid.hpp | 1 + apps/opencs/view/world/regionmap.cpp | 14 +++++++++++--- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index fe310d0aa..53b55939b 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -27,6 +27,7 @@ namespace CSMWorld enum Display { Display_None, //Do not use + Display_Cell_Missing, //Do not used, actually. It is here to simplify dragging non-existed cells handling Display_String, Display_LongString, diff --git a/apps/opencs/model/world/tablemimedata.cpp b/apps/opencs/model/world/tablemimedata.cpp index 93810a252..e0a735e35 100644 --- a/apps/opencs/model/world/tablemimedata.cpp +++ b/apps/opencs/model/world/tablemimedata.cpp @@ -33,7 +33,7 @@ std::string CSMWorld::TableMimeData::getIcon() const { if (mUniversalId.empty()) { - throw ("TableMimeData holds no UniversalId"); + return ""; } std::string tmpIcon; @@ -360,6 +360,8 @@ CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::Col case CSMWorld::ColumnBase::Display_Script: return CSMWorld::UniversalId::Type_Script; + case CSMWorld::ColumnBase::Display_Cell_Missing: + return CSMWorld::UniversalId::Type_Cell_Missing; //this one actually never happens, since there is no display_Cell_missing column anywhere. default: return CSMWorld::UniversalId::Type_None; @@ -375,6 +377,10 @@ CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::U return CSMWorld::ColumnBase::Display_Race; + case CSMWorld::UniversalId::Type_Cell_Missing: + return CSMWorld::ColumnBase::Display_Cell_Missing; + + case CSMWorld::UniversalId::Type_Skill: return CSMWorld::ColumnBase::Display_Skill; diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index a62acc02b..94b042ec5 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -64,6 +64,7 @@ namespace { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" }, diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 34167cd85..24fb54399 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -60,6 +60,7 @@ namespace CSMWorld Type_Spell, Type_Cells, Type_Cell, + Type_Cell_Missing, //For cells that does not exist yet. Type_Referenceables, Type_Referenceable, Type_Activator, diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 85b79c3f2..beb2e849e 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -353,13 +353,21 @@ void CSVWorld::RegionMap::mouseMoveEvent (QMouseEvent* event) std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDragedRecords() const { - QModelIndexList selected = getSelectedCells(); + QModelIndexList selected(getSelectedCells(true, false)); std::vector ids; foreach (QModelIndex it, selected) { ids.push_back( - CSMWorld::UniversalId - (CSMWorld::UniversalId::Type_Cell, + CSMWorld::UniversalId( + CSMWorld::UniversalId::Type_Cell, + model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData())); + } + selected = getSelectedCells(false, true); + foreach (QModelIndex it, selected) + { + ids.push_back( + CSMWorld::UniversalId( + CSMWorld::UniversalId::Type_Cell_Missing, model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData())); } return ids; From eeb18b533e1006663b2889ec7bd33eeb1d1dab0c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 29 Apr 2014 19:43:58 +0200 Subject: [PATCH 010/121] moved editlock to the dragrecordtable --- apps/opencs/view/world/dragrecordtable.cpp | 8 +++++++- apps/opencs/view/world/dragrecordtable.hpp | 3 +++ apps/opencs/view/world/regionmap.cpp | 7 +------ apps/opencs/view/world/regionmap.hpp | 3 --- apps/opencs/view/world/table.cpp | 4 ++-- apps/opencs/view/world/table.hpp | 3 +-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp index f962f6f10..8e283294e 100644 --- a/apps/opencs/view/world/dragrecordtable.cpp +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -18,5 +18,11 @@ void CSVWorld::DragRecordTable::startDrag (const CSVWorld::DragRecordTable& tabl CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document, QWidget* parent) : mDocument(document), -QTableView(parent) +QTableView(parent), +mEditLock(false) {} + +void CSVWorld::DragRecordTable::setEditLock (bool locked) +{ + mEditLock = locked; +} diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp index 7a2b51743..29b590c36 100644 --- a/apps/opencs/view/world/dragrecordtable.hpp +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -22,12 +22,15 @@ namespace CSVWorld { protected: CSMDoc::Document& mDocument; + bool mEditLock; public: DragRecordTable(CSMDoc::Document& document, QWidget* parent = NULL); virtual std::vector getDragedRecords() const = 0; + virtual void setEditLock(bool locked); + protected: void startDrag(const DragRecordTable& table); }; diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index beb2e849e..326f3c60d 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -181,7 +181,7 @@ void CSVWorld::RegionMap::setRegion (const std::string& regionId) CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, QWidget *parent) -: mEditLock (false), DragRecordTable(document, parent) +: DragRecordTable(document, parent) { verticalHeader()->hide(); horizontalHeader()->hide(); @@ -226,11 +226,6 @@ CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId, addAction (mViewInTableAction); } -void CSVWorld::RegionMap::setEditLock (bool locked) -{ - mEditLock = locked; -} - void CSVWorld::RegionMap::selectAll() { QModelIndexList unselected = getUnselectedCells(); diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index 596ddfaed..c8b110f4b 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -35,7 +35,6 @@ namespace CSVWorld QAction *mUnsetRegionAction; QAction *mViewAction; QAction *mViewInTableAction; - bool mEditLock; std::string mRegionId; private: @@ -62,8 +61,6 @@ namespace CSVWorld RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, QWidget *parent = 0); - void setEditLock (bool locked); - virtual std::vector getDragedRecords() const; signals: diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index d700d5f2e..8e98e93a3 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -188,7 +188,7 @@ std::vector CSVWorld::Table::listDeletableSelectedIds() const CSVWorld::Table::Table (const CSMWorld::UniversalId& id, bool createAndDelete, bool sorting, CSMDoc::Document& document) -: mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0), +: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0), DragRecordTable(document) { mModel = &dynamic_cast (*mDocument.getData().getTableModel (id)); @@ -282,7 +282,7 @@ void CSVWorld::Table::setEditLock (bool locked) for (std::vector::iterator iter (mDelegates.begin()); iter!=mDelegates.end(); ++iter) (*iter)->setEditLock (locked); - mEditLock = locked; + DragRecordTable::setEditLock(locked); } CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 30b487ce8..83a294dd8 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -47,7 +47,6 @@ namespace CSVWorld QAction *mPreviewAction; CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTable *mModel; - bool mEditLock; int mRecordStatusDisplay; private: @@ -73,7 +72,7 @@ namespace CSVWorld ///< \param createAndDelete Allow creation and deletion of records. /// \param sorting Allow changing order of rows in the view via column headers. - void setEditLock (bool locked); + virtual void setEditLock (bool locked); CSMWorld::UniversalId getUniversalId (int row) const; From 4d79f00e284cb00ddf75c9e8142c9ee85db07b73 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 30 Apr 2014 13:32:54 +0200 Subject: [PATCH 011/121] enable dragging on the region map cells --- apps/opencs/view/world/dragrecordtable.cpp | 10 ++++++ apps/opencs/view/world/dragrecordtable.hpp | 5 +++ apps/opencs/view/world/regionmap.cpp | 37 ++++++++++++++++++++++ apps/opencs/view/world/regionmap.hpp | 2 ++ apps/opencs/view/world/table.cpp | 10 ------ apps/opencs/view/world/table.hpp | 5 +-- 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp index 8e283294e..d9d891ff1 100644 --- a/apps/opencs/view/world/dragrecordtable.cpp +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -26,3 +26,13 @@ void CSVWorld::DragRecordTable::setEditLock (bool locked) { mEditLock = locked; } + +void CSVWorld::DragRecordTable::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} + +void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event) +{ + event->accept(); +} diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp index 29b590c36..06ee3b9c6 100644 --- a/apps/opencs/view/world/dragrecordtable.hpp +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -2,6 +2,7 @@ #define CSV_WORLD_DRAGRECORDTABLE_H #include +#include class QWidget; class QAction; @@ -33,6 +34,10 @@ namespace CSVWorld protected: void startDrag(const DragRecordTable& table); + + void dragEnterEvent(QDragEnterEvent *event); + + void dragMoveEvent(QDragMoveEvent *event); }; } diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 326f3c60d..ccd121204 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -224,6 +225,8 @@ CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId, mViewInTableAction = new QAction (tr ("View Cells in Table"), this); connect (mViewInTableAction, SIGNAL (triggered()), this, SLOT (viewInTable())); addAction (mViewInTableAction); + + setAcceptDrops(true); } void CSVWorld::RegionMap::selectAll() @@ -367,3 +370,37 @@ std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDragedRecords() con } return ids; } + +void CSVWorld::RegionMap::dropEvent (QDropEvent* event) +{ + QModelIndex index = indexAt (event->pos()); + + bool exists = QTableView::model()->data(index, Qt::BackgroundRole)!=QBrush (Qt::DiagCrossPattern); + + if (!index.isValid() || !exists) + { + return; + } + + const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + if (mime->fromDocument(mDocument) && mime->holdsType(CSMWorld::UniversalId::Type_Region)) + { + CSMWorld::UniversalId record (mime->returnMatching (CSMWorld::UniversalId::Type_Region)); + + QAbstractItemModel *regionModel = model(); + + CSMWorld::IdTable *cellsModel = &dynamic_cast (* + mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + + std::string cellId(regionModel->data (index, CSMWorld::RegionMap::Role_CellId). + toString().toUtf8().constData()); + + QModelIndex index2 = cellsModel->getModelIndex (cellId, + cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region)); + + mDocument.getUndoStack().push(new CSMWorld::ModifyCommand + (*cellsModel, index2, QString::fromUtf8(record.getId().c_str()))); + + mRegionId = record.getId(); + } +} \ No newline at end of file diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index c8b110f4b..08744a4a0 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -56,6 +56,8 @@ namespace CSVWorld void mouseMoveEvent(QMouseEvent *event); + void dropEvent(QDropEvent* event); + public: RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 8e98e93a3..e5cfbe360 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -516,11 +516,6 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event) } } -void CSVWorld::Table::dragEnterEvent(QDragEnterEvent *event) -{ - event->acceptProposedAction(); -} - void CSVWorld::Table::dropEvent(QDropEvent *event) { QModelIndex index = indexAt (event->pos()); @@ -548,11 +543,6 @@ void CSVWorld::Table::dropEvent(QDropEvent *event) } //TODO handle drops from different document } -void CSVWorld::Table::dragMoveEvent(QDragMoveEvent *event) -{ - event->accept(); -} - std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const { const int count = mModel->columnCount(); diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 83a294dd8..cfab486e5 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -59,10 +59,6 @@ namespace CSVWorld void mouseMoveEvent(QMouseEvent *event); - void dragEnterEvent(QDragEnterEvent *event); - - void dragMoveEvent(QDragMoveEvent *event); - void dropEvent(QDropEvent *event); public: @@ -94,6 +90,7 @@ namespace CSVWorld /// \param modified Number of added and modified records void createRequest(); + void cloneRequest(const CSMWorld::UniversalId&); private slots: From 14ebd8b110ba8a0e9ff86ec92bf81eeaadc28a20 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Wed, 30 Apr 2014 07:44:29 -0400 Subject: [PATCH 012/121] Fixed logic in commit crime --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index eca0c2289..a16c6588d 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -860,8 +860,8 @@ namespace MWMechanics // Tell everyone, including yourself for (std::vector::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1) { - if ( *it == ptr - || !it->getClass().isNpc()) continue; // not the player and is an NPC + if ( *it1 == ptr + || !it1->getClass().isNpc()) continue; // not the player and is an NPC // TODO: Add more messages if (type == OT_Theft) From 5c9c467b2694580627dc0ead360e18f2a5d34c0b Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Wed, 30 Apr 2014 08:06:36 -0400 Subject: [PATCH 013/121] Improved sneak. --- apps/openmw/mwworld/player.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 5e4211faa..d023d4388 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -135,7 +135,7 @@ namespace MWWorld ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak); - if (sneak == true) + if (sneak) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); @@ -145,15 +145,20 @@ namespace MWWorld esmStore.get().find("fSneakUseDist")->getInt(), neighbors); for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { + if (*it == ptr) // not the player + continue; + if ( MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, *it) ) { MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); break; } } - if (neighbors.size() == 0) + if (neighbors.empty()) MWBase::Environment::get().getWindowManager()->setSneakVisibility(true); } + else + MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); } void Player::yaw(float yaw) From 19dac9dc86cdac61a17cc88c3bb2dee76acdbf45 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 30 Apr 2014 14:27:11 +0200 Subject: [PATCH 014/121] that would be it --- .../view/render/pagedworldspacewidget.cpp | 46 ++++++++++++++++++- .../view/render/pagedworldspacewidget.hpp | 8 ++++ apps/opencs/view/world/regionmap.cpp | 1 - 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 0f23dfe7b..3f40712d2 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -3,9 +3,17 @@ #include +#include + +#include + +#include + CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent) : WorldspaceWidget (parent) -{} +{ + setAcceptDrops(true); +} void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) { @@ -44,4 +52,38 @@ void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSel { mSelection = selection; emit cellSelectionChanged (mSelection); -} \ No newline at end of file +} + +void CSVRender::PagedWorldspaceWidget::dragEnterEvent (QDragEnterEvent* event) +{ + event->accept(); +} + +void CSVRender::PagedWorldspaceWidget::dragMoveEvent (QDragMoveEvent* event) +{ + event->accept(); +} + +void CSVRender::PagedWorldspaceWidget::dropEvent (QDropEvent* event) +{ + /* + const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + if (true) + { + if (mime->holdsType(CSMWorld::UniversalId::Type_Cell)) + { + CSMWorld::UniversalId record(mime->returnMatching (CSMWorld::UniversalId::Type_Cell)); + QString id(QString::fromUtf8(record.getId().c_str())); + if (*id.begin() == '#') + { + id.remove(0,1); + QStringList splited(id.split(' ')); + int x = splited.begin()->toInt(); + int y = (splited.begin()+1)->toInt(); + mSelection.add(CSMWorld::CellCoordinates(x, y)); + } + } + } + */ + //TODO! +} diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index f6ff32dc1..c6fdbf3be 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -13,6 +13,14 @@ namespace CSVRender CSMWorld::CellSelection mSelection; + private: + + void dropEvent(QDropEvent* event); + + void dragEnterEvent(QDragEnterEvent *event); + + void dragMoveEvent(QDragMoveEvent *event); + public: PagedWorldspaceWidget (QWidget *parent); diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index ccd121204..de46f175f 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include From 6aaa15b2e86f5ddc69e6e4250bccf2a7b65f0831 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 30 Apr 2014 15:03:46 +0200 Subject: [PATCH 015/121] paged worldspace drop --- .../view/render/pagedworldspacewidget.cpp | 40 ++++++++++++------- .../view/render/pagedworldspacewidget.hpp | 6 ++- apps/opencs/view/world/scenesubview.cpp | 2 +- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 3f40712d2..d916e33e9 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -9,8 +9,9 @@ #include -CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent) -: WorldspaceWidget (parent) +CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent, const CSMDoc::Document& document) +: WorldspaceWidget (parent), +mDocument(document) { setAcceptDrops(true); } @@ -66,24 +67,33 @@ void CSVRender::PagedWorldspaceWidget::dragMoveEvent (QDragMoveEvent* event) void CSVRender::PagedWorldspaceWidget::dropEvent (QDropEvent* event) { - /* const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); - if (true) + if (mime->fromDocument(mDocument)) { - if (mime->holdsType(CSMWorld::UniversalId::Type_Cell)) + std::vector data(mime->getData()); + + for (unsigned i = 0; i < data.size(); ++i) { - CSMWorld::UniversalId record(mime->returnMatching (CSMWorld::UniversalId::Type_Cell)); - QString id(QString::fromUtf8(record.getId().c_str())); - if (*id.begin() == '#') + if (data[i].getType() == CSMWorld::UniversalId::Type_Cell || + data[i].getType() == CSMWorld::UniversalId::Type_Cell_Missing) { - id.remove(0,1); - QStringList splited(id.split(' ')); - int x = splited.begin()->toInt(); - int y = (splited.begin()+1)->toInt(); - mSelection.add(CSMWorld::CellCoordinates(x, y)); + if (*(data[i].getId().begin()) == '#') + { + std::pair coordinate(getCoordinatesFromId(data[i].getId())); + mSelection.add(CSMWorld::CellCoordinates(coordinate.first, coordinate.second)); + } } } } - */ - //TODO! } + +std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (const std::string& record) const +{ + QString id(QString::fromUtf8(record.c_str())); + id.remove(0,1); + QStringList splited(id.split(' ')); //Well, this is the simplest approach + int x = splited.begin()->toInt(); + int y = (splited.begin()+1)->toInt(); + return std::make_pair(x, y); +} + diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index c6fdbf3be..bfcb25e66 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -2,6 +2,7 @@ #define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H #include "../../model/world/cellselection.hpp" +#include #include "worldspacewidget.hpp" @@ -12,6 +13,7 @@ namespace CSVRender Q_OBJECT CSMWorld::CellSelection mSelection; + const CSMDoc::Document& mDocument; //for checking if drop comes from same document private: @@ -21,9 +23,11 @@ namespace CSVRender void dragMoveEvent(QDragMoveEvent *event); + std::pair getCoordinatesFromId(const std::string& record) const; + public: - PagedWorldspaceWidget (QWidget *parent); + PagedWorldspaceWidget (QWidget *parent, const CSMDoc::Document& document); ///< \note Sets the cell area selection to an invalid value to indicate that currently /// no cells are displayed. The cells to be displayed will be specified later through /// hint system. diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 0bb11ce8c..506a0288d 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -40,7 +40,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D if (id.getId()=="sys::default") { - CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this); + CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this, document); mScene = widget; connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); From 9e01a54d72096a63b521ab83e594e0e16532c780 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 30 Apr 2014 15:17:20 +0200 Subject: [PATCH 016/121] minor correction --- apps/opencs/view/world/regionmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index de46f175f..260b3b825 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -394,8 +394,8 @@ void CSVWorld::RegionMap::dropEvent (QDropEvent* event) std::string cellId(regionModel->data (index, CSMWorld::RegionMap::Role_CellId). toString().toUtf8().constData()); - QModelIndex index2 = cellsModel->getModelIndex (cellId, - cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region)); + QModelIndex index2(cellsModel->getModelIndex (cellId, + cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region))); mDocument.getUndoStack().push(new CSMWorld::ModifyCommand (*cellsModel, index2, QString::fromUtf8(record.getId().c_str()))); From 57131332f4908ad753a9cc373fe9cedb012aaaa0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 1 May 2014 12:34:54 +0200 Subject: [PATCH 017/121] fixing minor issues --- apps/opencs/model/world/columnbase.hpp | 1 - apps/opencs/model/world/tablemimedata.cpp | 16 +++++++--------- apps/opencs/model/world/tablemimedata.hpp | 1 + .../opencs/view/render/pagedworldspacewidget.cpp | 15 ++++++++------- apps/opencs/view/world/dragrecordtable.cpp | 2 +- apps/opencs/view/world/dragrecordtable.hpp | 4 ++-- apps/opencs/view/world/regionmap.cpp | 2 +- apps/opencs/view/world/regionmap.hpp | 2 +- apps/opencs/view/world/table.cpp | 2 +- apps/opencs/view/world/table.hpp | 2 +- 10 files changed, 23 insertions(+), 24 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 53b55939b..fe310d0aa 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -27,7 +27,6 @@ namespace CSMWorld enum Display { Display_None, //Do not use - Display_Cell_Missing, //Do not used, actually. It is here to simplify dragging non-existed cells handling Display_String, Display_LongString, diff --git a/apps/opencs/model/world/tablemimedata.cpp b/apps/opencs/model/world/tablemimedata.cpp index e0a735e35..6d65d0ff8 100644 --- a/apps/opencs/model/world/tablemimedata.cpp +++ b/apps/opencs/model/world/tablemimedata.cpp @@ -1,6 +1,9 @@ #include "tablemimedata.hpp" + #include +#include + #include "universalid.hpp" #include "columnbase.hpp" @@ -33,7 +36,8 @@ std::string CSMWorld::TableMimeData::getIcon() const { if (mUniversalId.empty()) { - return ""; + qDebug()<<"TableMimeData object does not hold any records!"; //because throwing in the event loop tends to be problematic + throw("TableMimeData object does not hold any records!"); } std::string tmpIcon; @@ -50,7 +54,7 @@ std::string CSMWorld::TableMimeData::getIcon() const if (tmpIcon != mUniversalId[i].getIcon()) { - return ":/multitype.png"; //icon stolen from gnome + return ":/multitype.png"; //icon stolen from gnome TODO: get new icon } tmpIcon = mUniversalId[i].getIcon(); @@ -360,8 +364,6 @@ CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::Col case CSMWorld::ColumnBase::Display_Script: return CSMWorld::UniversalId::Type_Script; - case CSMWorld::ColumnBase::Display_Cell_Missing: - return CSMWorld::UniversalId::Type_Cell_Missing; //this one actually never happens, since there is no display_Cell_missing column anywhere. default: return CSMWorld::UniversalId::Type_None; @@ -377,10 +379,6 @@ CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::U return CSMWorld::ColumnBase::Display_Race; - case CSMWorld::UniversalId::Type_Cell_Missing: - return CSMWorld::ColumnBase::Display_Cell_Missing; - - case CSMWorld::UniversalId::Type_Skill: return CSMWorld::ColumnBase::Display_Skill; @@ -537,4 +535,4 @@ CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::U const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const { return &mDocument; -} \ No newline at end of file +} diff --git a/apps/opencs/model/world/tablemimedata.hpp b/apps/opencs/model/world/tablemimedata.hpp index 9ca712801..85c243944 100644 --- a/apps/opencs/model/world/tablemimedata.hpp +++ b/apps/opencs/model/world/tablemimedata.hpp @@ -56,6 +56,7 @@ namespace CSMWorld UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const; static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type); + static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type); private: diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index d916e33e9..cdbd88278 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -5,8 +5,6 @@ #include -#include - #include CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent, const CSMDoc::Document& document) @@ -89,11 +87,14 @@ void CSVRender::PagedWorldspaceWidget::dropEvent (QDropEvent* event) std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (const std::string& record) const { - QString id(QString::fromUtf8(record.c_str())); - id.remove(0,1); - QStringList splited(id.split(' ')); //Well, this is the simplest approach - int x = splited.begin()->toInt(); - int y = (splited.begin()+1)->toInt(); + std::istringstream stream (record.c_str()); + char ignore; + stream >> ignore; + char ignore1; // : or ; + char ignore2; // # + int x, y; + + stream >> ignore1 >> ignore2 >> x >> y; return std::make_pair(x, y); } diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp index d9d891ff1..c33fa58ad 100644 --- a/apps/opencs/view/world/dragrecordtable.cpp +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -5,7 +5,7 @@ void CSVWorld::DragRecordTable::startDrag (const CSVWorld::DragRecordTable& table) { - CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (table.getDragedRecords(), mDocument); + CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (table.getDraggedRecords(), mDocument); if (mime) { diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp index 06ee3b9c6..8c5f1b841 100644 --- a/apps/opencs/view/world/dragrecordtable.hpp +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -28,9 +28,9 @@ namespace CSVWorld public: DragRecordTable(CSMDoc::Document& document, QWidget* parent = NULL); - virtual std::vector getDragedRecords() const = 0; + virtual std::vector getDraggedRecords() const = 0; - virtual void setEditLock(bool locked); + void setEditLock(bool locked); protected: void startDrag(const DragRecordTable& table); diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 260b3b825..849a1988a 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -348,7 +348,7 @@ void CSVWorld::RegionMap::mouseMoveEvent (QMouseEvent* event) startDrag(*this); } -std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDragedRecords() const +std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDraggedRecords() const { QModelIndexList selected(getSelectedCells(true, false)); std::vector ids; diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index 08744a4a0..0097a16dc 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -63,7 +63,7 @@ namespace CSVWorld RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, QWidget *parent = 0); - virtual std::vector getDragedRecords() const; + virtual std::vector getDraggedRecords() const; signals: diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index e5cfbe360..cc51a2213 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -561,7 +561,7 @@ std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column return titles; } -std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDragedRecords() const +std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDraggedRecords() const { QModelIndexList selectedRows = selectionModel()->selectedRows(); diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index cfab486e5..8e874ec56 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -76,7 +76,7 @@ namespace CSVWorld std::vector getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const; - virtual std::vector getDragedRecords() const; + virtual std::vector getDraggedRecords() const; signals: From ab94e7072459fa513b611cc2c19af8893e6cc41b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 1 May 2014 13:04:48 +0200 Subject: [PATCH 018/121] more cleanup of document setup --- apps/opencs/model/doc/document.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 25b48a3c9..760c675a0 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2245,6 +2245,18 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, } } + if (mNew) + { + mData.setDescription (""); + mData.setAuthor (""); + + if (mContentFiles.size()==1) + createBase(); + } + + addOptionalGmsts(); + addOptionalGlobals(); + connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool))); connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); @@ -2262,9 +2274,7 @@ CSMDoc::Document::~Document() void CSMDoc::Document::setupData() { - if (mNew && mContentFiles.size()==1) - createBase(); - else + if (!mNew || mContentFiles.size()>1) { std::vector::const_iterator end = mContentFiles.end(); @@ -2274,16 +2284,7 @@ void CSMDoc::Document::setupData() load (mContentFiles.begin(), end, !mNew); } - if (mNew) - { - mData.setDescription (""); - mData.setAuthor (""); - } - getData().loadFile (mProjectPath, false, true); - - addOptionalGmsts(); - addOptionalGlobals(); } QUndoStack& CSMDoc::Document::getUndoStack() From 36914b43d776ce0dde24df6c5acf0972d8f19289 Mon Sep 17 00:00:00 2001 From: Sandy Date: Thu, 1 May 2014 08:19:05 -0400 Subject: [PATCH 019/121] Remove install of License of no longer used font --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 392fdfc66..bd45a207c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -434,7 +434,6 @@ IF(NOT WIN32 AND NOT APPLE) # Install licenses INSTALL(FILES "DejaVu Font License.txt" DESTINATION "${LICDIR}" ) - INSTALL(FILES "OFL.txt" DESTINATION "${LICDIR}" ) INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" ) ENDIF (DPKG_PROGRAM) From d00dbf47d5cf79b6652deccef5420670ba9d4189 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 1 May 2014 15:09:47 +0200 Subject: [PATCH 020/121] working on worldspace drops --- .../view/render/pagedworldspacewidget.cpp | 68 +++++++++-------- .../view/render/pagedworldspacewidget.hpp | 10 +-- .../view/render/unpagedworldspacewidget.cpp | 38 +++++++++- .../view/render/unpagedworldspacewidget.hpp | 11 +++ apps/opencs/view/render/worldspacewidget.cpp | 76 ++++++++++++++++++- apps/opencs/view/render/worldspacewidget.hpp | 26 ++++++- 6 files changed, 184 insertions(+), 45 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index cdbd88278..3691a7a4d 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -8,11 +8,8 @@ #include CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent, const CSMDoc::Document& document) -: WorldspaceWidget (parent), -mDocument(document) -{ - setAcceptDrops(true); -} +: WorldspaceWidget (document, parent) +{} void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) { @@ -53,48 +50,55 @@ void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSel emit cellSelectionChanged (mSelection); } -void CSVRender::PagedWorldspaceWidget::dragEnterEvent (QDragEnterEvent* event) -{ - event->accept(); -} - -void CSVRender::PagedWorldspaceWidget::dragMoveEvent (QDragMoveEvent* event) -{ - event->accept(); -} - void CSVRender::PagedWorldspaceWidget::dropEvent (QDropEvent* event) { const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + if (mime->fromDocument(mDocument)) { - std::vector data(mime->getData()); + const std::vector data(mime->getData()); + CSVRender::WorldspaceWidget::dropType whatHappend = getDropType(data); - for (unsigned i = 0; i < data.size(); ++i) + std::cout< coordinate(getCoordinatesFromId(data[i].getId())); - mSelection.add(CSMWorld::CellCoordinates(coordinate.first, coordinate.second)); - } - } + case CSVRender::WorldspaceWidget::cellsExterior: + handleDrop(data); + break; + + case CSVRender::WorldspaceWidget::cellsInterior: + emit interiorCellsDropped(data); + break; + + default: + //not interior or exterior = either mixed or not actually cells. We don't need to do anything in this case. + break; } - } + } //not handling drops from different documents at the moment } std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (const std::string& record) const { std::istringstream stream (record.c_str()); char ignore; - stream >> ignore; - char ignore1; // : or ; - char ignore2; // # int x, y; - - stream >> ignore1 >> ignore2 >> x >> y; + stream >> ignore >> x >> y; return std::make_pair(x, y); } +void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data) +{ + bool selectionChanged = false; + for (unsigned i = 0; i < data.size(); ++i) + { + std::pair coordinates(getCoordinatesFromId(data[i].getId())); + if (mSelection.add(CSMWorld::CellCoordinates(coordinates.first, coordinates.second))) + { + selectionChanged = true; + } + } + if (selectionChanged) + { + emit cellSelectionChanged(mSelection); + } +} diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index bfcb25e66..f9215f596 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -2,7 +2,6 @@ #define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H #include "../../model/world/cellselection.hpp" -#include #include "worldspacewidget.hpp" @@ -13,18 +12,15 @@ namespace CSVRender Q_OBJECT CSMWorld::CellSelection mSelection; - const CSMDoc::Document& mDocument; //for checking if drop comes from same document private: void dropEvent(QDropEvent* event); - void dragEnterEvent(QDragEnterEvent *event); - - void dragMoveEvent(QDragMoveEvent *event); - std::pair getCoordinatesFromId(const std::string& record) const; + void handleDrop(const std::vector& data); + public: PagedWorldspaceWidget (QWidget *parent, const CSMDoc::Document& document); @@ -39,6 +35,8 @@ namespace CSVRender signals: void cellSelectionChanged (const CSMWorld::CellSelection& selection); + + void interiorCellsDropped(const std::vector& data); }; } diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index fb74788cc..43c8dbd8d 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -3,10 +3,13 @@ #include +#include + #include "../../model/doc/document.hpp" #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" +#include "../../model/world/tablemimedata.hpp" void CSVRender::UnpagedWorldspaceWidget::update() { @@ -22,7 +25,7 @@ void CSVRender::UnpagedWorldspaceWidget::update() CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget *parent) -: WorldspaceWidget (parent), mCellId (cellId) +: WorldspaceWidget (document, parent), mCellId (cellId) { mCellsModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); @@ -63,4 +66,35 @@ void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelI if (cellIndex.row()>=start && cellIndex.row()<=end) emit closeRequest(); -} \ No newline at end of file +} + +void CSVRender::UnpagedWorldspaceWidget::dropEvent (QDropEvent* event) +{ + const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + + if (mime->fromDocument (mDocument)) + { + const std::vector data (mime->getData()); + CSVRender::WorldspaceWidget::dropType whatHappend = getDropType (data); + + switch (whatHappend) + { + case CSVRender::WorldspaceWidget::cellsExterior: + emit exteriorCellsDropped(data); + break; + + case CSVRender::WorldspaceWidget::cellsInterior: + handleDrop(data); + break; + + default: + //not interior or exterior = either mixed or not actually cells. We don't need to do anything in this case. + break; + } + } //not handling drops from different documents at the moment +} + +void CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data) +{ + +} diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 17dc46918..d5b62b8ed 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -33,11 +33,22 @@ namespace CSVRender UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget *parent); + private: + + void handleDrop(const std::vector& data); + + void dropEvent(QDropEvent* event); + private slots: void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + signals: + + void exteriorCellsDropped(const std::vector& data); + }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 4d2442c89..925dd921b 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -5,15 +5,20 @@ #include #include -#include "../world/scenetoolmode.hpp" +#include -CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent) -: SceneWidget (parent) +#include "../world/scenetoolmode.hpp" +#include + +CSVRender::WorldspaceWidget::WorldspaceWidget (const CSMDoc::Document& document, QWidget* parent) +: SceneWidget (parent), mDocument(document) { Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE); ent->setMaterialName("BaseWhite"); getSceneManager()->getRootSceneNode()->attachObject(ent); + + setAcceptDrops(true); } void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) @@ -46,4 +51,67 @@ CSVWorld::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( this, SLOT (selectNavigationMode (const std::string&))); return tool; -} \ No newline at end of file +} + +CSVRender::WorldspaceWidget::dropType CSVRender::WorldspaceWidget::getDropType ( + const std::vector< CSMWorld::UniversalId >& data) const +{ + dropType output = notCells; + bool firstIteration = true; + + for (unsigned i = 0; i < data.size(); ++i) + { + if (data[i].getType() == CSMWorld::UniversalId::Type_Cell || + data[i].getType() == CSMWorld::UniversalId::Type_Cell_Missing) + { + if (*(data[i].getId().begin()) == '#') //exterior + { + if (firstIteration) + { + output = cellsExterior; + firstIteration = false; + continue; + } + + if (output == cellsInterior) + { + output = cellsMixed; + break; + } else { + output = cellsInterior; + } + } else //interior + { + if (firstIteration) + { + output = cellsInterior; + firstIteration = false; + continue; + } + + if (output == cellsExterior) + { + output = cellsMixed; + break; + } else { + output = cellsInterior; + } + } + } else { + output = notCells; + break; + } + } + + return output; +} + +void CSVRender::WorldspaceWidget::dragEnterEvent (QDragEnterEvent* event) +{ + event->accept(); +} + +void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event) +{ + event->accept(); +} diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index f7208d7a1..83ef593d6 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -6,7 +6,12 @@ #include "navigation1st.hpp" #include "navigationfree.hpp" #include "navigationorbit.hpp" +#include +namespace CSMWorld +{ + class UniversalId; +} namespace CSVWorld { class SceneToolMode; @@ -25,7 +30,7 @@ namespace CSVRender public: - WorldspaceWidget (QWidget *parent = 0); + WorldspaceWidget (const CSMDoc::Document& document, QWidget *parent = 0); CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent); ///< \attention The created tool is not added to the toolbar (via addTool). Doing that @@ -36,6 +41,25 @@ namespace CSVRender virtual void useViewHint (const std::string& hint); ///< Default-implementation: ignored. + protected: + const CSMDoc::Document& mDocument; //for checking if drop comes from same document + + enum dropType + { + cellsMixed, + cellsInterior, + cellsExterior, + notCells + }; + + dropType getDropType(const std::vector& data) const; + + private: + + void dragEnterEvent(QDragEnterEvent *event); + + void dragMoveEvent(QDragMoveEvent *event); + private slots: void selectNavigationMode (const std::string& mode); From 5415ca6a6311215b5b3aab84526d7044f7c6280f Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 29 Apr 2014 13:04:09 +0200 Subject: [PATCH 021/121] Fix exception when shift+click on empty space in save dialog --- apps/openmw/mwgui/savegamedialog.cpp | 2 +- apps/openmw/mwgui/statswindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 74ccc82f4..a77c625f9 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -53,7 +53,7 @@ namespace MWGui { onSlotSelected(sender, pos); - if (MyGUI::InputManager::getInstance().isShiftPressed()) + if (pos != MyGUI::ITEM_NONE && MyGUI::InputManager::getInstance().isShiftPressed()) { ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog(); dialog->open("#{sMessage3}"); diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 3d4c741a3..31a3b6fdd 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -475,7 +475,7 @@ namespace MWGui text += std::string("#DDC79E") + faction->mName; if (expelled.find(it->first) != expelled.end()) - text += "\n#{sExpelled}"; + text += "\n#BF9959#{sExpelled}"; else { text += std::string("\n#BF9959") + faction->mRanks[it->second]; From f99eda1a543c79bad59e23e9ed5a0fcd9215644d Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 30 Apr 2014 13:34:06 +0200 Subject: [PATCH 022/121] Fixes #1302: Do not attempt to set OnPcAdd before the script has been added --- apps/openmw/mwworld/containerstore.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index b1cbcc9c2..eb6760d14 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -231,6 +231,8 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr { CellStore *cell; + MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item); + if(&(MWWorld::Class::get (player).getContainerStore (player)) == this) { cell = 0; // Items in player's inventory have cell set to 0, so their scripts will never be removed @@ -243,7 +245,6 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr item.mCell = cell; item.mContainerStore = 0; - MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item); } return it; From 6f7fbc867f6e4ba8acb9fe03d7169c819cfecf91 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 30 Apr 2014 21:15:14 +0200 Subject: [PATCH 023/121] Fix several leaks --- apps/openmw/mwgui/inventorywindow.cpp | 10 +++++----- apps/openmw/mwgui/inventorywindow.hpp | 4 ++-- apps/openmw/mwrender/characterpreview.hpp | 4 ++++ apps/openmw/mwrender/ripplesimulation.cpp | 5 ++++- components/ogreinit/ogreinit.cpp | 1 + components/terrain/world.cpp | 2 ++ files/mygui/openmw_text.skin.xml | 16 ---------------- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index e9efe75e7..2bea088e3 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -35,7 +35,7 @@ namespace MWGui , mTrading(false) , mLastXSize(0) , mLastYSize(0) - , mPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr()) + , mPreview(new MWRender::InventoryPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr())) , mPreviewDirty(true) , mDragAndDrop(dragAndDrop) , mSelectedItem(-1) @@ -91,8 +91,8 @@ namespace MWGui mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr()); mSortModel = new SortFilterItemModel(mTradeModel); mItemView->setModel(mSortModel); - mPreview = MWRender::InventoryPreview(mPtr); - mPreview.setup(); + mPreview.reset(new MWRender::InventoryPreview(mPtr)); + mPreview->setup(); } void InventoryWindow::setGuiMode(GuiMode mode) @@ -444,7 +444,7 @@ namespace MWGui MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y) { - int slot = mPreview.getSlotSelected (x, y); + int slot = mPreview->getSlotSelected (x, y); if (slot == -1) return MWWorld::Ptr(); @@ -493,7 +493,7 @@ namespace MWGui mPreviewDirty = false; MyGUI::IntSize size = mAvatarImage->getSize(); - mPreview.update (size.width, size.height); + mPreview->update (size.width, size.height); mAvatarImage->setImageTexture("CharacterPreview"); mAvatarImage->setImageCoord(MyGUI::IntCoord(0, 0, std::min(512, size.width), std::min(1024, size.height))); diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 7ef168e98..c23a74efa 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -34,7 +34,7 @@ namespace MWGui MWWorld::Ptr getAvatarSelectedItem(int x, int y); void rebuildAvatar() { - mPreview.rebuild(); + mPreview->rebuild(); } TradeItemModel* getTradeModel(); @@ -81,7 +81,7 @@ namespace MWGui int mLastXSize; int mLastYSize; - MWRender::InventoryPreview mPreview; + std::auto_ptr mPreview; bool mTrading; diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index 16e6ab017..60312455f 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -34,6 +34,10 @@ namespace MWRender virtual void rebuild(); + private: + CharacterPreview(const CharacterPreview&); + CharacterPreview& operator=(const CharacterPreview&); + protected: virtual bool renderHeadOnly() { return false; } diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index f52deedcc..74216c1de 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -28,7 +28,9 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) mRippleAreaLength(1000), mImpulseSize(20), mTexelOffset(0,0), - mFirstUpdate(true) + mFirstUpdate(true), + mRectangle(NULL), + mImpulse(NULL) { Ogre::AxisAlignedBox aabInf; aabInf.setInfinite(); @@ -105,6 +107,7 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) RippleSimulation::~RippleSimulation() { delete mRectangle; + delete mImpulse; Ogre::Root::getSingleton().destroySceneManager(mSceneMgr); } diff --git a/components/ogreinit/ogreinit.cpp b/components/ogreinit/ogreinit.cpp index 1b9a899a0..01b8764c2 100644 --- a/components/ogreinit/ogreinit.cpp +++ b/components/ogreinit/ogreinit.cpp @@ -62,6 +62,7 @@ namespace OgreInit OgreInit::~OgreInit() { delete mRoot; + delete Ogre::LogManager::getSingletonPtr(); std::vector::iterator ei; for(ei = mEmitterFactories.begin();ei != mEmitterFactories.end();++ei) diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index 844144d7c..3d968470f 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -337,6 +337,8 @@ namespace Terrain it->mTarget->loadLayers(*it); } + delete data; + mRootNode->loadMaterials(); mLayerLoadPending = false; diff --git a/files/mygui/openmw_text.skin.xml b/files/mygui/openmw_text.skin.xml index b80859ea1..d4c72c75b 100644 --- a/files/mygui/openmw_text.skin.xml +++ b/files/mygui/openmw_text.skin.xml @@ -49,22 +49,6 @@ - - - - - - - - - - - - - - - - From 64a30ad182bdb4caec160b6fd1d53b0caab9e8b5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 1 May 2014 12:44:31 +0200 Subject: [PATCH 024/121] Fix another leak --- apps/openmw/mwgui/fontloader.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/fontloader.cpp b/apps/openmw/mwgui/fontloader.cpp index 7a6317c16..59c2e7ca6 100644 --- a/apps/openmw/mwgui/fontloader.cpp +++ b/apps/openmw/mwgui/fontloader.cpp @@ -196,6 +196,16 @@ namespace MWGui bitmapFile->read(&textureData[0], width*height*4); bitmapFile->close(); + std::string resourceName; + if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic")) + resourceName = "Magic Cards"; + else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century")) + resourceName = "Century Gothic"; + else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric")) + resourceName = "Daedric"; + else + return; // no point in loading it, since there is no way of using additional fonts + std::string textureName = name; Ogre::Image image; image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA); @@ -208,18 +218,11 @@ namespace MWGui // Register the font with MyGUI MyGUI::ResourceManualFont* font = static_cast( MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont")); + // We need to emulate loading from XML because the data members are private as of mygui 3.2.0 MyGUI::xml::Document xmlDocument; MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont"); - - if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic")) - root->addAttribute("name", "Magic Cards"); - else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century")) - root->addAttribute("name", "Century Gothic"); - else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric")) - root->addAttribute("name", "Daedric"); - else - return; // no point in loading it, since there is no way of using additional fonts + root->addAttribute("name", resourceName); MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property"); defaultHeight->addAttribute("key", "DefaultHeight"); @@ -285,6 +288,7 @@ namespace MWGui font->deserialization(root, MyGUI::Version(3,2,0)); + MyGUI::ResourceManager::getInstance().removeByName(font->getResourceName()); MyGUI::ResourceManager::getInstance().addResource(font); } From fc7e79027af9df32276211b9f8306c73cb51f1e4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 1 May 2014 16:44:39 +0200 Subject: [PATCH 025/121] Fixes #1144: Don't refreshCurrentAnims when adding already dead actors --- apps/openmw/mwmechanics/character.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 8ad2b4a67..280639f71 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -489,12 +489,13 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim mIdleState = CharState_Idle; } - refreshCurrentAnims(mIdleState, mMovementState, true); if(mDeathState != CharState_None) { playRandomDeath(1.0f); } + else + refreshCurrentAnims(mIdleState, mMovementState, true); } CharacterController::~CharacterController() From ea1aaef8cabd03500a1574f6f87af8f2f19d892c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 1 May 2014 18:25:28 +0200 Subject: [PATCH 026/121] replace paged with unpaged (and vice versa) --- apps/opencs/model/world/data.cpp | 2 +- .../view/render/pagedworldspacewidget.cpp | 5 +- .../view/render/pagedworldspacewidget.hpp | 8 +- apps/opencs/view/render/scenewidget.hpp | 2 +- .../view/render/unpagedworldspacewidget.cpp | 8 +- .../view/render/unpagedworldspacewidget.hpp | 1 + apps/opencs/view/world/scenesubview.cpp | 108 +++++++++++++++--- apps/opencs/view/world/scenesubview.hpp | 10 ++ 8 files changed, 115 insertions(+), 29 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index d60dcae11..b71f537f3 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -453,7 +453,7 @@ CSMWorld::IdCollection& CSMWorld::Data::getFilters() return mFilters; } -QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id) +QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id) { std::map::iterator iter = mModelIndex.find (id.getType()); diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 3691a7a4d..a6bdb5180 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -7,7 +7,7 @@ #include -CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent, const CSMDoc::Document& document) +CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) : WorldspaceWidget (document, parent) {} @@ -56,10 +56,9 @@ void CSVRender::PagedWorldspaceWidget::dropEvent (QDropEvent* event) if (mime->fromDocument(mDocument)) { - const std::vector data(mime->getData()); + const std::vector& data(mime->getData()); CSVRender::WorldspaceWidget::dropType whatHappend = getDropType(data); - std::cout< getCoordinatesFromId(const std::string& record) const; - void handleDrop(const std::vector& data); - public: - PagedWorldspaceWidget (QWidget *parent, const CSMDoc::Document& document); + PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document); ///< \note Sets the cell area selection to an invalid value to indicate that currently /// no cells are displayed. The cells to be displayed will be specified later through /// hint system. - virtual void useViewHint (const std::string& hint); + void useViewHint (const std::string& hint); void setCellSelection (const CSMWorld::CellSelection& selection); + virtual void handleDrop(const std::vector& data); + signals: void cellSelectionChanged (const CSMWorld::CellSelection& selection); diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 8df9cf347..7f8f104f1 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -36,7 +36,7 @@ namespace CSVRender SceneWidget(QWidget *parent); virtual ~SceneWidget(); - QPaintEngine* paintEngine() const; + QPaintEngine* paintEngine() const; CSVWorld::SceneToolMode *makeLightingSelector (CSVWorld::SceneToolbar *parent); ///< \attention The created tool is not added to the toolbar (via addTool). Doing that diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 43c8dbd8d..929088789 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -23,8 +23,7 @@ void CSVRender::UnpagedWorldspaceWidget::update() /// \todo deal with mSunlight and mFog/mForDensity } -CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, - CSMDoc::Document& document, QWidget *parent) +CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent) : WorldspaceWidget (document, parent), mCellId (cellId) { mCellsModel = &dynamic_cast ( @@ -74,7 +73,7 @@ void CSVRender::UnpagedWorldspaceWidget::dropEvent (QDropEvent* event) if (mime->fromDocument (mDocument)) { - const std::vector data (mime->getData()); + const std::vector& data (mime->getData()); CSVRender::WorldspaceWidget::dropType whatHappend = getDropType (data); switch (whatHappend) @@ -96,5 +95,6 @@ void CSVRender::UnpagedWorldspaceWidget::dropEvent (QDropEvent* event) void CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data) { - + mCellId = data.begin()->getId(); + update(); } diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index d5b62b8ed..ad1e22e39 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -33,6 +33,7 @@ namespace CSVRender UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget *parent); + private: void handleDrop(const std::vector& data); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 506a0288d..45cd11618 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -18,11 +18,10 @@ #include "tablebottombox.hpp" #include "creator.hpp" -#include "scenetoolbar.hpp" #include "scenetoolmode.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id) +: SubView (id), mLayout(new QHBoxLayout), mDocument(document) { QVBoxLayout *layout = new QVBoxLayout; @@ -32,33 +31,43 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id, this), 0); - QHBoxLayout *layout2 = new QHBoxLayout; + mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); - layout2->setContentsMargins (QMargins (0, 0, 0, 0)); - - SceneToolbar *toolbar = new SceneToolbar (48+6, this); + mToolbar = new SceneToolbar (48+6, this); if (id.getId()=="sys::default") { CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this, document); + mScene = widget; + connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), - this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); + this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); + + connect (widget, SIGNAL(interiorCellsDropped (const std::vector&)), + this, SLOT(changeToUnpaged (const std::vector&))); } else - mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); + { + CSVRender::UnpagedWorldspaceWidget *widget = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); - SceneToolMode *navigationTool = mScene->makeNavigationSelector (toolbar); - toolbar->addTool (navigationTool); + mScene = widget; - SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); - toolbar->addTool (lightingTool); + connect (widget, SIGNAL(exteriorCellsDropped(const std::vector&)), + this, SLOT(changeToUnpaged(const std::vector&))); + } - layout2->addWidget (toolbar, 0); + SceneToolMode *navigationTool = mScene->makeNavigationSelector (mToolbar); + mToolbar->addTool (navigationTool); - layout2->addWidget (mScene, 1); + SceneToolMode *lightingTool = mScene->makeLightingSelector (mToolbar); + mToolbar->addTool (lightingTool); - layout->insertLayout (0, layout2, 1); + mLayout->addWidget (mToolbar, 0); + + mLayout->addWidget (mScene, 1); + + layout->insertLayout (0, mLayout, 1); CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this); @@ -126,4 +135,71 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection } setWindowTitle (QString::fromUtf8 (stream.str().c_str())); -} \ No newline at end of file +} + +void CSVWorld::SceneSubView::changeToPaged (const std::vector< CSMWorld::UniversalId >& data) +{ + mLayout->removeWidget(mToolbar); + mLayout->removeWidget(mScene); + + delete mScene; + + delete mToolbar; + + mToolbar = new SceneToolbar (48+6, this); + + CSVRender::PagedWorldspaceWidget* widget = new CSVRender::PagedWorldspaceWidget (this, mDocument); + + mScene = widget; + + SceneToolMode* navigationTool = mScene->makeNavigationSelector (mToolbar); + mToolbar->addTool (navigationTool); + + SceneToolMode* lightingTool = mScene->makeLightingSelector (mToolbar); + mToolbar->addTool (lightingTool); + + connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), + this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); + + connect (widget, SIGNAL (interiorCellsDropped (const std::vector&)), + this, SLOT (changeToUnpaged (const std::vector&))); + + mLayout->addWidget (mToolbar, 0); + mLayout->addWidget (mScene, 1); + + mScene->selectDefaultNavigationMode(); + + connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); + + widget->handleDrop (data); +} + +void CSVWorld::SceneSubView::changeToUnpaged (const std::vector< CSMWorld::UniversalId >& data) +{ + mLayout->removeWidget(mToolbar); + mLayout->removeWidget(mScene); + + delete mScene; + delete mToolbar; + + mToolbar = new SceneToolbar (48+6, this); + CSVRender::UnpagedWorldspaceWidget* widget = new CSVRender::UnpagedWorldspaceWidget (data.begin()->getId(), mDocument, this); + + mScene = widget; + + SceneToolMode* navigationTool = mScene->makeNavigationSelector (mToolbar); + mToolbar->addTool (navigationTool); + + SceneToolMode* lightingTool = mScene->makeLightingSelector (mToolbar); + mToolbar->addTool (lightingTool); + + connect (widget, SIGNAL (exteriorCellsDropped (const std::vector&)), + this, SLOT (changeToPaged (const std::vector&))); + + mLayout->addWidget (mToolbar, 0); + mLayout->addWidget (mScene, 1); + + mScene->selectDefaultNavigationMode(); + + connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); +} diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 0b15ea541..9af76ef6a 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -1,7 +1,10 @@ #ifndef CSV_WORLD_SCENESUBVIEW_H #define CSV_WORLD_SCENESUBVIEW_H +#include + #include "../doc/subview.hpp" +#include "scenetoolbar.hpp" class QModelIndex; @@ -32,6 +35,9 @@ namespace CSVWorld TableBottomBox *mBottom; CSVRender::WorldspaceWidget *mScene; + QHBoxLayout* mLayout; + CSMDoc::Document& mDocument; + SceneToolbar* mToolbar; public: @@ -50,6 +56,10 @@ namespace CSVWorld void closeRequest(); void cellSelectionChanged (const CSMWorld::CellSelection& selection); + + void changeToPaged(const std::vector& data); + + void changeToUnpaged(const std::vector& data); }; } From c2b070f097dcabcff3321f711394f403037bc4a0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 1 May 2014 19:17:33 +0200 Subject: [PATCH 027/121] trying to do it right. --- apps/opencs/view/world/scenesubview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 45cd11618..f3807e4e9 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -143,9 +143,9 @@ void CSVWorld::SceneSubView::changeToPaged (const std::vector< CSMWorld::Univers mLayout->removeWidget(mScene); delete mScene; - delete mToolbar; + setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Cell, "sys::default")); mToolbar = new SceneToolbar (48+6, this); CSVRender::PagedWorldspaceWidget* widget = new CSVRender::PagedWorldspaceWidget (this, mDocument); @@ -184,6 +184,7 @@ void CSVWorld::SceneSubView::changeToUnpaged (const std::vector< CSMWorld::Unive mToolbar = new SceneToolbar (48+6, this); CSVRender::UnpagedWorldspaceWidget* widget = new CSVRender::UnpagedWorldspaceWidget (data.begin()->getId(), mDocument, this); + setUniversalId(*(data.begin())); mScene = widget; From 17bb8d7f9a84fbe5106ab97fbe4407f327b34097 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 1 May 2014 21:16:32 +0200 Subject: [PATCH 028/121] Fixes #1252: Add item/magic keybindings to savegame --- apps/openmw/mwbase/windowmanager.hpp | 1 + apps/openmw/mwgui/quickkeysmenu.cpp | 119 +++++++++++++++++++++++- apps/openmw/mwgui/quickkeysmenu.hpp | 5 + apps/openmw/mwgui/windowmanagerimp.cpp | 15 ++- apps/openmw/mwgui/windowmanagerimp.hpp | 1 + apps/openmw/mwstate/statemanagerimp.cpp | 4 +- components/esm/defs.hpp | 7 ++ 7 files changed, 144 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 4287e466b..c78902a60 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -305,6 +305,7 @@ namespace MWBase virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0; + virtual int countSavedGameRecords() const = 0; }; } diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index dc7226909..fb41b3b67 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -55,6 +55,14 @@ namespace MWGui } } + void QuickKeysMenu::clear() + { + for (int i=0; i<10; ++i) + { + unassign(mQuickKeyButtons[i], i); + } + } + QuickKeysMenu::~QuickKeysMenu() { delete mAssignDialog; @@ -154,8 +162,6 @@ namespace MWGui frame->setUserString ("ToolTipType", "ItemPtr"); frame->setUserData(item); frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked); - - MyGUI::ImageBox* image = frame->createWidget("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); std::string path = std::string("icons\\"); path += MWWorld::Class::get(item).getInventoryIcon(item); @@ -165,7 +171,8 @@ namespace MWGui image->setImageTexture (path); image->setNeedMouseFocus (false); - mItemSelectionDialog->setVisible(false); + if (mItemSelectionDialog) + mItemSelectionDialog->setVisible(false); } void QuickKeysMenu::onAssignItemCancel() @@ -198,7 +205,8 @@ namespace MWGui image->setImageTexture (path); image->setNeedMouseFocus (false); - mMagicSelectionDialog->setVisible(false); + if (mMagicSelectionDialog) + mMagicSelectionDialog->setVisible(false); } void QuickKeysMenu::onAssignMagic (const std::string& spellId) @@ -239,7 +247,8 @@ namespace MWGui image->setImageTexture (path); image->setNeedMouseFocus (false); - mMagicSelectionDialog->setVisible(false); + if (mMagicSelectionDialog) + mMagicSelectionDialog->setVisible(false); } void QuickKeysMenu::onAssignMagicCancel () @@ -374,6 +383,106 @@ namespace MWGui center(); } + void QuickKeysMenu::write(ESM::ESMWriter &writer) + { + const std::string recKey = "KEY_"; + writer.startRecord(ESM::REC_KEYS); + + for (int i=0; i<10; ++i) + { + writer.startSubRecord(recKey); + + MyGUI::Button* button = mQuickKeyButtons[i]; + + int type = *button->getUserData(); + writer.writeHNT("TYPE", type); + + switch (type) + { + case Type_Unassigned: + writer.writeHNString("ID__", ""); + break; + case Type_Item: + case Type_MagicItem: + { + MWWorld::Ptr item = *button->getChildAt(0)->getUserData(); + writer.writeHNString("ID__", item.getCellRef().mRefID); + break; + } + case Type_Magic: + std::string spellId = button->getChildAt(0)->getUserString("Spell"); + writer.writeHNString("ID__", spellId); + break; + } + + writer.endRecord(recKey); + } + + writer.endRecord(ESM::REC_KEYS); + } + + void QuickKeysMenu::readRecord(ESM::ESMReader &reader, int32_t type) + { + if (type != ESM::REC_KEYS) + return; + + int i=0; + while (reader.isNextSub("KEY_")) + { + reader.getSubHeader(); + int keyType; + reader.getHNT(keyType, "TYPE"); + std::string id; + id = reader.getHNString("ID__"); + + mSelectedIndex = i; + + MyGUI::Button* button = mQuickKeyButtons[i]; + + switch (keyType) + { + case Type_Magic: + onAssignMagic(id); + break; + case Type_Item: + case Type_MagicItem: + { + // Find the item by id + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player); + MWWorld::Ptr item; + for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + { + if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, id)) + { + if (item.isEmpty() || + // Prefer the stack with the lowest remaining uses + (it->getCellRef().mCharge != -1 && (item.getCellRef().mCharge == -1 || it->getCellRef().mCharge < item.getCellRef().mCharge) )) + { + item = *it; + } + } + } + + if (item.isEmpty()) + unassign(button, i); + else + { + if (keyType == Type_Item) + onAssignItem(item); + else if (keyType == Type_MagicItem) + onAssignMagicItem(item); + } + + break; + } + case Type_Unassigned: + unassign(button, i); + break; + } + ++i; + } + } // --------------------------------------------------------------------------------------------------------- diff --git a/apps/openmw/mwgui/quickkeysmenu.hpp b/apps/openmw/mwgui/quickkeysmenu.hpp index 058519ece..c0e25a517 100644 --- a/apps/openmw/mwgui/quickkeysmenu.hpp +++ b/apps/openmw/mwgui/quickkeysmenu.hpp @@ -41,6 +41,11 @@ namespace MWGui }; + void write (ESM::ESMWriter& writer); + void readRecord (ESM::ESMReader& reader, int32_t type); + void clear(); + + private: MyGUI::EditBox* mInstructionLabel; MyGUI::Button* mOkButton; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e2e4e157c..1b4145e5c 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1405,16 +1405,29 @@ namespace MWGui void WindowManager::clear() { mMap->clear(); + mQuickKeysMenu->clear(); } void WindowManager::write(ESM::ESMWriter &writer, Loading::Listener& progress) { mMap->write(writer, progress); + + mQuickKeysMenu->write(writer); + progress.increaseProgress(); } void WindowManager::readRecord(ESM::ESMReader &reader, int32_t type) { - mMap->readRecord(reader, type); + if (type == ESM::REC_GMAP) + mMap->readRecord(reader, type); + else if (type == ESM::REC_KEYS) + mQuickKeysMenu->readRecord(reader, type); + } + + int WindowManager::countSavedGameRecords() const + { + return 1 // Global map + + 1; // QuickKeysMenu } void WindowManager::playVideo(const std::string &name, bool allowSkipping) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 064ca89ba..44bc56654 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -293,6 +293,7 @@ namespace MWGui virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress); virtual void readRecord (ESM::ESMReader& reader, int32_t type); + virtual int countSavedGameRecords() const; private: bool mConsoleOnlyScripts; diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 33f2dce7c..48d12f0a6 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -201,7 +201,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot +MWBase::Environment::get().getWorld()->countSavedGameRecords() +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() - +1; // global map + +MWBase::Environment::get().getWindowManager()->countSavedGameRecords(); writer.setRecordCount (recordCount); writer.save (stream); @@ -323,7 +323,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl break; case ESM::REC_GMAP: - + case ESM::REC_KEYS: MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val); break; diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index 4d5b36c74..b2a1637f1 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -34,6 +34,12 @@ struct Position }; #pragma pack(pop) +template +struct FourCC +{ + static const unsigned int value = (((((d << 8) | c) << 8) | b) << 8) | a; +}; + enum RecNameInts { // format 0 / legacy @@ -93,6 +99,7 @@ enum RecNameInts REC_GMAP = 0x50414d47, REC_DIAS = 0x53414944, REC_WTHR = 0x52485457, + REC_KEYS = FourCC<'K','E','Y','S'>::value, // format 1 REC_FILT = 0x544C4946 From 6381b1e9381436a22c8a3af212bd4b4145607529 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 11:20:43 +0200 Subject: [PATCH 029/121] Fixes #1309: Do not allow saving while dialogs are opened, just like vanilla This limitation could be removed post-1.0 by serializing the state of open windows. --- apps/openmw/mwbase/windowmanager.hpp | 3 +++ apps/openmw/mwgui/mainmenu.cpp | 3 ++- apps/openmw/mwgui/referenceinterface.hpp | 2 ++ apps/openmw/mwgui/windowmanagerimp.cpp | 20 ++++++++++++++++++++ apps/openmw/mwgui/windowmanagerimp.hpp | 3 +++ apps/openmw/mwstate/statemanagerimp.cpp | 5 +++-- 6 files changed, 33 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index c78902a60..9e5230af6 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -306,6 +306,9 @@ namespace MWBase virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0; virtual int countSavedGameRecords() const = 0; + + /// Does the current stack of GUI-windows permit saving? + virtual bool isSavingAllowed() const = 0; }; } diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index df9c53ea8..8b44af2ef 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -170,7 +170,8 @@ namespace MWGui buttons.push_back("loadgame"); if (state==MWBase::StateManager::State_Running && - MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1) + MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 && + MWBase::Environment::get().getWindowManager()->isSavingAllowed()) buttons.push_back("savegame"); buttons.push_back("options"); diff --git a/apps/openmw/mwgui/referenceinterface.hpp b/apps/openmw/mwgui/referenceinterface.hpp index 39574d0f7..df53a42b7 100644 --- a/apps/openmw/mwgui/referenceinterface.hpp +++ b/apps/openmw/mwgui/referenceinterface.hpp @@ -17,6 +17,8 @@ namespace MWGui void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable + void resetReference() { mPtr = MWWorld::Ptr(); mCurrentPlayerCell = NULL; } + protected: virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1b4145e5c..d2a31e8d1 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1406,6 +1406,19 @@ namespace MWGui { mMap->clear(); mQuickKeysMenu->clear(); + + mTrainingWindow->resetReference(); + mDialogueWindow->resetReference(); + mTradeWindow->resetReference(); + mSpellBuyingWindow->resetReference(); + mSpellCreationDialog->resetReference(); + mEnchantingDialog->resetReference(); + mContainerWindow->resetReference(); + mCompanionWindow->resetReference(); + mConsole->resetReference(); + + mGuiModes.clear(); + updateVisible(); } void WindowManager::write(ESM::ESMWriter &writer, Loading::Listener& progress) @@ -1430,6 +1443,13 @@ namespace MWGui + 1; // QuickKeysMenu } + bool WindowManager::isSavingAllowed() const + { + return !MyGUI::InputManager::getInstance().isModalAny() + // TODO: remove this, once we have properly serialized the state of open windows + && (!isGuiMode() || (mGuiModes.size() == 1 && getMode() == GM_MainMenu)); + } + void WindowManager::playVideo(const std::string &name, bool allowSkipping) { mVideoWidget->playVideo("video\\" + name, allowSkipping); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 44bc56654..e31013b45 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -295,6 +295,9 @@ namespace MWGui virtual void readRecord (ESM::ESMReader& reader, int32_t type); virtual int countSavedGameRecords() const; + /// Does the current stack of GUI-windows permit saving? + virtual bool isSavingAllowed() const; + private: bool mConsoleOnlyScripts; diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 48d12f0a6..c718eeced 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -235,8 +235,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot void MWState::StateManager::quickSave (std::string name) { - if (mState!=State_Running || - MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")!=-1) // char gen + if (!(mState==State_Running && + MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 // char gen + && MWBase::Environment::get().getWindowManager()->isSavingAllowed())) { //You can not save your game right now MWBase::Environment::get().getWindowManager()->messageBox("#{sSaveGameDenied}"); From f8cc328b5e63e2eed325cde7b97bc7ee1d8bacb7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 11:26:05 +0200 Subject: [PATCH 030/121] Slightly prettier backdrop when loading game from main menu. --- apps/openmw/mwgui/savegamedialog.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index a77c625f9..c0daa2c0e 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -206,6 +206,13 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage65}"); return; } + } + + setVisible(false); + MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu); + + if (mSaving) + { MWBase::Environment::get().getStateManager()->saveGame (mSaveNameEdit->getCaption(), mCurrentSlot); } else @@ -213,12 +220,9 @@ namespace MWGui if (mCurrentCharacter && mCurrentSlot) { MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot); - MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu); } } - setVisible(false); - if (MWBase::Environment::get().getStateManager()->getState()== MWBase::StateManager::State_NoGame) { From 8560b43464a9af526e34ce23b17423ed9a577fe1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 12:47:28 +0200 Subject: [PATCH 031/121] Move to esm component --- apps/openmw/mwgui/quickkeysmenu.cpp | 36 ++++++++++++++---------- components/CMakeLists.txt | 2 +- components/esm/quickkeys.cpp | 43 +++++++++++++++++++++++++++++ components/esm/quickkeys.hpp | 28 +++++++++++++++++++ 4 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 components/esm/quickkeys.cpp create mode 100644 components/esm/quickkeys.hpp diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index fb41b3b67..51e24e29c 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" @@ -385,39 +387,41 @@ namespace MWGui void QuickKeysMenu::write(ESM::ESMWriter &writer) { - const std::string recKey = "KEY_"; writer.startRecord(ESM::REC_KEYS); + ESM::QuickKeys keys; + for (int i=0; i<10; ++i) { - writer.startSubRecord(recKey); - MyGUI::Button* button = mQuickKeyButtons[i]; int type = *button->getUserData(); - writer.writeHNT("TYPE", type); + + ESM::QuickKeys::QuickKey key; + key.mType = type; switch (type) { case Type_Unassigned: - writer.writeHNString("ID__", ""); break; case Type_Item: case Type_MagicItem: { MWWorld::Ptr item = *button->getChildAt(0)->getUserData(); - writer.writeHNString("ID__", item.getCellRef().mRefID); + key.mId = item.getCellRef().mRefID; break; } case Type_Magic: std::string spellId = button->getChildAt(0)->getUserString("Spell"); - writer.writeHNString("ID__", spellId); + key.mId = spellId; break; } - writer.endRecord(recKey); + keys.mKeys.push_back(key); } + keys.save(writer); + writer.endRecord(ESM::REC_KEYS); } @@ -426,17 +430,18 @@ namespace MWGui if (type != ESM::REC_KEYS) return; + ESM::QuickKeys keys; + keys.load(reader); + int i=0; - while (reader.isNextSub("KEY_")) + for (std::vector::const_iterator it = keys.mKeys.begin(); it != keys.mKeys.end(); ++it) { - reader.getSubHeader(); - int keyType; - reader.getHNT(keyType, "TYPE"); - std::string id; - id = reader.getHNString("ID__"); + if (i >= 10) + return; mSelectedIndex = i; - + int keyType = it->mType; + std::string id = it->mId; MyGUI::Button* button = mQuickKeyButtons[i]; switch (keyType) @@ -480,6 +485,7 @@ namespace MWGui unassign(button, i); break; } + ++i; } } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 38be5b11a..1c60dfb83 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -45,7 +45,7 @@ add_component_dir (esm loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate - npcstats creaturestats weatherstate + npcstats creaturestats weatherstate quickkeys ) add_component_dir (misc diff --git a/components/esm/quickkeys.cpp b/components/esm/quickkeys.cpp new file mode 100644 index 000000000..ad2b671aa --- /dev/null +++ b/components/esm/quickkeys.cpp @@ -0,0 +1,43 @@ +#include "quickkeys.hpp" + +#include "esmwriter.hpp" +#include "esmreader.hpp" + +namespace ESM +{ + + void QuickKeys::load(ESMReader &esm) + { + while (esm.isNextSub("KEY_")) + { + esm.getSubHeader(); + int keyType; + esm.getHNT(keyType, "TYPE"); + std::string id; + id = esm.getHNString("ID__"); + + QuickKey key; + key.mType = keyType; + key.mId = id; + + mKeys.push_back(key); + } + } + + void QuickKeys::save(ESMWriter &esm) const + { + const std::string recKey = "KEY_"; + + for (std::vector::const_iterator it = mKeys.begin(); it != mKeys.end(); ++it) + { + esm.startSubRecord(recKey); + + esm.writeHNT("TYPE", it->mType); + esm.writeHNString("ID__", it->mId); + + esm.endRecord(recKey); + } + } + + +} diff --git a/components/esm/quickkeys.hpp b/components/esm/quickkeys.hpp new file mode 100644 index 000000000..c52466b13 --- /dev/null +++ b/components/esm/quickkeys.hpp @@ -0,0 +1,28 @@ +#ifndef OPENMW_COMPONENTS_ESM_QUICKKEYS_H +#define OPENMW_COMPONENTS_ESM_QUICKKEYS_H + +#include +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + struct QuickKeys + { + struct QuickKey + { + int mType; + std::string mId; // Spell or Item ID + }; + + std::vector mKeys; + + void load (ESMReader &esm); + void save (ESMWriter &esm) const; + }; + +} + +#endif From 58d868d56af79a09f1a5c567beca27c75f6eb089 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 19:16:10 +0200 Subject: [PATCH 032/121] Change default water setting (current fps is low enough as it is without this setting enabled) --- files/settings-default.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/settings-default.cfg b/files/settings-default.cfg index f24636d15..2b44d0f4e 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -133,9 +133,9 @@ distant land = false shader = true [Water] -shader = true +shader = false -refraction = true +refraction = false rtt size = 512 reflect terrain = true From 7f1df878f690c11b2e9b2e275ab1a5f01b7ffcb5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 2 May 2014 20:15:46 +0200 Subject: [PATCH 033/121] make getDropType static and public. --- apps/opencs/view/render/worldspacewidget.cpp | 2 +- apps/opencs/view/render/worldspacewidget.hpp | 30 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 925dd921b..16ff0a403 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -54,7 +54,7 @@ CSVWorld::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( } CSVRender::WorldspaceWidget::dropType CSVRender::WorldspaceWidget::getDropType ( - const std::vector< CSMWorld::UniversalId >& data) const + const std::vector< CSMWorld::UniversalId >& data) { dropType output = notCells; bool firstIteration = true; diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 83ef593d6..f9d4f9a06 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -30,20 +30,6 @@ namespace CSVRender public: - WorldspaceWidget (const CSMDoc::Document& document, QWidget *parent = 0); - - CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent); - ///< \attention The created tool is not added to the toolbar (via addTool). Doing that - /// is the responsibility of the calling function. - - void selectDefaultNavigationMode(); - - virtual void useViewHint (const std::string& hint); - ///< Default-implementation: ignored. - - protected: - const CSMDoc::Document& mDocument; //for checking if drop comes from same document - enum dropType { cellsMixed, @@ -52,7 +38,21 @@ namespace CSVRender notCells }; - dropType getDropType(const std::vector& data) const; + WorldspaceWidget (const CSMDoc::Document& document, QWidget *parent = 0); + + CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent); + ///< \attention The created tool is not added to the toolbar (via addTool). Doing that + /// is the responsibility of the calling function. + + void selectDefaultNavigationMode(); + + static dropType getDropType(const std::vector& data); + + virtual void useViewHint (const std::string& hint); + ///< Default-implementation: ignored. + + protected: + const CSMDoc::Document& mDocument; //for checking if drop comes from same document private: From 92467ba6bc5b91f5e4487a5bca5100f8d6a13930 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 20:55:58 +0200 Subject: [PATCH 034/121] Fix sunlight for interiors --- apps/openmw/mwrender/renderingmanager.cpp | 3 ++- apps/openmw/mwworld/weather.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 97283d065..19d26a176 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -563,7 +563,8 @@ void RenderingManager::configureAmbient(MWWorld::CellStore &mCell) Ogre::ColourValue colour; colour.setAsABGR (mCell.getCell()->mAmbi.mSunlight); mSun->setDiffuseColour (colour); - mSun->setDirection(0,-1,0); + mSun->setDirection(1,-1,-1); + sunEnable(false); } } // Switch through lighting modes. diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 3611114a9..25f523bee 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -329,7 +329,6 @@ void WeatherManager::update(float duration) const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior()); if (!exterior) { - mRendering->sunDisable(false); mRendering->skyDisable(); mRendering->getSkyManager()->setLightningStrength(0.f); stopSounds(true); From df1694c27b49d239d270b58ddc694c2fc74b13fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 22:19:02 +0200 Subject: [PATCH 035/121] Console autocompletion: List candidates when repeatedly pressing tab (bash-style) --- apps/openmw/mwgui/console.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 01eb770f7..d51d4298f 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -215,16 +215,22 @@ namespace MWGui { std::vector matches; listNames(); - mCommandLine->setCaption(complete( mCommandLine->getOnlyText(), matches )); -#if 0 - int i = 0; - for(std::vector::iterator it=matches.begin(); it < matches.end(); ++it,++i ) + std::string oldCaption = mCommandLine->getCaption(); + std::string newCaption = complete( mCommandLine->getOnlyText(), matches ); + mCommandLine->setCaption(newCaption); + + // List candidates if repeatedly pressing tab + if (oldCaption == newCaption && matches.size()) { - printOK( *it ); - if( i == 50 ) - break; + int i = 0; + printOK(""); + for(std::vector::iterator it=matches.begin(); it < matches.end(); ++it,++i ) + { + printOK( *it ); + if( i == 50 ) + break; + } } -#endif } if(mCommandHistory.empty()) return; From 1b074e55243cf17be2f5b5ee9b4783bcacb7c146 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 22:38:39 +0200 Subject: [PATCH 036/121] Call setAttacked even if the attack missed. Unsuccessful hits should also evoke a response. --- apps/openmw/mwclass/npc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e43bfe40d..5222eac44 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -624,6 +624,8 @@ namespace MWClass if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); + getCreatureStats(ptr).setAttacked(true); + if(!successful) { // TODO: Handle HitAttemptOnMe script function @@ -659,7 +661,6 @@ namespace MWClass { MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); } - getCreatureStats(ptr).setAttacked(true); // Check for knockdown float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat(); From e7b9b6d87abdd1201ec764c5acd2cb6803e6b5f6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 May 2014 23:07:01 +0200 Subject: [PATCH 037/121] Fix a confusing variable name --- extern/sdl4ogre/sdlinputwrapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index c3ea2fd74..09a244177 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -241,8 +241,8 @@ namespace SFO //eep, wrap the pointer manually if the input driver doesn't support //relative positioning natively - int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); - if(relative && success != 0) + bool success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == 0; + if(relative && !success) mWrapPointer = true; //now remove all mouse events using the old setting from the queue From 7331a64e34523743b57982e61be6105a91610c6b Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 3 May 2014 11:33:20 +0200 Subject: [PATCH 038/121] Restore fix for Bug #875 (commit 602be9bbe7f2, was broken by 43757efdc4af643) --- apps/openmw/mwworld/physicssystem.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 247c0d4bd..e30a2bbc1 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -227,10 +227,6 @@ namespace MWWorld Ogre::Vector3 inertia(0.0f); Ogre::Vector3 velocity; - bool canWalk = ptr.getClass().canWalk(ptr); - bool isBipedal = ptr.getClass().isBipedal(ptr); - bool isNpc = ptr.getClass().isNpc(); - if(position.z < waterlevel || isFlying) // under water by 3/4 or can fly { // TODO: Shouldn't water have higher drag in calculating velocity? @@ -277,14 +273,11 @@ namespace MWWorld // NOTE: velocity is either z axis only or x & z axis Ogre::Vector3 nextpos = newPosition + velocity * remainingTime; - // If not able to fly, walk or bipedal don't allow to move out of water + // If not able to fly, don't allow to swim up into the air // TODO: this if condition may not work for large creatures or situations // where the creature gets above the waterline for some reason if(newPosition.z < waterlevel && // started 3/4 under water !isFlying && // can't fly - !canWalk && // can't walk - !isBipedal && // not bipedal (assume bipedals can walk) - !isNpc && // FIXME: shouldn't really need this nextpos.z > waterlevel && // but about to go above water newPosition.z <= waterlevel) { From e09218f164f9f2c52a44dfc4146652e426a987d6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 3 May 2014 12:07:05 +0200 Subject: [PATCH 039/121] moved load code from Document to Loader class --- apps/opencs/model/doc/document.cpp | 37 ++++----------------------- apps/opencs/model/doc/document.hpp | 8 ++---- apps/opencs/model/doc/loader.cpp | 41 +++++++++++++++++++++++++----- apps/opencs/model/doc/loader.hpp | 9 ++++++- 4 files changed, 50 insertions(+), 45 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 760c675a0..a441f4ae2 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -8,23 +8,6 @@ #include #endif -void CSMDoc::Document::load (const std::vector::const_iterator& begin, - const std::vector::const_iterator& end, bool lastAsModified) -{ - assert (begin!=end); - - std::vector::const_iterator end2 (end); - - if (lastAsModified) - --end2; - - for (std::vector::const_iterator iter (begin); iter!=end2; ++iter) - getData().loadFile (*iter, true, false); - - if (lastAsModified) - getData().loadFile (*end2, false, false); -} - void CSMDoc::Document::addGmsts() { static const char *gmstFloats[] = @@ -2272,21 +2255,6 @@ CSMDoc::Document::~Document() { } -void CSMDoc::Document::setupData() -{ - if (!mNew || mContentFiles.size()>1) - { - std::vector::const_iterator end = mContentFiles.end(); - - if (mNew) - --end; - - load (mContentFiles.begin(), end, !mNew); - } - - getData().loadFile (mProjectPath, false, true); -} - QUndoStack& CSMDoc::Document::getUndoStack() { return mUndoStack; @@ -2313,6 +2281,11 @@ const boost::filesystem::path& CSMDoc::Document::getSavePath() const return mSavePath; } +const boost::filesystem::path& CSMDoc::Document::getProjectPath() const +{ + return mProjectPath; +} + const std::vector& CSMDoc::Document::getContentFiles() const { return mContentFiles; diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index e19efd04e..11a4057d1 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -54,10 +54,6 @@ namespace CSMDoc Document (const Document&); Document& operator= (const Document&); - void load (const std::vector::const_iterator& begin, - const std::vector::const_iterator& end, bool lastAsModified); - ///< \param lastAsModified Store the last file in Modified instead of merging it into Base. - void createBase(); void addGmsts(); @@ -78,14 +74,14 @@ namespace CSMDoc ~Document(); - void setupData(); - QUndoStack& getUndoStack(); int getState() const; const boost::filesystem::path& getSavePath() const; + const boost::filesystem::path& getProjectPath() const; + const std::vector& getContentFiles() const; ///< \attention The last element in this collection is the file that is being edited, /// but with its original path instead of the save path. diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index dbaa2b4d5..5277b08d2 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -5,6 +5,9 @@ #include "document.hpp" +CSMDoc::Loader::Stage::Stage() : mFile (0) {} + + CSMDoc::Loader::Loader() { QTimer *timer = new QTimer (this); @@ -28,31 +31,57 @@ void CSMDoc::Loader::load() return; } - std::vector >::iterator iter = mDocuments.begin(); + std::vector >::iterator iter = mDocuments.begin(); Document *document = iter->first; - mDocuments.erase (iter); + int size = static_cast (document->getContentFiles().size()); + + if (document->isNew()) + --size; + + bool done = false; try { - document->setupData(); - emit documentLoaded (document); + if (iter->second.mFilegetData().loadFile (document->getContentFiles()[iter->second.mFile], + iter->second.mFilesecond.mFile==size) + { + document->getData().loadFile (document->getProjectPath(), false, true); + } + else + { + done = true; + } + + ++(iter->second.mFile); } catch (const std::exception& e) { + mDocuments.erase (iter); emit documentNotLoaded (document, e.what()); + return; + } + + if (done) + { + mDocuments.erase (iter); + emit documentLoaded (document); } } void CSMDoc::Loader::loadDocument (CSMDoc::Document *document) { - mDocuments.push_back (std::make_pair (document, false)); + mDocuments.push_back (std::make_pair (document, Stage())); } void CSMDoc::Loader::abortLoading (Document *document) { - for (std::vector >::iterator iter = mDocuments.begin(); + for (std::vector >::iterator iter = mDocuments.begin(); iter!=mDocuments.end(); ++iter) { if (iter->first==document) diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index 4e3db1815..dee7d06cb 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -15,9 +15,16 @@ namespace CSMDoc { Q_OBJECT + struct Stage + { + int mFile; + + Stage(); + }; + QMutex mMutex; QWaitCondition mThingsToDo; - std::vector > mDocuments; + std::vector > mDocuments; public: From 122e606e30ccc427f3049f653b47e74d49299e59 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 3 May 2014 12:09:34 +0200 Subject: [PATCH 040/121] Crime: improvement to arrest on sight for large bounties iCrimeThreshold controls the needed bounty to have guards run to the player and force dialogue. In vanilla, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or present a death sentence and attack (>= 5000 bounty). --- apps/openmw/mwmechanics/actors.cpp | 18 ++++++++---------- apps/openmw/mwmechanics/aisequence.cpp | 13 +++++++++---- components/esm/loadcrea.hpp | 2 +- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index b0b482cfd..38ebda268 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -719,22 +719,21 @@ namespace MWMechanics CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats(ptr); - // If I'm a guard and I'm not hostile - if (ptr.getClass().isClass(ptr, "Guard") && !creatureStats.isHostile()) + if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPersue && !creatureStats.isHostile()) { /// \todo Move me! I shouldn't be here... const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - float cutoff = float(esmStore.get().find("iCrimeThreshold")->getInt()) * - float(esmStore.get().find("iCrimeThresholdMultiplier")->getInt()) * - esmStore.get().find("fCrimeGoldDiscountMult")->getFloat(); - // Attack on sight if bounty is greater than the cutoff + float cutoff = float(esmStore.get().find("iCrimeThreshold")->getInt()); + // Force dialogue on sight if bounty is greater than the cutoff + // In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or attack (>= 5000 bounty) if ( player.getClass().getNpcStats(player).getBounty() >= cutoff + // TODO: do not run these two every frame. keep an Aware state for each actor and update it every 0.2 s or so? && MWBase::Environment::get().getWorld()->getLOS(ptr, player) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)) { - creatureStats.getAiSequence().stack(AiCombat(player), ptr); - creatureStats.setHostile(true); - npcStats.setCrimeId( MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() ); + creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)), ptr); + creatureStats.setAlarmed(true); + npcStats.setCrimeId(MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId()); } } @@ -767,7 +766,6 @@ namespace MWMechanics creatureStats.setHostile(true); } } - // if I didn't report a crime was I attacked? else if (creatureStats.getAttacked() && !creatureStats.isHostile()) { diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 6460b0305..acab7c786 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -93,11 +93,16 @@ void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration) { if (!mPackages.empty()) { - mLastAiPackage = mPackages.front()->getTypeId(); - if (mPackages.front()->execute (actor,duration)) + MWMechanics::AiPackage* package = mPackages.front(); + mLastAiPackage = package->getTypeId(); + if (package->execute (actor,duration)) { - delete *mPackages.begin(); - mPackages.erase (mPackages.begin()); + // To account for the rare case where AiPackage::execute() queued another AI package + // (e.g. AiPersue executing a dialogue script that uses startCombat) + std::list::iterator toRemove = + std::find(mPackages.begin(), mPackages.end(), package); + mPackages.erase(toRemove); + delete package; mDone = true; } else diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 817c0e43c..e459dded7 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -33,7 +33,7 @@ struct Creature Respawn = 0x002, Weapon = 0x004, // Has weapon and shield - None = 0x008, // ?? + None = 0x008, // ?? This flag appears set for every creature in Morrowind.esm Essential = 0x080, // Blood types From 7bddfc002529e0a37cb1a72f47cd5ef8ebb84818 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 3 May 2014 12:23:22 +0200 Subject: [PATCH 041/121] Fix some spelling mistakes. --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwmechanics/actors.cpp | 12 ++++++------ apps/openmw/mwmechanics/aipackage.hpp | 2 +- .../mwmechanics/{aipersue.cpp => aipursue.cpp} | 14 +++++++------- .../mwmechanics/{aipersue.hpp => aipursue.hpp} | 10 +++++----- apps/openmw/mwmechanics/aisequence.cpp | 8 ++++---- apps/openmw/mwmechanics/aisequence.hpp | 4 ++-- apps/openmw/mwworld/player.cpp | 10 +++++----- apps/openmw/mwworld/player.hpp | 6 +++--- components/esm/player.cpp | 6 +++--- components/esm/player.hpp | 4 ++-- 11 files changed, 39 insertions(+), 39 deletions(-) rename apps/openmw/mwmechanics/{aipersue.cpp => aipursue.cpp} (91%) rename apps/openmw/mwmechanics/{aipersue.hpp => aipursue.hpp} (68%) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index e83ae2d8d..0661508b8 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -67,7 +67,7 @@ add_openmw_dir (mwclass add_openmw_dir (mwmechanics mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects - drawstate spells activespells npcstats aipackage aisequence aipersue alchemy aiwander aitravel aifollow + drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting disease pickpocket levelledlist combat steering obstacle ) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 38ebda268..3c1a75d56 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -29,7 +29,7 @@ #include "aicombat.hpp" #include "aifollow.hpp" -#include "aipersue.hpp" +#include "aipursue.hpp" namespace { @@ -719,7 +719,7 @@ namespace MWMechanics CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats(ptr); - if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPersue && !creatureStats.isHostile()) + if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPursue && !creatureStats.isHostile()) { /// \todo Move me! I shouldn't be here... const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); @@ -731,7 +731,7 @@ namespace MWMechanics && MWBase::Environment::get().getWorld()->getLOS(ptr, player) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)) { - creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)), ptr); + creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr); creatureStats.setAlarmed(true); npcStats.setCrimeId(MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId()); } @@ -740,12 +740,12 @@ namespace MWMechanics // if I was a witness to a crime if (npcStats.getCrimeId() != -1) { - // if you've payed for your crimes and I havent noticed + // if you've paid for your crimes and I havent noticed if( npcStats.getCrimeId() <= MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() ) { // Calm witness down if (ptr.getClass().isClass(ptr, "Guard")) - creatureStats.getAiSequence().stopPersue(); + creatureStats.getAiSequence().stopPursuit(); creatureStats.getAiSequence().stopCombat(); // Reset factors to attack @@ -760,7 +760,7 @@ namespace MWMechanics else if (!creatureStats.isHostile()) { if (ptr.getClass().isClass(ptr, "Guard")) - creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)), ptr); + creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr); else creatureStats.getAiSequence().stack(AiCombat(player), ptr); creatureStats.setHostile(true); diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 8e015da15..bd172c373 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -20,7 +20,7 @@ namespace MWMechanics TypeIdFollow = 3, TypeIdActivate = 4, TypeIdCombat = 5, - TypeIdPersue = 6 + TypeIdPursue = 6 }; virtual ~AiPackage(); diff --git a/apps/openmw/mwmechanics/aipersue.cpp b/apps/openmw/mwmechanics/aipursue.cpp similarity index 91% rename from apps/openmw/mwmechanics/aipersue.cpp rename to apps/openmw/mwmechanics/aipursue.cpp index 36e18946c..8da5c640e 100644 --- a/apps/openmw/mwmechanics/aipersue.cpp +++ b/apps/openmw/mwmechanics/aipursue.cpp @@ -1,4 +1,4 @@ -#include "aipersue.hpp" +#include "aipursue.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" @@ -11,15 +11,15 @@ #include "movement.hpp" #include "creaturestats.hpp" -MWMechanics::AiPersue::AiPersue(const std::string &objectId) +MWMechanics::AiPursue::AiPursue(const std::string &objectId) : mObjectId(objectId) { } -MWMechanics::AiPersue *MWMechanics::AiPersue::clone() const +MWMechanics::AiPursue *MWMechanics::AiPursue::clone() const { - return new AiPersue(*this); + return new AiPursue(*this); } -bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration) +bool MWMechanics::AiPursue::execute (const MWWorld::Ptr& actor, float duration) { MWBase::World *world = MWBase::Environment::get().getWorld(); ESM::Position pos = actor.getRefData().getPosition(); @@ -100,7 +100,7 @@ bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration) return false; } -int MWMechanics::AiPersue::getTypeId() const +int MWMechanics::AiPursue::getTypeId() const { - return TypeIdPersue; + return TypeIdPursue; } diff --git a/apps/openmw/mwmechanics/aipersue.hpp b/apps/openmw/mwmechanics/aipursue.hpp similarity index 68% rename from apps/openmw/mwmechanics/aipersue.hpp rename to apps/openmw/mwmechanics/aipursue.hpp index 3fd708ab3..86750acca 100644 --- a/apps/openmw/mwmechanics/aipersue.hpp +++ b/apps/openmw/mwmechanics/aipursue.hpp @@ -1,5 +1,5 @@ -#ifndef GAME_MWMECHANICS_AIPERSUE_H -#define GAME_MWMECHANICS_AIPERSUE_H +#ifndef GAME_MWMECHANICS_AIPURSUE_H +#define GAME_MWMECHANICS_AIPURSUE_H #include "aipackage.hpp" #include @@ -9,11 +9,11 @@ namespace MWMechanics { - class AiPersue : public AiPackage + class AiPursue : public AiPackage { public: - AiPersue(const std::string &objectId); - virtual AiPersue *clone() const; + AiPursue(const std::string &objectId); + virtual AiPursue *clone() const; virtual bool execute (const MWWorld::Ptr& actor,float duration); ///< \return Package completed? virtual int getTypeId() const; diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index acab7c786..0b1da180d 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -73,9 +73,9 @@ void MWMechanics::AiSequence::stopCombat() } } -void MWMechanics::AiSequence::stopPersue() +void MWMechanics::AiSequence::stopPursuit() { - while (getTypeId() == AiPackage::TypeIdPersue) + while (getTypeId() == AiPackage::TypeIdPursue) { delete *mPackages.begin(); mPackages.erase (mPackages.begin()); @@ -98,7 +98,7 @@ void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration) if (package->execute (actor,duration)) { // To account for the rare case where AiPackage::execute() queued another AI package - // (e.g. AiPersue executing a dialogue script that uses startCombat) + // (e.g. AiPursue executing a dialogue script that uses startCombat) std::list::iterator toRemove = std::find(mPackages.begin(), mPackages.end(), package); mPackages.erase(toRemove); @@ -123,7 +123,7 @@ void MWMechanics::AiSequence::clear() void MWMechanics::AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor) { - if (package.getTypeId() == AiPackage::TypeIdCombat || package.getTypeId() == AiPackage::TypeIdPersue) + if (package.getTypeId() == AiPackage::TypeIdCombat || package.getTypeId() == AiPackage::TypeIdPursue) { // Notify AiWander of our current position so we can return to it after combat finished for (std::list::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter) diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp index cb1b0de02..614eb4154 100644 --- a/apps/openmw/mwmechanics/aisequence.hpp +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -50,8 +50,8 @@ namespace MWMechanics void stopCombat(); ///< Removes all combat packages until first non-combat or stack empty. - void stopPersue(); - ///< Removes all persue packages until first non-persue or stack empty. + void stopPursuit(); + ///< Removes all pursue packages until first non-pursue or stack empty. bool isPackageDone() const; ///< Has a package been completed during the last update? diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index c40d47d7f..12809755e 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -37,7 +37,7 @@ namespace MWWorld mTeleported(false), mMarkedCell(NULL), mCurrentCrimeId(-1), - mPayedCrimeId(-1) + mPaidCrimeId(-1) { mPlayer.mBase = player; mPlayer.mRef.mRefID = "player"; @@ -223,7 +223,7 @@ namespace MWWorld player.mCellId = mCellStore->getCell()->getCellId(); player.mCurrentCrimeId = mCurrentCrimeId; - player.mPayedCrimeId = mPayedCrimeId; + player.mPaidCrimeId = mPaidCrimeId; player.mBirthsign = mSign; @@ -273,7 +273,7 @@ namespace MWWorld throw std::runtime_error ("invalid player state record (birthsign)"); mCurrentCrimeId = player.mCurrentCrimeId; - mPayedCrimeId = player.mPayedCrimeId; + mPaidCrimeId = player.mPaidCrimeId; mSign = player.mBirthsign; @@ -318,11 +318,11 @@ namespace MWWorld void Player::recordCrimeId() { - mPayedCrimeId = mCurrentCrimeId; + mPaidCrimeId = mCurrentCrimeId; } int Player::getCrimeId() const { - return mPayedCrimeId; + return mPaidCrimeId; } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index b1de3e510..d8cde5952 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -48,7 +48,7 @@ namespace MWWorld bool mTeleported; int mCurrentCrimeId; // the id assigned witnesses - int mPayedCrimeId; // the last id payed off (0 bounty) + int mPaidCrimeId; // the last id paid off (0 bounty) public: @@ -105,8 +105,8 @@ namespace MWWorld bool readRecord (ESM::ESMReader& reader, int32_t type); int getNewCrimeId(); // get new id for witnesses - void recordCrimeId(); // record the payed crime id when bounty is 0 - int getCrimeId() const; // get the last payed crime id + void recordCrimeId(); // record the paid crime id when bounty is 0 + int getCrimeId() const; // get the last paid crime id }; } #endif diff --git a/components/esm/player.cpp b/components/esm/player.cpp index 70f795afe..52b44c945 100644 --- a/components/esm/player.cpp +++ b/components/esm/player.cpp @@ -28,8 +28,8 @@ void ESM::Player::load (ESMReader &esm) mCurrentCrimeId = -1; esm.getHNOT (mCurrentCrimeId, "CURD"); - mPayedCrimeId = -1; - esm.getHNOT (mPayedCrimeId, "PAYD"); + mPaidCrimeId = -1; + esm.getHNOT (mPaidCrimeId, "PAYD"); } void ESM::Player::save (ESMWriter &esm) const @@ -52,5 +52,5 @@ void ESM::Player::save (ESMWriter &esm) const esm.writeHNString ("SIGN", mBirthsign); esm.writeHNT ("CURD", mCurrentCrimeId); - esm.writeHNT ("PAYD", mPayedCrimeId); + esm.writeHNT ("PAYD", mPaidCrimeId); } diff --git a/components/esm/player.hpp b/components/esm/player.hpp index 377c8547a..440d0a2d9 100644 --- a/components/esm/player.hpp +++ b/components/esm/player.hpp @@ -26,11 +26,11 @@ namespace ESM std::string mBirthsign; int mCurrentCrimeId; - int mPayedCrimeId; + int mPaidCrimeId; void load (ESMReader &esm); void save (ESMWriter &esm) const; }; } -#endif \ No newline at end of file +#endif From e0e2ad8316eaf097a0191d1b3796ac97ab5e76a8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 3 May 2014 13:01:29 +0200 Subject: [PATCH 042/121] content file loading progress bar --- apps/opencs/main.cpp | 6 +++ apps/opencs/model/doc/documentmanager.cpp | 2 + apps/opencs/model/doc/documentmanager.hpp | 2 + apps/opencs/model/doc/loader.cpp | 9 ++++- apps/opencs/model/doc/loader.hpp | 2 + apps/opencs/view/doc/loader.cpp | 46 ++++++++++++++++++++++- apps/opencs/view/doc/loader.hpp | 10 +++++ apps/opencs/view/doc/viewmanager.cpp | 4 ++ 8 files changed, 78 insertions(+), 3 deletions(-) diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index eded36394..1febb1678 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -3,9 +3,11 @@ #include #include +#include #include #include +#include #include @@ -15,6 +17,8 @@ #include #endif +Q_DECLARE_METATYPE (std::string) + class Application : public QApplication { private: @@ -42,6 +46,8 @@ int main(int argc, char *argv[]) { Q_INIT_RESOURCE (resources); + qRegisterMetaType ("std::string"); + OgreInit::OgreInit ogreInit; std::auto_ptr shinyFactory; diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index ae6f1103f..f102dac70 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -29,6 +29,8 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con this, SLOT (documentNotLoaded (Document *, const std::string&))); connect (this, SIGNAL (loadRequest (CSMDoc::Document *)), &mLoader, SLOT (loadDocument (CSMDoc::Document *))); + connect (&mLoader, SIGNAL (nextStage (CSMDoc::Document *, const std::string&)), + this, SIGNAL (nextStage (CSMDoc::Document *, const std::string&))); } CSMDoc::DocumentManager::~DocumentManager() diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 4adc9726c..be9528659 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -71,6 +71,8 @@ namespace CSMDoc void loadingStopped (CSMDoc::Document *document, bool completed, const std::string& error); + + void nextStage (CSMDoc::Document *document, const std::string& name); }; } diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 5277b08d2..47cac1713 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -46,11 +46,16 @@ void CSMDoc::Loader::load() { if (iter->second.mFilegetData().loadFile (document->getContentFiles()[iter->second.mFile], - iter->second.mFilegetContentFiles()[iter->second.mFile]; + + emit nextStage (document, path.filename().string()); + + document->getData().loadFile (path, iter->second.mFilesecond.mFile==size) { + emit nextStage (document, "Project File"); + document->getData().loadFile (document->getProjectPath(), false, true); } else diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index dee7d06cb..270aeeb00 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -54,6 +54,8 @@ namespace CSMDoc void documentNotLoaded (Document *document, const std::string& error); ///< Document load has been interrupted either because of a call to abortLoading /// or a problem during loading). In the former case error will be an empty string. + + void nextStage (CSMDoc::Document *document, const std::string& name); }; } diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 15296d616..50c29eedb 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -1,14 +1,50 @@ #include "loader.hpp" +#include +#include +#include +#include + #include "../../model/doc/document.hpp" CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) { - setWindowTitle (("Loading " + document->getSavePath().filename().string()).c_str()); + setWindowTitle (("Opening " + document->getSavePath().filename().string()).c_str()); + + QVBoxLayout *layout = new QVBoxLayout (this); + + mFileProgress = new QProgressBar (this); + + layout->addWidget (mFileProgress); + + int size = static_cast (document->getContentFiles().size())+1; + if (document->isNew()) + --size; + + mFileProgress->setMinimum (0); + mFileProgress->setMaximum (size); + mFileProgress->setTextVisible (true); + mFileProgress->setValue (0); + + mFile = new QLabel (this); + + layout->addWidget (mFile); + + setLayout (layout); + + move (QCursor::pos()); + show(); } +void CSVDoc::LoadingDocument::nextStage (const std::string& name) +{ + mFile->setText (QString::fromUtf8 (("Loading: " + name).c_str())); + + mFileProgress->setValue (mFileProgress->value()+1); +} + CSVDoc::Loader::Loader() { @@ -41,4 +77,12 @@ void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed, break; } } +} + +void CSVDoc::Loader::nextStage (CSMDoc::Document *document, const std::string& name) +{ + std::map::iterator iter = mDocuments.find (document); + + if (iter!=mDocuments.end()) + iter->second->nextStage (name); } \ No newline at end of file diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index cb154b13e..ad1e3ffb8 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -6,6 +6,9 @@ #include #include +class QLabel; +class QProgressBar; + namespace CSMDoc { class Document; @@ -17,9 +20,14 @@ namespace CSVDoc { Q_OBJECT + QLabel *mFile; + QProgressBar *mFileProgress; + public: LoadingDocument (CSMDoc::Document *document); + + void nextStage (const std::string& name); }; class Loader : public QObject @@ -40,6 +48,8 @@ namespace CSVDoc void loadingStopped (CSMDoc::Document *document, bool completed, const std::string& error); + + void nextStage (CSMDoc::Document *document, const std::string& name); }; } diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index c18cca809..877bc1dea 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -93,6 +93,10 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) connect ( &mDocumentManager, SIGNAL (loadingStopped (CSMDoc::Document *, bool, const std::string&)), &mLoader, SLOT (loadingStopped (CSMDoc::Document *, bool, const std::string&))); + + connect ( + &mDocumentManager, SIGNAL (nextStage (CSMDoc::Document *, const std::string&)), + &mLoader, SLOT (nextStage (CSMDoc::Document *, const std::string&))); } CSVDoc::ViewManager::~ViewManager() From 5e9938101935cf28f92630c3a6c385a72e0664b8 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 3 May 2014 14:00:30 +0200 Subject: [PATCH 043/121] Drag and drop works. --- .../view/render/pagedworldspacewidget.cpp | 41 ++-- .../view/render/pagedworldspacewidget.hpp | 6 +- apps/opencs/view/render/scenewidget.cpp | 2 +- .../view/render/unpagedworldspacewidget.cpp | 42 ++-- .../view/render/unpagedworldspacewidget.hpp | 12 +- apps/opencs/view/render/worldspacewidget.cpp | 11 ++ apps/opencs/view/render/worldspacewidget.hpp | 30 ++- apps/opencs/view/world/scenesubview.cpp | 180 ++++++++++-------- apps/opencs/view/world/scenesubview.hpp | 16 +- 9 files changed, 186 insertions(+), 154 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index a6bdb5180..c9308fbfb 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -50,32 +50,6 @@ void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSel emit cellSelectionChanged (mSelection); } -void CSVRender::PagedWorldspaceWidget::dropEvent (QDropEvent* event) -{ - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); - - if (mime->fromDocument(mDocument)) - { - const std::vector& data(mime->getData()); - CSVRender::WorldspaceWidget::dropType whatHappend = getDropType(data); - - switch (whatHappend) - { - case CSVRender::WorldspaceWidget::cellsExterior: - handleDrop(data); - break; - - case CSVRender::WorldspaceWidget::cellsInterior: - emit interiorCellsDropped(data); - break; - - default: - //not interior or exterior = either mixed or not actually cells. We don't need to do anything in this case. - break; - } - } //not handling drops from different documents at the moment -} - std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (const std::string& record) const { std::istringstream stream (record.c_str()); @@ -101,3 +75,18 @@ void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld:: emit cellSelectionChanged(mSelection); } } + +CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const +{ + switch (type) + { + case cellsExterior: + return canHandle; + + case cellsInterior: + return needUnpaged; + + default: + return ignored; + } +} \ No newline at end of file diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index bd5d1107c..0a73c791c 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -15,8 +15,6 @@ namespace CSVRender private: - void dropEvent(QDropEvent* event); - std::pair getCoordinatesFromId(const std::string& record) const; public: @@ -32,11 +30,11 @@ namespace CSVRender virtual void handleDrop(const std::vector& data); + virtual dropRequirments getDropRequirements(dropType type) const; + signals: void cellSelectionChanged (const CSMWorld::CellSelection& selection); - - void interiorCellsDropped(const std::vector& data); }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 1aee421ed..8a58b7d32 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -320,7 +320,7 @@ namespace CSVRender } - if (mUpdate) + if (mUpdate && mWindow) { mUpdate = false; mWindow->update(); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 929088789..de4dde9dd 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -67,34 +67,24 @@ void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelI emit closeRequest(); } -void CSVRender::UnpagedWorldspaceWidget::dropEvent (QDropEvent* event) -{ - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); - - if (mime->fromDocument (mDocument)) - { - const std::vector& data (mime->getData()); - CSVRender::WorldspaceWidget::dropType whatHappend = getDropType (data); - - switch (whatHappend) - { - case CSVRender::WorldspaceWidget::cellsExterior: - emit exteriorCellsDropped(data); - break; - - case CSVRender::WorldspaceWidget::cellsInterior: - handleDrop(data); - break; - - default: - //not interior or exterior = either mixed or not actually cells. We don't need to do anything in this case. - break; - } - } //not handling drops from different documents at the moment -} - void CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data) { mCellId = data.begin()->getId(); update(); + emit cellChanged(*data.begin()); +} + +CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const +{ + switch(type) + { + case cellsInterior: + return canHandle; + + case cellsExterior: + return needPaged; + + default: + return ignored; + } } diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index ad1e22e39..bb5340845 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -31,14 +31,11 @@ namespace CSVRender public: UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, - QWidget *parent); + QWidget *parent); + virtual dropRequirments getDropRequirements(dropType type) const; - private: - - void handleDrop(const std::vector& data); - - void dropEvent(QDropEvent* event); + virtual void handleDrop(const std::vector& data); private slots: @@ -48,8 +45,7 @@ namespace CSVRender signals: - void exteriorCellsDropped(const std::vector& data); - + void cellChanged(const CSMWorld::UniversalId& id); }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 16ff0a403..c83a5a3e1 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -115,3 +115,14 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event) { event->accept(); } + + +void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) +{ + const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + + if (mime->fromDocument (mDocument)) + { + emit dataDropped(mime->getData()); + } //not handling drops from different documents at the moment +} \ No newline at end of file diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index f9d4f9a06..a14e03915 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -7,6 +7,7 @@ #include "navigationfree.hpp" #include "navigationorbit.hpp" #include +#include namespace CSMWorld { @@ -30,13 +31,21 @@ namespace CSVRender public: - enum dropType - { - cellsMixed, - cellsInterior, - cellsExterior, - notCells - }; + enum dropType + { + cellsMixed, + cellsInterior, + cellsExterior, + notCells + }; + + enum dropRequirments + { + canHandle, + needPaged, + needUnpaged, + ignored //either mixed cells, or not cells + }; WorldspaceWidget (const CSMDoc::Document& document, QWidget *parent = 0); @@ -48,9 +57,13 @@ namespace CSVRender static dropType getDropType(const std::vector& data); + virtual dropRequirments getDropRequirements(dropType type) const = 0; + virtual void useViewHint (const std::string& hint); ///< Default-implementation: ignored. + virtual void handleDrop(const std::vector& data) = 0; + protected: const CSMDoc::Document& mDocument; //for checking if drop comes from same document @@ -58,6 +71,8 @@ namespace CSVRender void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent* event); + void dragMoveEvent(QDragMoveEvent *event); private slots: @@ -67,6 +82,7 @@ namespace CSVRender signals: void closeRequest(); + void dataDropped(const std::vector& data); }; } diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index f3807e4e9..d411985b3 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "../../model/doc/document.hpp" @@ -21,7 +22,7 @@ #include "scenetoolmode.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mLayout(new QHBoxLayout), mDocument(document) +: SubView (id), mLayout(new QHBoxLayout), mDocument(document), mScene(NULL), mToolbar(NULL) { QVBoxLayout *layout = new QVBoxLayout; @@ -33,39 +34,26 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); - mToolbar = new SceneToolbar (48+6, this); + CSVRender::WorldspaceWidget* wordspaceWidget = NULL; if (id.getId()=="sys::default") { - CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this, document); + CSVRender::PagedWorldspaceWidget *newWidget = new CSVRender::PagedWorldspaceWidget (this, document); - mScene = widget; + wordspaceWidget = newWidget; - connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), - this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); - - connect (widget, SIGNAL(interiorCellsDropped (const std::vector&)), - this, SLOT(changeToUnpaged (const std::vector&))); + makeConnections(newWidget); } else { - CSVRender::UnpagedWorldspaceWidget *widget = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); + CSVRender::UnpagedWorldspaceWidget *newWidget = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); - mScene = widget; + wordspaceWidget = newWidget; - connect (widget, SIGNAL(exteriorCellsDropped(const std::vector&)), - this, SLOT(changeToUnpaged(const std::vector&))); + makeConnections(newWidget); } - SceneToolMode *navigationTool = mScene->makeNavigationSelector (mToolbar); - mToolbar->addTool (navigationTool); - - SceneToolMode *lightingTool = mScene->makeLightingSelector (mToolbar); - mToolbar->addTool (lightingTool); - - mLayout->addWidget (mToolbar, 0); - - mLayout->addWidget (mScene, 1); + replaceToolbarAndWorldspace(wordspaceWidget, makeToolbar(wordspaceWidget)); layout->insertLayout (0, mLayout, 1); @@ -78,10 +66,41 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D widget->setLayout (layout); setWidget (widget); +} - mScene->selectDefaultNavigationMode(); +void CSVWorld::SceneSubView::makeConnections (CSVRender::UnpagedWorldspaceWidget* widget) +{ + connect (widget, SIGNAL (closeRequest()), this, SLOT (closeRequest())); - connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); + connect(widget, SIGNAL(dataDropped(const std::vector&)), + this, SLOT(handleDrop(const std::vector&))); + + connect(widget, SIGNAL(cellChanged(const CSMWorld::UniversalId&)), + this, SLOT(cellSelectionChanged(const CSMWorld::UniversalId&))); +} + +void CSVWorld::SceneSubView::makeConnections (CSVRender::PagedWorldspaceWidget* widget) +{ + connect (widget, SIGNAL (closeRequest()), this, SLOT (closeRequest())); + + connect(widget, SIGNAL(dataDropped(const std::vector&)), + this, SLOT(handleDrop(const std::vector&))); + + connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), + this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); +} + +CSVWorld::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget) +{ + CSVWorld::SceneToolbar* toolbar = new SceneToolbar (48+6, this); + + SceneToolMode *navigationTool = widget->makeNavigationSelector (toolbar); + toolbar->addTool (navigationTool); + + SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar); + toolbar->addTool (lightingTool); + + return toolbar; } void CSVWorld::SceneSubView::setEditLock (bool locked) @@ -111,8 +130,19 @@ void CSVWorld::SceneSubView::closeRequest() deleteLater(); } +void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id) +{ + setUniversalId(id); + std::ostringstream stream; + stream << "Scene: " << getUniversalId().getId(); + + setWindowTitle (QString::fromUtf8 (stream.str().c_str())); +} + + void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection) { + setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Cell, "sys::default")); int size = selection.getSize(); std::ostringstream stream; @@ -137,70 +167,60 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection setWindowTitle (QString::fromUtf8 (stream.str().c_str())); } -void CSVWorld::SceneSubView::changeToPaged (const std::vector< CSMWorld::UniversalId >& data) +void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalId >& data) { - mLayout->removeWidget(mToolbar); - mLayout->removeWidget(mScene); + CSVRender::PagedWorldspaceWidget* pagedNewWidget = NULL; + CSVRender::UnpagedWorldspaceWidget* unPagedNewWidget = NULL; + SceneToolbar* toolbar = NULL; - delete mScene; - delete mToolbar; + switch (mScene->getDropRequirements(CSVRender::WorldspaceWidget::getDropType(data))) + { + case CSVRender::WorldspaceWidget::canHandle: + mScene->handleDrop(data); + break; - setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Cell, "sys::default")); - mToolbar = new SceneToolbar (48+6, this); + case CSVRender::WorldspaceWidget::needPaged: + pagedNewWidget = new CSVRender::PagedWorldspaceWidget(this, mDocument); + toolbar = makeToolbar(pagedNewWidget); + makeConnections(pagedNewWidget); + replaceToolbarAndWorldspace(pagedNewWidget, toolbar); + mScene->handleDrop(data); + break; - CSVRender::PagedWorldspaceWidget* widget = new CSVRender::PagedWorldspaceWidget (this, mDocument); + case CSVRender::WorldspaceWidget::needUnpaged: + unPagedNewWidget = new CSVRender::UnpagedWorldspaceWidget(data.begin()->getId(), mDocument, this); + toolbar = makeToolbar(unPagedNewWidget); + makeConnections(unPagedNewWidget); + replaceToolbarAndWorldspace(unPagedNewWidget, toolbar); + cellSelectionChanged(*(data.begin())); + break; + + case CSVRender::WorldspaceWidget::ignored: + return; + } +} + +void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceWidget* widget, CSVWorld::SceneToolbar* toolbar) +{ + assert(mLayout); + + if (mScene) + { + mLayout->removeWidget(mScene); + mScene->deleteLater(); + } + + if (mToolbar) + { + mLayout->removeWidget(mToolbar); + mToolbar->deleteLater(); + } mScene = widget; - - SceneToolMode* navigationTool = mScene->makeNavigationSelector (mToolbar); - mToolbar->addTool (navigationTool); - - SceneToolMode* lightingTool = mScene->makeLightingSelector (mToolbar); - mToolbar->addTool (lightingTool); - - connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), - this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); - - connect (widget, SIGNAL (interiorCellsDropped (const std::vector&)), - this, SLOT (changeToUnpaged (const std::vector&))); + mToolbar = toolbar; mLayout->addWidget (mToolbar, 0); mLayout->addWidget (mScene, 1); mScene->selectDefaultNavigationMode(); - - connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); - - widget->handleDrop (data); -} - -void CSVWorld::SceneSubView::changeToUnpaged (const std::vector< CSMWorld::UniversalId >& data) -{ - mLayout->removeWidget(mToolbar); - mLayout->removeWidget(mScene); - - delete mScene; - delete mToolbar; - - mToolbar = new SceneToolbar (48+6, this); - CSVRender::UnpagedWorldspaceWidget* widget = new CSVRender::UnpagedWorldspaceWidget (data.begin()->getId(), mDocument, this); - setUniversalId(*(data.begin())); - - mScene = widget; - - SceneToolMode* navigationTool = mScene->makeNavigationSelector (mToolbar); - mToolbar->addTool (navigationTool); - - SceneToolMode* lightingTool = mScene->makeLightingSelector (mToolbar); - mToolbar->addTool (lightingTool); - - connect (widget, SIGNAL (exteriorCellsDropped (const std::vector&)), - this, SLOT (changeToPaged (const std::vector&))); - - mLayout->addWidget (mToolbar, 0); - mLayout->addWidget (mScene, 1); - - mScene->selectDefaultNavigationMode(); - - connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); -} +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 9af76ef6a..251ddae1f 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -21,6 +21,8 @@ namespace CSMDoc namespace CSVRender { class WorldspaceWidget; + class PagedWorldspaceWidget; + class UnpagedWorldspaceWidget; } namespace CSVWorld @@ -51,15 +53,25 @@ namespace CSVWorld virtual void useHint (const std::string& hint); + private: + + void makeConnections(CSVRender::PagedWorldspaceWidget* widget); + + void makeConnections(CSVRender::UnpagedWorldspaceWidget* widget); + + void replaceToolbarAndWorldspace(CSVRender::WorldspaceWidget* widget, SceneToolbar* toolbar); + + SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget); + private slots: void closeRequest(); void cellSelectionChanged (const CSMWorld::CellSelection& selection); - void changeToPaged(const std::vector& data); + void cellSelectionChanged (const CSMWorld::UniversalId& id); - void changeToUnpaged(const std::vector& data); + void handleDrop(const std::vector& data); }; } From 6692d2dc724d988a6e3224e0946b8cca53b07df4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 3 May 2014 15:05:02 +0200 Subject: [PATCH 044/121] split up load function in a start and continue part --- apps/opencs/model/doc/loader.cpp | 18 +- apps/opencs/model/doc/loader.hpp | 1 + apps/opencs/model/world/data.cpp | 289 ++++++++++++++++--------------- apps/opencs/model/world/data.hpp | 20 ++- 4 files changed, 187 insertions(+), 141 deletions(-) diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 47cac1713..85bfececd 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -5,7 +5,7 @@ #include "document.hpp" -CSMDoc::Loader::Stage::Stage() : mFile (0) {} +CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLeft (false) {} CSMDoc::Loader::Loader() @@ -13,7 +13,7 @@ CSMDoc::Loader::Loader() QTimer *timer = new QTimer (this); connect (timer, SIGNAL (timeout()), this, SLOT (load())); - timer->start (1000); + timer->start(); } QWaitCondition& CSMDoc::Loader::hasThingsToDo() @@ -44,19 +44,29 @@ void CSMDoc::Loader::load() try { + if (iter->second.mRecordsLeft) + { + if (document->getData().continueLoading()) + iter->second.mRecordsLeft = false; + + return; + } + if (iter->second.mFilegetContentFiles()[iter->second.mFile]; emit nextStage (document, path.filename().string()); - document->getData().loadFile (path, iter->second.mFilegetData().startLoading (path, iter->second.mFilesecond.mRecordsLeft = true; } else if (iter->second.mFile==size) { emit nextStage (document, "Project File"); - document->getData().loadFile (document->getProjectPath(), false, true); + document->getData().startLoading (document->getProjectPath(), false, true); + iter->second.mRecordsLeft = true; } else { diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index 270aeeb00..5e86e4e67 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -18,6 +18,7 @@ namespace CSMDoc struct Stage { int mFile; + bool mRecordsLeft; Stage(); }; diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index d60dcae11..93b734e27 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -55,7 +55,10 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec return number; } -CSMWorld::Data::Data() : mRefs (mCells) +CSMWorld::Data::Data() +/// \todo set encoding properly, once config implementation has been fixed. +: mEncoder (ToUTF8::calculateEncoding ("win1252")), + mRefs (mCells), mReader (0), mDialogue (0) { mGlobals.addColumn (new StringIdColumn); mGlobals.addColumn (new RecordStateColumn); @@ -260,6 +263,8 @@ CSMWorld::Data::~Data() { for (std::vector::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter) delete *iter; + + delete mReader; } const CSMWorld::IdCollection& CSMWorld::Data::getGlobals() const @@ -481,148 +486,162 @@ void CSMWorld::Data::merge() mGlobals.merge(); } -void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, bool project) +int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base, bool project) { - ESM::ESMReader reader; + delete mReader; + mReader = 0; + mDialogue = 0; - /// \todo set encoding properly, once config implementation has been fixed. - ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding ("win1252")); - reader.setEncoder (&encoder); + mReader = new ESM::ESMReader; + mReader->setEncoder (&mEncoder); + mReader->open (path.string()); - reader.open (path.string()); + mBase = base; + mProject = project; - const ESM::Dialogue *dialogue = 0; + mAuthor = mReader->getAuthor(); + mDescription = mReader->getDesc(); - mAuthor = reader.getAuthor(); - mDescription = reader.getDesc(); + return mReader->getRecordCount(); +} - // Note: We do not need to send update signals here, because at this point the model is not connected - // to any view. - while (reader.hasMoreRecs()) +bool CSMWorld::Data::continueLoading() +{ + if (!mReader) + throw std::logic_error ("can't continue loading, because no load has been started"); + + if (!mReader->hasMoreRecs()) { - ESM::NAME n = reader.getRecName(); - reader.getRecHeader(); - - switch (n.val) - { - case ESM::REC_GLOB: mGlobals.load (reader, base); break; - case ESM::REC_GMST: mGmsts.load (reader, base); break; - case ESM::REC_SKIL: mSkills.load (reader, base); break; - case ESM::REC_CLAS: mClasses.load (reader, base); break; - case ESM::REC_FACT: mFactions.load (reader, base); break; - case ESM::REC_RACE: mRaces.load (reader, base); break; - case ESM::REC_SOUN: mSounds.load (reader, base); break; - case ESM::REC_SCPT: mScripts.load (reader, base); break; - case ESM::REC_REGN: mRegions.load (reader, base); break; - case ESM::REC_BSGN: mBirthsigns.load (reader, base); break; - case ESM::REC_SPEL: mSpells.load (reader, base); break; - - case ESM::REC_CELL: - mCells.load (reader, base); - mRefs.load (reader, mCells.getSize()-1, base); - break; - - case ESM::REC_ACTI: mReferenceables.load (reader, base, UniversalId::Type_Activator); break; - case ESM::REC_ALCH: mReferenceables.load (reader, base, UniversalId::Type_Potion); break; - case ESM::REC_APPA: mReferenceables.load (reader, base, UniversalId::Type_Apparatus); break; - case ESM::REC_ARMO: mReferenceables.load (reader, base, UniversalId::Type_Armor); break; - case ESM::REC_BOOK: mReferenceables.load (reader, base, UniversalId::Type_Book); break; - case ESM::REC_CLOT: mReferenceables.load (reader, base, UniversalId::Type_Clothing); break; - case ESM::REC_CONT: mReferenceables.load (reader, base, UniversalId::Type_Container); break; - case ESM::REC_CREA: mReferenceables.load (reader, base, UniversalId::Type_Creature); break; - case ESM::REC_DOOR: mReferenceables.load (reader, base, UniversalId::Type_Door); break; - case ESM::REC_INGR: mReferenceables.load (reader, base, UniversalId::Type_Ingredient); break; - case ESM::REC_LEVC: - mReferenceables.load (reader, base, UniversalId::Type_CreatureLevelledList); break; - case ESM::REC_LEVI: - mReferenceables.load (reader, base, UniversalId::Type_ItemLevelledList); break; - case ESM::REC_LIGH: mReferenceables.load (reader, base, UniversalId::Type_Light); break; - case ESM::REC_LOCK: mReferenceables.load (reader, base, UniversalId::Type_Lockpick); break; - case ESM::REC_MISC: - mReferenceables.load (reader, base, UniversalId::Type_Miscellaneous); break; - case ESM::REC_NPC_: mReferenceables.load (reader, base, UniversalId::Type_Npc); break; - case ESM::REC_PROB: mReferenceables.load (reader, base, UniversalId::Type_Probe); break; - case ESM::REC_REPA: mReferenceables.load (reader, base, UniversalId::Type_Repair); break; - case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; - case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break; - - case ESM::REC_DIAL: - { - std::string id = reader.getHNOString ("NAME"); - - ESM::Dialogue record; - record.mId = id; - record.load (reader); - - if (record.mType==ESM::Dialogue::Journal) - { - mJournals.load (record, base); - dialogue = &mJournals.getRecord (id).get(); - } - else if (record.mType==ESM::Dialogue::Deleted) - { - dialogue = 0; // record vector can be shuffled around which would make pointer - // to record invalid - - if (mJournals.tryDelete (id)) - { - /// \todo handle info records - } - else if (mTopics.tryDelete (id)) - { - /// \todo handle info records - } - else - { - /// \todo report deletion of non-existing record - } - } - else - { - mTopics.load (record, base); - dialogue = &mTopics.getRecord (id).get(); - } - - break; - } - - case ESM::REC_INFO: - { - if (!dialogue) - { - /// \todo INFO record without matching DIAL record -> report to user - reader.skipRecord(); - break; - } - - if (dialogue->mType==ESM::Dialogue::Journal) - mJournalInfos.load (reader, base, *dialogue); - else - mTopicInfos.load (reader, base, *dialogue); - - break; - } - - case ESM::REC_FILT: - - if (project) - { - mFilters.load (reader, base); - mFilters.setData (mFilters.getSize()-1, - mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope), - static_cast (CSMFilter::Filter::Scope_Project)); - break; - } - - // fall through (filter record in a content file is an error with format 0) - - default: - - /// \todo throw an exception instead, once all records are implemented - /// or maybe report error and continue? - reader.skipRecord(); - } + delete mReader; + mReader = 0; + mDialogue = 0; + return true; } + + ESM::NAME n = mReader->getRecName(); + mReader->getRecHeader(); + + switch (n.val) + { + case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break; + case ESM::REC_GMST: mGmsts.load (*mReader, mBase); break; + case ESM::REC_SKIL: mSkills.load (*mReader, mBase); break; + case ESM::REC_CLAS: mClasses.load (*mReader, mBase); break; + case ESM::REC_FACT: mFactions.load (*mReader, mBase); break; + case ESM::REC_RACE: mRaces.load (*mReader, mBase); break; + case ESM::REC_SOUN: mSounds.load (*mReader, mBase); break; + case ESM::REC_SCPT: mScripts.load (*mReader, mBase); break; + case ESM::REC_REGN: mRegions.load (*mReader, mBase); break; + case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break; + case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break; + + case ESM::REC_CELL: + mCells.load (*mReader, mBase); + mRefs.load (*mReader, mCells.getSize()-1, mBase); + break; + + case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break; + case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break; + case ESM::REC_APPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Apparatus); break; + case ESM::REC_ARMO: mReferenceables.load (*mReader, mBase, UniversalId::Type_Armor); break; + case ESM::REC_BOOK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Book); break; + case ESM::REC_CLOT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Clothing); break; + case ESM::REC_CONT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Container); break; + case ESM::REC_CREA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Creature); break; + case ESM::REC_DOOR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Door); break; + case ESM::REC_INGR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Ingredient); break; + case ESM::REC_LEVC: + mReferenceables.load (*mReader, mBase, UniversalId::Type_CreatureLevelledList); break; + case ESM::REC_LEVI: + mReferenceables.load (*mReader, mBase, UniversalId::Type_ItemLevelledList); break; + case ESM::REC_LIGH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Light); break; + case ESM::REC_LOCK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Lockpick); break; + case ESM::REC_MISC: + mReferenceables.load (*mReader, mBase, UniversalId::Type_Miscellaneous); break; + case ESM::REC_NPC_: mReferenceables.load (*mReader, mBase, UniversalId::Type_Npc); break; + case ESM::REC_PROB: mReferenceables.load (*mReader, mBase, UniversalId::Type_Probe); break; + case ESM::REC_REPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Repair); break; + case ESM::REC_STAT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Static); break; + case ESM::REC_WEAP: mReferenceables.load (*mReader, mBase, UniversalId::Type_Weapon); break; + + case ESM::REC_DIAL: + { + std::string id = mReader->getHNOString ("NAME"); + + ESM::Dialogue record; + record.mId = id; + record.load (*mReader); + + if (record.mType==ESM::Dialogue::Journal) + { + mJournals.load (record, mBase); + mDialogue = &mJournals.getRecord (id).get(); + } + else if (record.mType==ESM::Dialogue::Deleted) + { + mDialogue = 0; // record vector can be shuffled around which would make pointer + // to record invalid + + if (mJournals.tryDelete (id)) + { + /// \todo handle info records + } + else if (mTopics.tryDelete (id)) + { + /// \todo handle info records + } + else + { + /// \todo report deletion of non-existing record + } + } + else + { + mTopics.load (record, mBase); + mDialogue = &mTopics.getRecord (id).get(); + } + + break; + } + + case ESM::REC_INFO: + { + if (!mDialogue) + { + /// \todo INFO record without matching DIAL record -> report to user + mReader->skipRecord(); + break; + } + + if (mDialogue->mType==ESM::Dialogue::Journal) + mJournalInfos.load (*mReader, mBase, *mDialogue); + else + mTopicInfos.load (*mReader, mBase, *mDialogue); + + break; + } + + case ESM::REC_FILT: + + if (mProject) + { + mFilters.load (*mReader, mBase); + mFilters.setData (mFilters.getSize()-1, + mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope), + static_cast (CSMFilter::Filter::Scope_Project)); + break; + } + + // fall through (filter record in a content file is an error with format 0) + + default: + + /// \todo throw an exception instead, once all records are implemented + /// or maybe report error and continue? + mReader->skipRecord(); + } + + return false; } bool CSMWorld::Data::hasId (const std::string& id) const diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 152c3ac41..234069e3a 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -33,12 +33,19 @@ class QAbstractItemModel; +namespace ESM +{ + class ESMReader; + struct Dialogue; +} + namespace CSMWorld { class Data : public QObject { Q_OBJECT + ToUTF8::Utf8Encoder mEncoder; IdCollection mGlobals; IdCollection mGmsts; IdCollection mSkills; @@ -62,6 +69,10 @@ namespace CSMWorld std::map mModelIndex; std::string mAuthor; std::string mDescription; + ESM::ESMReader *mReader; + const ESM::Dialogue *mDialogue; // last loaded dialogue + bool mBase; + bool mProject; // not implemented Data (const Data&); @@ -167,10 +178,15 @@ namespace CSMWorld void merge(); ///< Merge modified into base. - void loadFile (const boost::filesystem::path& path, bool base, bool project); - ///< Merging content of a file into base or modified. + int startLoading (const boost::filesystem::path& path, bool base, bool project); + ///< Begin merging content of a file into base or modified. /// /// \param project load project file instead of content file + /// + ///< \return estimated number of records + + bool continueLoading(); + ///< \return Finished? bool hasId (const std::string& id) const; From 6bc58692225073f47117577c0fd8a5f8f8ff1abb Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 3 May 2014 15:33:35 +0200 Subject: [PATCH 045/121] record loading progress bar --- apps/opencs/model/doc/documentmanager.cpp | 6 ++-- apps/opencs/model/doc/documentmanager.hpp | 4 ++- apps/opencs/model/doc/loader.cpp | 24 ++++++++----- apps/opencs/model/doc/loader.hpp | 7 +++- apps/opencs/view/doc/loader.cpp | 41 +++++++++++++++++++---- apps/opencs/view/doc/loader.hpp | 9 +++-- apps/opencs/view/doc/viewmanager.cpp | 8 +++-- 7 files changed, 77 insertions(+), 22 deletions(-) diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index f102dac70..f9e6bd96a 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -29,8 +29,10 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con this, SLOT (documentNotLoaded (Document *, const std::string&))); connect (this, SIGNAL (loadRequest (CSMDoc::Document *)), &mLoader, SLOT (loadDocument (CSMDoc::Document *))); - connect (&mLoader, SIGNAL (nextStage (CSMDoc::Document *, const std::string&)), - this, SIGNAL (nextStage (CSMDoc::Document *, const std::string&))); + connect (&mLoader, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)), + this, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int))); + connect (&mLoader, SIGNAL (nextRecord (CSMDoc::Document *)), + this, SIGNAL (nextRecord (CSMDoc::Document *))); } CSMDoc::DocumentManager::~DocumentManager() diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index be9528659..47118a0fb 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -72,7 +72,9 @@ namespace CSMDoc void loadingStopped (CSMDoc::Document *document, bool completed, const std::string& error); - void nextStage (CSMDoc::Document *document, const std::string& name); + void nextStage (CSMDoc::Document *document, const std::string& name, int steps); + + void nextRecord (CSMDoc::Document *document); }; } diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 85bfececd..e2cf6684f 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -42,12 +42,20 @@ void CSMDoc::Loader::load() bool done = false; + const int batchingSize = 100; + try { if (iter->second.mRecordsLeft) { - if (document->getData().continueLoading()) - iter->second.mRecordsLeft = false; + for (int i=0; igetData().continueLoading()) + { + iter->second.mRecordsLeft = false; + break; + } + + emit nextRecord (document); return; } @@ -56,17 +64,17 @@ void CSMDoc::Loader::load() { boost::filesystem::path path = document->getContentFiles()[iter->second.mFile]; - emit nextStage (document, path.filename().string()); - - document->getData().startLoading (path, iter->second.mFilegetData().startLoading (path, iter->second.mFilesecond.mRecordsLeft = true; + + emit nextStage (document, path.filename().string(), steps/batchingSize); } else if (iter->second.mFile==size) { - emit nextStage (document, "Project File"); - - document->getData().startLoading (document->getProjectPath(), false, true); + int steps = document->getData().startLoading (document->getProjectPath(), false, true); iter->second.mRecordsLeft = true; + + emit nextStage (document, "Project File", steps/batchingSize); } else { diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index 5e86e4e67..f6cfd2a0b 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -56,7 +56,12 @@ namespace CSMDoc ///< Document load has been interrupted either because of a call to abortLoading /// or a problem during loading). In the former case error will be an empty string. - void nextStage (CSMDoc::Document *document, const std::string& name); + void nextStage (CSMDoc::Document *document, const std::string& name, int steps); + + void nextRecord (CSMDoc::Document *document); + ///< \note This signal is only given once per group of records. The group size is + /// approximately the total number of records divided by the steps value of the + /// previous nextStage signal. }; } diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 50c29eedb..418dc5638 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -14,6 +14,11 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) QVBoxLayout *layout = new QVBoxLayout (this); + // file progress + mFile = new QLabel (this); + + layout->addWidget (mFile); + mFileProgress = new QProgressBar (this); layout->addWidget (mFileProgress); @@ -27,9 +32,16 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) mFileProgress->setTextVisible (true); mFileProgress->setValue (0); - mFile = new QLabel (this); + // record progress + layout->addWidget (new QLabel ("Records", this)); - layout->addWidget (mFile); + mRecordProgress = new QProgressBar (this); + + layout->addWidget (mRecordProgress); + + mRecordProgress->setMinimum (0); + mRecordProgress->setTextVisible (true); + mRecordProgress->setValue (0); setLayout (layout); @@ -38,19 +50,28 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) show(); } -void CSVDoc::LoadingDocument::nextStage (const std::string& name) +void CSVDoc::LoadingDocument::nextStage (const std::string& name, int steps) { mFile->setText (QString::fromUtf8 (("Loading: " + name).c_str())); mFileProgress->setValue (mFileProgress->value()+1); + + mRecordProgress->setValue (0); + mRecordProgress->setMaximum (steps); } -CSVDoc::Loader::Loader() +void CSVDoc::LoadingDocument::nextRecord() { + int value = mRecordProgress->value()+1; + if (value<=mRecordProgress->maximum()) + mRecordProgress->setValue (value); } + +CSVDoc::Loader::Loader() {} + CSVDoc::Loader::~Loader() { for (std::map::iterator iter (mDocuments.begin()); @@ -79,10 +100,18 @@ void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed, } } -void CSVDoc::Loader::nextStage (CSMDoc::Document *document, const std::string& name) +void CSVDoc::Loader::nextStage (CSMDoc::Document *document, const std::string& name, int steps) { std::map::iterator iter = mDocuments.find (document); if (iter!=mDocuments.end()) - iter->second->nextStage (name); + iter->second->nextStage (name, steps); +} + +void CSVDoc::Loader::nextRecord (CSMDoc::Document *document) +{ + std::map::iterator iter = mDocuments.find (document); + + if (iter!=mDocuments.end()) + iter->second->nextRecord(); } \ No newline at end of file diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index ad1e3ffb8..0c85223c6 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -22,12 +22,15 @@ namespace CSVDoc QLabel *mFile; QProgressBar *mFileProgress; + QProgressBar *mRecordProgress; public: LoadingDocument (CSMDoc::Document *document); - void nextStage (const std::string& name); + void nextStage (const std::string& name, int steps); + + void nextRecord(); }; class Loader : public QObject @@ -49,7 +52,9 @@ namespace CSVDoc void loadingStopped (CSMDoc::Document *document, bool completed, const std::string& error); - void nextStage (CSMDoc::Document *document, const std::string& name); + void nextStage (CSMDoc::Document *document, const std::string& name, int steps); + + void nextRecord (CSMDoc::Document *document); }; } diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index c7d9ed470..1c5f51129 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -93,8 +93,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) &mLoader, SLOT (loadingStopped (CSMDoc::Document *, bool, const std::string&))); connect ( - &mDocumentManager, SIGNAL (nextStage (CSMDoc::Document *, const std::string&)), - &mLoader, SLOT (nextStage (CSMDoc::Document *, const std::string&))); + &mDocumentManager, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)), + &mLoader, SLOT (nextStage (CSMDoc::Document *, const std::string&, int))); + + connect ( + &mDocumentManager, SIGNAL (nextRecord (CSMDoc::Document *)), + &mLoader, SLOT (nextRecord (CSMDoc::Document *))); } CSVDoc::ViewManager::~ViewManager() From eff648e3ab2509f12f5fe8c0be1aeee6d37c4af1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 3 May 2014 16:16:27 +0200 Subject: [PATCH 046/121] Show unhandled SDL events in hexadecimal (easier to compare with the enum) --- extern/sdl4ogre/sdlinputwrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 09a244177..82db5ea99 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -115,7 +115,7 @@ namespace SFO mWindowListener->windowClosed(); break; default: - std::cerr << "Unhandled SDL event of type " << evt.type << std::endl; + std::cerr << "Unhandled SDL event of type 0x" << std::hex << evt.type << std::endl; break; } } From 3fdd72f2040d5a1c8515bb8ed1033c5be4f0eeb4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 3 May 2014 16:44:50 +0200 Subject: [PATCH 047/121] added cancel button to loading window --- apps/opencs/model/doc/documentmanager.cpp | 2 ++ apps/opencs/model/doc/documentmanager.hpp | 2 ++ apps/opencs/model/doc/loader.cpp | 4 ++-- apps/opencs/model/doc/loader.hpp | 2 +- apps/opencs/view/doc/loader.cpp | 20 +++++++++++++++++++- apps/opencs/view/doc/loader.hpp | 14 ++++++++++++++ apps/opencs/view/doc/viewmanager.cpp | 4 ++++ 7 files changed, 44 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index f9e6bd96a..d44da15c5 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -33,6 +33,8 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con this, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int))); connect (&mLoader, SIGNAL (nextRecord (CSMDoc::Document *)), this, SIGNAL (nextRecord (CSMDoc::Document *))); + connect (this, SIGNAL (cancelLoading (CSMDoc::Document *)), + &mLoader, SLOT (abortLoading (CSMDoc::Document *))); } CSMDoc::DocumentManager::~DocumentManager() diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 47118a0fb..d834d85d4 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -75,6 +75,8 @@ namespace CSMDoc void nextStage (CSMDoc::Document *document, const std::string& name, int steps); void nextRecord (CSMDoc::Document *document); + + void cancelLoading (CSMDoc::Document *document); }; } diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index e2cf6684f..2ef808dd6 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -102,7 +102,7 @@ void CSMDoc::Loader::loadDocument (CSMDoc::Document *document) mDocuments.push_back (std::make_pair (document, Stage())); } -void CSMDoc::Loader::abortLoading (Document *document) +void CSMDoc::Loader::abortLoading (CSMDoc::Document *document) { for (std::vector >::iterator iter = mDocuments.begin(); iter!=mDocuments.end(); ++iter) @@ -114,4 +114,4 @@ void CSMDoc::Loader::abortLoading (Document *document) break; } } -} \ No newline at end of file +} diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index f6cfd2a0b..a6bcb6b87 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -42,7 +42,7 @@ namespace CSMDoc void loadDocument (CSMDoc::Document *document); ///< The ownership of \a document is not transferred. - void abortLoading (Document *document); + void abortLoading (CSMDoc::Document *document); ///< Abort loading \a docuemnt (ignored if \a document has already finished being /// loaded). Will result in a documentNotLoaded signal, once the Loader has finished /// cleaning up. diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 418dc5638..a9206ef2b 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -5,10 +5,12 @@ #include #include #include +#include #include "../../model/doc/document.hpp" CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) +: mDocument (document) { setWindowTitle (("Opening " + document->getSavePath().filename().string()).c_str()); @@ -43,11 +45,18 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) mRecordProgress->setTextVisible (true); mRecordProgress->setValue (0); + QDialogButtonBox *buttonBox = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, + this); + + layout->addWidget (buttonBox); + setLayout (layout); move (QCursor::pos()); show(); + + connect (buttonBox, SIGNAL (rejected()), this, SLOT (cancel())); } void CSVDoc::LoadingDocument::nextStage (const std::string& name, int steps) @@ -69,6 +78,11 @@ void CSVDoc::LoadingDocument::nextRecord() mRecordProgress->setValue (value); } +void CSVDoc::LoadingDocument::cancel() +{ + emit cancel (mDocument); +} + CSVDoc::Loader::Loader() {} @@ -81,7 +95,11 @@ CSVDoc::Loader::~Loader() void CSVDoc::Loader::add (CSMDoc::Document *document) { - mDocuments.insert (std::make_pair (document, new LoadingDocument (document))); + LoadingDocument *loading = new LoadingDocument (document); + mDocuments.insert (std::make_pair (document, loading)); + + connect (loading, SIGNAL (cancel (CSMDoc::Document *)), + this, SIGNAL (cancel (CSMDoc::Document *))); } void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed, diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index 0c85223c6..a251e75d9 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -5,6 +5,7 @@ #include #include +#include class QLabel; class QProgressBar; @@ -20,6 +21,7 @@ namespace CSVDoc { Q_OBJECT + CSMDoc::Document *mDocument; QLabel *mFile; QProgressBar *mFileProgress; QProgressBar *mRecordProgress; @@ -31,6 +33,14 @@ namespace CSVDoc void nextStage (const std::string& name, int steps); void nextRecord(); + + private slots: + + void cancel(); + + signals: + + void cancel (CSMDoc::Document *document); }; class Loader : public QObject @@ -45,6 +55,10 @@ namespace CSVDoc virtual ~Loader(); + signals: + + void cancel (CSMDoc::Document *document); + public slots: void add (CSMDoc::Document *document); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 1c5f51129..b8971a296 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -99,6 +99,10 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) connect ( &mDocumentManager, SIGNAL (nextRecord (CSMDoc::Document *)), &mLoader, SLOT (nextRecord (CSMDoc::Document *))); + + connect ( + &mLoader, SIGNAL (cancel (CSMDoc::Document *)), + &mDocumentManager, SIGNAL (cancelLoading (CSMDoc::Document *))); } CSVDoc::ViewManager::~ViewManager() From e9c2f24faaf2838507b52462fa8204020145b946 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 3 May 2014 17:14:17 +0200 Subject: [PATCH 048/121] intercept close button clicks in loading window --- apps/opencs/view/doc/loader.cpp | 7 +++++++ apps/opencs/view/doc/loader.hpp | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index a9206ef2b..3b5890479 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -6,9 +6,16 @@ #include #include #include +#include #include "../../model/doc/document.hpp" +void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) +{ + event->ignore(); + emit cancel (mDocument); +} + CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) : mDocument (document) { diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index a251e75d9..d1c740011 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -26,6 +26,10 @@ namespace CSVDoc QProgressBar *mFileProgress; QProgressBar *mRecordProgress; + private: + + void closeEvent (QCloseEvent *event); + public: LoadingDocument (CSMDoc::Document *document); From 658c37a29999a55b9d574160066384c54509aed9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 3 May 2014 17:14:59 +0200 Subject: [PATCH 049/121] AiPursue: If we reached the path end, that does not mean we reached the target. Rebuild the path if the target has moved in the meantime. Fixes guards in pursuit activating the dialogue too early. Also tweaked the activation distance. --- apps/openmw/mwmechanics/aipursue.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwmechanics/aipursue.cpp b/apps/openmw/mwmechanics/aipursue.cpp index 8da5c640e..0c10bd81d 100644 --- a/apps/openmw/mwmechanics/aipursue.cpp +++ b/apps/openmw/mwmechanics/aipursue.cpp @@ -52,11 +52,13 @@ bool MWMechanics::AiPursue::execute (const MWWorld::Ptr& actor, float duration) } } + // Big TODO: Sync this with current AiFollow. Move common code to a shared base class or helpers (applies to all AI packages, way too much duplicated code) + MWWorld::Ptr target = world->getPtr(mObjectId,false); ESM::Position targetPos = target.getRefData().getPosition(); bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY; - if(!mPathFinder.isPathConstructed() || cellChange) + if(!mPathFinder.isPathConstructed() || cellChange || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) { mCellX = cell->mData.mX; mCellY = cell->mData.mY; @@ -76,15 +78,7 @@ bool MWMechanics::AiPursue::execute (const MWWorld::Ptr& actor, float duration) if((pos.pos[0]-targetPos.pos[0])*(pos.pos[0]-targetPos.pos[0])+ (pos.pos[1]-targetPos.pos[1])*(pos.pos[1]-targetPos.pos[1])+ - (pos.pos[2]-targetPos.pos[2])*(pos.pos[2]-targetPos.pos[2]) < 200*200) - { - movement.mPosition[1] = 0; - MWWorld::Ptr target = world->getPtr(mObjectId,false); - MWWorld::Class::get(target).activate(target,actor).get()->execute(actor); - return true; - } - - if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) + (pos.pos[2]-targetPos.pos[2])*(pos.pos[2]-targetPos.pos[2]) < 100*100) { movement.mPosition[1] = 0; MWWorld::Ptr target = world->getPtr(mObjectId,false); From 05e326bdc38166e5e9a4de38310fd7cb230f89f9 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sat, 3 May 2014 12:48:07 -0400 Subject: [PATCH 050/121] Added update sneak to actors Intends to check the state of a players sneak by asking the question if each npc can see the player. --- apps/openmw/mwmechanics/actors.cpp | 23 +++++++++++++++++++++++ apps/openmw/mwmechanics/actors.hpp | 2 ++ apps/openmw/mwworld/player.cpp | 5 ----- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 804ec7a41..f51593088 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -236,6 +236,7 @@ namespace MWMechanics updateDrowning(ptr, duration); calculateNpcStatModifiers(ptr); updateEquippedLight(ptr, duration); + updateSneak(ptr); } } @@ -720,6 +721,28 @@ namespace MWMechanics } } + void Actors::updateSneak (const MWWorld::Ptr& ptr) + { + const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + if (player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak)) + { + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); + int radius = esmStore.get().find("fSneakUseDist")->getInt(); + + // am I close enough to the player? + if (Ogre::Vector3(ptr.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) + <= radius * radius ) + { + bool seen = false; // unseen + if ( !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr) + && !MWBase::Environment::get().getWorld()->getLOS(player, ptr) ) + seen = true; // seen + + MWBase::Environment::get().getWindowManager()->setSneakVisibility(seen); + } + } + } + void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration) { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index f7dff1058..ddd7a47d3 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -44,6 +44,8 @@ namespace MWMechanics void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration); + void updateSneak (const MWWorld::Ptr& ptr); + public: Actors(); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index d023d4388..c0f88249c 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -100,7 +100,6 @@ namespace MWWorld void Player::setLeftRight (int value) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[0] = value; } @@ -119,7 +118,6 @@ namespace MWWorld void Player::setUpDown(int value) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[2] = value; } @@ -132,7 +130,6 @@ namespace MWWorld void Player::setSneak(bool sneak) { MWWorld::Ptr ptr = getPlayer(); - ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak); if (sneak) @@ -157,8 +154,6 @@ namespace MWWorld if (neighbors.empty()) MWBase::Environment::get().getWindowManager()->setSneakVisibility(true); } - else - MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); } void Player::yaw(float yaw) From e1e23447f2b2306cf0f1c57fba2f2b6d35954786 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sat, 3 May 2014 13:16:07 -0400 Subject: [PATCH 051/121] Removed initial check form setSneak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It wasn’t needed. --- apps/openmw/mwmechanics/actors.cpp | 20 +++++++++----------- apps/openmw/mwworld/player.cpp | 24 ++---------------------- 2 files changed, 11 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index f51593088..71ccf7ff2 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -728,18 +728,16 @@ namespace MWMechanics { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); int radius = esmStore.get().find("fSneakUseDist")->getInt(); - - // am I close enough to the player? - if (Ogre::Vector3(ptr.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) - <= radius * radius ) - { - bool seen = false; // unseen - if ( !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr) - && !MWBase::Environment::get().getWorld()->getLOS(player, ptr) ) - seen = true; // seen + bool seen = false; - MWBase::Environment::get().getWindowManager()->setSneakVisibility(seen); - } + // am I close enough and can I see the player? + if ( (Ogre::Vector3(ptr.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) <= radius*radius) + && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr) + && MWBase::Environment::get().getWorld()->getLOS(player, ptr)) + + seen = true; + + MWBase::Environment::get().getWindowManager()->setSneakVisibility(seen); } } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index c0f88249c..d581a86c0 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -132,28 +132,8 @@ namespace MWWorld MWWorld::Ptr ptr = getPlayer(); ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak); - if (sneak) - { - const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - - // Find all the actors who might be able to see the player - std::vector neighbors; - MWBase::Environment::get().getMechanicsManager()->getActorsInRange( Ogre::Vector3(ptr.getRefData().getPosition().pos), - esmStore.get().find("fSneakUseDist")->getInt(), neighbors); - for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) - { - if (*it == ptr) // not the player - continue; - - if ( MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, *it) ) - { - MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); - break; - } - } - if (neighbors.empty()) - MWBase::Environment::get().getWindowManager()->setSneakVisibility(true); - } + if(!sneak) + MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); } void Player::yaw(float yaw) From 00b21449a2f26262e54bfb55af3b855b976af22e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 3 May 2014 19:47:13 +0200 Subject: [PATCH 052/121] replaced type_cell with type_scene --- apps/opencs/view/world/scenesubview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index d411985b3..34008c9a8 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -142,7 +142,7 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection) { - setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Cell, "sys::default")); + setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Scene, "sys::default")); int size = selection.getSize(); std::ostringstream stream; From 320411f5b30d854f247fde0238df7c8e7494d02b Mon Sep 17 00:00:00 2001 From: Thoronador Date: Sat, 3 May 2014 21:05:45 +0200 Subject: [PATCH 053/121] remove unused CMake files for Audiere, MPG123 and Sndfile --- cmake/FindAudiere.cmake | 60 ----------------------------------------- cmake/FindMPG123.cmake | 47 -------------------------------- cmake/FindSNDFILE.cmake | 41 ---------------------------- 3 files changed, 148 deletions(-) delete mode 100644 cmake/FindAudiere.cmake delete mode 100644 cmake/FindMPG123.cmake delete mode 100644 cmake/FindSNDFILE.cmake diff --git a/cmake/FindAudiere.cmake b/cmake/FindAudiere.cmake deleted file mode 100644 index 79427309c..000000000 --- a/cmake/FindAudiere.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# Locate Audiere -# This module defines -# AUDIERE_LIBRARY -# AUDIERE_FOUND, if false, do not try to link to Audiere -# AUDIERE_INCLUDE_DIR, where to find the headers -# -# Created by Nicolay Korslund for OpenMW (http://openmw.com) -# -# More or less a direct ripoff of FindOpenAL.cmake by Eric Wing. - -#============================================================================= -# Copyright 2005-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - - -FIND_PATH(AUDIERE_INCLUDE_DIR audiere.h - HINTS - PATH_SUFFIXES include - PATHS - $ENV{AUDIERE_DIR} - ~/Library/Frameworks - /Library/Frameworks - /usr/local - /usr - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt -) - -FIND_LIBRARY(AUDIERE_LIBRARY - NAMES audiere - HINTS - PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64 - PATHS - $ENV{AUDIERE_DIR} - ~/Library/Frameworks - /Library/Frameworks - /usr/local - /usr - /sw - /opt/local - /opt/csw - /opt -) - -SET(AUDIERE_FOUND "NO") -IF(AUDIERE_LIBRARY AND AUDIERE_INCLUDE_DIR) - SET(AUDIERE_FOUND "YES") -ENDIF(AUDIERE_LIBRARY AND AUDIERE_INCLUDE_DIR) - diff --git a/cmake/FindMPG123.cmake b/cmake/FindMPG123.cmake deleted file mode 100644 index 51e562c91..000000000 --- a/cmake/FindMPG123.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Locate MPG123 -# This module defines -# MPG123_LIBRARY -# MPG123_FOUND, if false, do not try to link to Mpg123 -# MPG123_INCLUDE_DIR, where to find the headers -# -# Created by Nicolay Korslund for OpenMW (http://openmw.com) -# -# Ripped off from other sources. In fact, this file is so generic (I -# just did a search and replace on another file) that I wonder why the -# CMake guys haven't wrapped this entire thing in a single -# function. Do we really need to repeat this stuff for every single -# library when they all work the same? - -FIND_PATH(MPG123_INCLUDE_DIR mpg123.h - HINTS - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local - /usr - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt -) - -FIND_LIBRARY(MPG123_LIBRARY - NAMES mpg123 - HINTS - PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64 - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local - /usr - /sw - /opt/local - /opt/csw - /opt -) - -SET(MPG123_FOUND "NO") -IF(MPG123_LIBRARY AND MPG123_INCLUDE_DIR) - SET(MPG123_FOUND "YES") -ENDIF(MPG123_LIBRARY AND MPG123_INCLUDE_DIR) - diff --git a/cmake/FindSNDFILE.cmake b/cmake/FindSNDFILE.cmake deleted file mode 100644 index 5c7664b50..000000000 --- a/cmake/FindSNDFILE.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# Locate SNDFILE -# This module defines -# SNDFILE_LIBRARY -# SNDFILE_FOUND, if false, do not try to link to Sndfile -# SNDFILE_INCLUDE_DIR, where to find the headers -# -# Created by Nicolay Korslund for OpenMW (http://openmw.com) - -FIND_PATH(SNDFILE_INCLUDE_DIR sndfile.h - HINTS - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local - /usr - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt -) - -FIND_LIBRARY(SNDFILE_LIBRARY - NAMES sndfile - HINTS - PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64 - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local - /usr - /sw - /opt/local - /opt/csw - /opt -) - -SET(SNDFILE_FOUND "NO") -IF(SNDFILE_LIBRARY AND SNDFILE_INCLUDE_DIR) - SET(SNDFILE_FOUND "YES") -ENDIF(SNDFILE_LIBRARY AND SNDFILE_INCLUDE_DIR) - From 688d5565107da4d03a4f04599360b3174dc723c5 Mon Sep 17 00:00:00 2001 From: Thoronador Date: Sat, 3 May 2014 21:20:22 +0200 Subject: [PATCH 054/121] remove references to Audiere and MPG123 from top-level CMake file --- CMakeLists.txt | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd45a207c..27007f161 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,8 +86,6 @@ option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest ang GMock fram # Sound source selection option(USE_FFMPEG "use ffmpeg for sound" ON) -option(USE_AUDIERE "use audiere for sound" ON) -option(USE_MPG123 "use mpg123 + libsndfile for sound" ON) # OS X deployment option(OPENMW_OSX_DEPLOYMENT OFF) @@ -171,27 +169,6 @@ if (USE_FFMPEG) endif (FFMPEG_FOUND) endif (USE_FFMPEG) -if (USE_AUDIERE AND NOT GOT_SOUND_INPUT) - find_package(Audiere) - if (AUDIERE_FOUND) - set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${AUDIERE_INCLUDE_DIR}) - set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${AUDIERE_LIBRARY}) - set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_AUDIERE) - set(GOT_SOUND_INPUT 1) - endif (AUDIERE_FOUND) -endif (USE_AUDIERE AND NOT GOT_SOUND_INPUT) - -if (USE_MPG123 AND NOT GOT_SOUND_INPUT) - find_package(MPG123 REQUIRED) - find_package(SNDFILE REQUIRED) - if (MPG123_FOUND AND SNDFILE_FOUND) - set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${MPG123_INCLUDE_DIR} ${SNDFILE_INCLUDE_DIR}) - set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${MPG123_LIBRARY} ${SNDFILE_LIBRARY}) - set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_MPG123) - set(GOT_SOUND_INPUT 1) - endif (MPG123_FOUND AND SNDFILE_FOUND) -endif (USE_MPG123 AND NOT GOT_SOUND_INPUT) - if (NOT GOT_SOUND_INPUT) message(WARNING "--------------------") message(WARNING "Failed to find any sound input packages") From 620a8ccaf3f78b28193c215e9f80365dae4cf785 Mon Sep 17 00:00:00 2001 From: Thoronador Date: Sat, 3 May 2014 21:49:57 +0200 Subject: [PATCH 055/121] remove Audiere and MPG123+Sndfile decoder sources --- apps/openmw/mwsound/audiere_decoder.cpp | 137 ------------- apps/openmw/mwsound/audiere_decoder.hpp | 46 ----- apps/openmw/mwsound/mpgsnd_decoder.cpp | 247 ------------------------ apps/openmw/mwsound/mpgsnd_decoder.hpp | 59 ------ apps/openmw/mwsound/soundmanagerimp.cpp | 18 +- 5 files changed, 2 insertions(+), 505 deletions(-) delete mode 100644 apps/openmw/mwsound/audiere_decoder.cpp delete mode 100644 apps/openmw/mwsound/audiere_decoder.hpp delete mode 100644 apps/openmw/mwsound/mpgsnd_decoder.cpp delete mode 100644 apps/openmw/mwsound/mpgsnd_decoder.hpp diff --git a/apps/openmw/mwsound/audiere_decoder.cpp b/apps/openmw/mwsound/audiere_decoder.cpp deleted file mode 100644 index 3f3e3a62d..000000000 --- a/apps/openmw/mwsound/audiere_decoder.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#ifdef OPENMW_USE_AUDIERE - -#include -#include - -#include "audiere_decoder.hpp" - - -static void fail(const std::string &msg) -{ throw std::runtime_error("Audiere exception: "+msg); } - -namespace MWSound -{ - -class OgreFile : public audiere::File -{ - Ogre::DataStreamPtr mStream; - - ADR_METHOD(int) read(void* buffer, int size) - { - return mStream->read(buffer, size); - } - - ADR_METHOD(bool) seek(int position, SeekMode mode) - { - if(mode == CURRENT) - mStream->seek(mStream->tell()+position); - else if(mode == BEGIN) - mStream->seek(position); - else if(mode == END) - mStream->seek(mStream->size()+position); - else - return false; - - return true; - } - - ADR_METHOD(int) tell() - { - return mStream->tell(); - } - - size_t refs; - ADR_METHOD(void) ref() { ++refs; } - ADR_METHOD(void) unref() - { - if(--refs == 0) - delete this; - } - -public: - OgreFile(const Ogre::DataStreamPtr &stream) - : mStream(stream), refs(1) - { } - virtual ~OgreFile() { } - - Ogre::String getName() - { return mStream->getName(); } -}; - - -void Audiere_Decoder::open(const std::string &fname) -{ - close(); - - mSoundFile = audiere::FilePtr(new OgreFile(mResourceMgr.openResource(fname))); - mSoundSource = audiere::OpenSampleSource(mSoundFile); - mSoundFileName = fname; - - int channels, srate; - audiere::SampleFormat format; - - mSoundSource->getFormat(channels, srate, format); - if(format == audiere::SF_S16) - mSampleType = SampleType_Int16; - else if(format == audiere::SF_U8) - mSampleType = SampleType_UInt8; - else - fail("Unsupported sample type"); - - if(channels == 1) - mChannelConfig = ChannelConfig_Mono; - else if(channels == 2) - mChannelConfig = ChannelConfig_Stereo; - else - fail("Unsupported channel count"); - - mSampleRate = srate; -} - -void Audiere_Decoder::close() -{ - mSoundFile = NULL; - mSoundSource = NULL; -} - -std::string Audiere_Decoder::getName() -{ - return mSoundFileName; -} - -void Audiere_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) -{ - *samplerate = mSampleRate; - *chans = mChannelConfig; - *type = mSampleType; -} - -size_t Audiere_Decoder::read(char *buffer, size_t bytes) -{ - int size = bytesToFrames(bytes, mChannelConfig, mSampleType); - size = mSoundSource->read(size, buffer); - return framesToBytes(size, mChannelConfig, mSampleType); -} - -void Audiere_Decoder::rewind() -{ - mSoundSource->reset(); -} - -size_t Audiere_Decoder::getSampleOffset() -{ - return 0; -} - -Audiere_Decoder::Audiere_Decoder() -{ -} - -Audiere_Decoder::~Audiere_Decoder() -{ - close(); -} - -} - -#endif diff --git a/apps/openmw/mwsound/audiere_decoder.hpp b/apps/openmw/mwsound/audiere_decoder.hpp deleted file mode 100644 index f432c32ec..000000000 --- a/apps/openmw/mwsound/audiere_decoder.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef GAME_SOUND_AUDIERE_DECODER_H -#define GAME_SOUND_AUDIERE_DECODER_H - -#include - -#include "audiere.h" - -#include "sound_decoder.hpp" - - -namespace MWSound -{ - class Audiere_Decoder : public Sound_Decoder - { - std::string mSoundFileName; - audiere::FilePtr mSoundFile; - audiere::SampleSourcePtr mSoundSource; - int mSampleRate; - SampleType mSampleType; - ChannelConfig mChannelConfig; - - virtual void open(const std::string &fname); - virtual void close(); - - virtual std::string getName(); - virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type); - - virtual size_t read(char *buffer, size_t bytes); - virtual void rewind(); - virtual size_t getSampleOffset(); - - Audiere_Decoder& operator=(const Audiere_Decoder &rhs); - Audiere_Decoder(const Audiere_Decoder &rhs); - - Audiere_Decoder(); - public: - virtual ~Audiere_Decoder(); - - friend class SoundManager; - }; -#ifndef DEFAULT_DECODER -#define DEFAULT_DECODER (::MWSound::Audiere_Decoder) -#endif -}; - -#endif diff --git a/apps/openmw/mwsound/mpgsnd_decoder.cpp b/apps/openmw/mwsound/mpgsnd_decoder.cpp deleted file mode 100644 index fb187f844..000000000 --- a/apps/openmw/mwsound/mpgsnd_decoder.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#ifdef OPENMW_USE_MPG123 - -#include -#include - -#include "mpgsnd_decoder.hpp" - - -static void fail(const std::string &msg) -{ throw std::runtime_error("MpgSnd exception: "+msg); } - -namespace MWSound -{ - -// -// libSndFile io callbacks -// -sf_count_t MpgSnd_Decoder::ogresf_get_filelen(void *user_data) -{ - Ogre::DataStreamPtr stream = static_cast(user_data)->mDataStream; - return stream->size(); -} - -sf_count_t MpgSnd_Decoder::ogresf_seek(sf_count_t offset, int whence, void *user_data) -{ - Ogre::DataStreamPtr stream = static_cast(user_data)->mDataStream; - - if(whence == SEEK_CUR) - stream->seek(stream->tell()+offset); - else if(whence == SEEK_SET) - stream->seek(offset); - else if(whence == SEEK_END) - stream->seek(stream->size()+offset); - else - return -1; - - return stream->tell(); -} - -sf_count_t MpgSnd_Decoder::ogresf_read(void *ptr, sf_count_t count, void *user_data) -{ - Ogre::DataStreamPtr stream = static_cast(user_data)->mDataStream; - return stream->read(ptr, count); -} - -sf_count_t MpgSnd_Decoder::ogresf_write(const void*, sf_count_t, void*) -{ return -1; } - -sf_count_t MpgSnd_Decoder::ogresf_tell(void *user_data) -{ - Ogre::DataStreamPtr stream = static_cast(user_data)->mDataStream; - return stream->tell(); -} - -// -// libmpg13 io callbacks -// -ssize_t MpgSnd_Decoder::ogrempg_read(void *user_data, void *ptr, size_t count) -{ - Ogre::DataStreamPtr stream = static_cast(user_data)->mDataStream; - return stream->read(ptr, count); -} - -off_t MpgSnd_Decoder::ogrempg_lseek(void *user_data, off_t offset, int whence) -{ - Ogre::DataStreamPtr stream = static_cast(user_data)->mDataStream; - - if(whence == SEEK_CUR) - stream->seek(stream->tell()+offset); - else if(whence == SEEK_SET) - stream->seek(offset); - else if(whence == SEEK_END) - stream->seek(stream->size()+offset); - else - return -1; - - return stream->tell(); -} - - -void MpgSnd_Decoder::open(const std::string &fname) -{ - close(); - mDataStream = mResourceMgr.openResource(fname); - - SF_VIRTUAL_IO streamIO = { - ogresf_get_filelen, ogresf_seek, - ogresf_read, ogresf_write, ogresf_tell - }; - mSndFile = sf_open_virtual(&streamIO, SFM_READ, &mSndInfo, this); - if(mSndFile) - { - if(mSndInfo.channels == 1) - mChanConfig = ChannelConfig_Mono; - else if(mSndInfo.channels == 2) - mChanConfig = ChannelConfig_Stereo; - else - { - sf_close(mSndFile); - mSndFile = NULL; - fail("Unsupported channel count in "+fname); - } - mSampleRate = mSndInfo.samplerate; - return; - } - mDataStream->seek(0); - - mMpgFile = mpg123_new(NULL, NULL); - if(mMpgFile && mpg123_replace_reader_handle(mMpgFile, ogrempg_read, ogrempg_lseek, NULL) == MPG123_OK && - mpg123_open_handle(mMpgFile, this) == MPG123_OK) - { - try - { - int encoding, channels; - long rate; - if(mpg123_getformat(mMpgFile, &rate, &channels, &encoding) != MPG123_OK) - fail("Failed to get audio format"); - if(encoding != MPG123_ENC_SIGNED_16) - fail("Unsupported encoding in "+fname); - if(channels != 1 && channels != 2) - fail("Unsupported channel count in "+fname); - mChanConfig = ((channels==2)?ChannelConfig_Stereo:ChannelConfig_Mono); - mSampleRate = rate; - return; - } - catch(std::exception &e) - { - mpg123_close(mMpgFile); - mpg123_delete(mMpgFile); - mMpgFile = NULL; - throw; - } - mpg123_close(mMpgFile); - } - if(mMpgFile) - mpg123_delete(mMpgFile); - mMpgFile = NULL; - - fail("Unsupported file type: "+fname); -} - -void MpgSnd_Decoder::close() -{ - if(mSndFile) - sf_close(mSndFile); - mSndFile = NULL; - - if(mMpgFile) - { - mpg123_close(mMpgFile); - mpg123_delete(mMpgFile); - mMpgFile = NULL; - } - - mDataStream.setNull(); -} - -std::string MpgSnd_Decoder::getName() -{ - return mDataStream->getName(); -} - -void MpgSnd_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) -{ - if(!mSndFile && !mMpgFile) - fail("No open file"); - - *samplerate = mSampleRate; - *chans = mChanConfig; - *type = SampleType_Int16; -} - -size_t MpgSnd_Decoder::read(char *buffer, size_t bytes) -{ - size_t got = 0; - - if(mSndFile) - { - got = sf_read_short(mSndFile, (short*)buffer, bytes/2)*2; - } - else if(mMpgFile) - { - int err; - err = mpg123_read(mMpgFile, (unsigned char*)buffer, bytes, &got); - if(err != MPG123_OK && err != MPG123_DONE) - fail("Failed to read from file"); - } - return got; -} - -void MpgSnd_Decoder::readAll(std::vector &output) -{ - if(mSndFile && mSndInfo.frames > 0) - { - size_t pos = output.size(); - output.resize(pos + mSndInfo.frames*mSndInfo.channels*2); - sf_readf_short(mSndFile, (short*)(&output[0]+pos), mSndInfo.frames); - return; - } - // Fallback in case we don't know the total already - Sound_Decoder::readAll(output); -} - -void MpgSnd_Decoder::rewind() -{ - if(!mSndFile && !mMpgFile) - fail("No open file"); - - if(mSndFile) - { - if(sf_seek(mSndFile, 0, SEEK_SET) == -1) - fail("seek failed"); - } - else if(mMpgFile) - { - if(mpg123_seek(mMpgFile, 0, SEEK_SET) < 0) - fail("seek failed"); - } -} - -size_t MpgSnd_Decoder::getSampleOffset() -{ - return 0; -} - -MpgSnd_Decoder::MpgSnd_Decoder() - : mSndInfo() - , mSndFile(NULL) - , mMpgFile(NULL) - , mDataStream() - , mChanConfig(ChannelConfig_Stereo) - , mSampleRate(0) -{ - static bool initdone = false; - if(!initdone) - mpg123_init(); - initdone = true; -} - -MpgSnd_Decoder::~MpgSnd_Decoder() -{ - close(); -} - -} - -#endif diff --git a/apps/openmw/mwsound/mpgsnd_decoder.hpp b/apps/openmw/mwsound/mpgsnd_decoder.hpp deleted file mode 100644 index be52f6f49..000000000 --- a/apps/openmw/mwsound/mpgsnd_decoder.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef GAME_SOUND_MPGSND_DECODER_H -#define GAME_SOUND_MPGSND_DECODER_H - -#include - -#include - -#include "mpg123.h" -#include "sndfile.h" - -#include "sound_decoder.hpp" - - -namespace MWSound -{ - class MpgSnd_Decoder : public Sound_Decoder - { - SF_INFO mSndInfo; - SNDFILE *mSndFile; - mpg123_handle *mMpgFile; - - Ogre::DataStreamPtr mDataStream; - static sf_count_t ogresf_get_filelen(void *user_data); - static sf_count_t ogresf_seek(sf_count_t offset, int whence, void *user_data); - static sf_count_t ogresf_read(void *ptr, sf_count_t count, void *user_data); - static sf_count_t ogresf_write(const void*, sf_count_t, void*); - static sf_count_t ogresf_tell(void *user_data); - static ssize_t ogrempg_read(void*, void*, size_t); - static off_t ogrempg_lseek(void*, off_t, int); - - ChannelConfig mChanConfig; - int mSampleRate; - - virtual void open(const std::string &fname); - virtual void close(); - - virtual std::string getName(); - virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type); - - virtual size_t read(char *buffer, size_t bytes); - virtual void readAll(std::vector &output); - virtual void rewind(); - virtual size_t getSampleOffset(); - - MpgSnd_Decoder& operator=(const MpgSnd_Decoder &rhs); - MpgSnd_Decoder(const MpgSnd_Decoder &rhs); - - MpgSnd_Decoder(); - public: - virtual ~MpgSnd_Decoder(); - - friend class SoundManager; - }; -#ifndef DEFAULT_DECODER -#define DEFAULT_DECODER (::MWSound::MpgSnd_Decoder) -#endif -} - -#endif diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 33032477f..8ce87a25e 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -17,8 +17,8 @@ #include "openal_output.hpp" #define SOUND_OUT "OpenAL" -/* Set up the sound manager to use FFMPEG, MPG123+libsndfile, or Audiere for - * input. The OPENMW_USE_x macros are set in CMakeLists.txt. +/* Set up the sound manager to use FFMPEG for input. + * The OPENMW_USE_x macros are set in CMakeLists.txt. */ #ifdef OPENMW_USE_FFMPEG #include "ffmpeg_decoder.hpp" @@ -27,20 +27,6 @@ #endif #endif -#ifdef OPENMW_USE_AUDIERE -#include "audiere_decoder.hpp" -#ifndef SOUND_IN -#define SOUND_IN "Audiere" -#endif -#endif - -#ifdef OPENMW_USE_MPG123 -#include "mpgsnd_decoder.hpp" -#ifndef SOUND_IN -#define SOUND_IN "mpg123,sndfile" -#endif -#endif - namespace MWSound { From be89654eef51fb33701006b9114e804ecf40723e Mon Sep 17 00:00:00 2001 From: Thoronador Date: Sat, 3 May 2014 22:05:21 +0200 Subject: [PATCH 056/121] remove audiere_decoder + mpgsnd_decoder from CMake file for openmw --- apps/openmw/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 0661508b8..89e40c9b1 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -48,7 +48,7 @@ add_openmw_dir (mwscript ) add_openmw_dir (mwsound - soundmanagerimp openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder + soundmanagerimp openal_output ffmpeg_decoder ) add_openmw_dir (mwworld From bc6197c5523fc7cc8879910ee9b6d45d154e03e6 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 3 May 2014 18:57:34 -0500 Subject: [PATCH 057/121] Added custom spin box class --- apps/opencs/view/settings/spinbox.cpp | 51 +++++++++++++++++++++++++++ apps/opencs/view/settings/spinbox.hpp | 31 ++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 apps/opencs/view/settings/spinbox.cpp create mode 100644 apps/opencs/view/settings/spinbox.hpp diff --git a/apps/opencs/view/settings/spinbox.cpp b/apps/opencs/view/settings/spinbox.cpp new file mode 100644 index 000000000..bfb166370 --- /dev/null +++ b/apps/opencs/view/settings/spinbox.cpp @@ -0,0 +1,51 @@ +#include "spinbox.hpp" + +#include +#include + +CSVSettings::SpinBox::SpinBox(QWidget *parent) + : mValueList(QStringList()), QSpinBox(parent) +{ + setRange (0, 0); +} + +QString CSVSettings::SpinBox::textFromValue(int val) const +{ + if (mValueList.isEmpty()) + return QVariant (val).toString(); + + QString value = ""; + + if (val < mValueList.size()) + value = mValueList.at (val); + + return value; +} + +int CSVSettings::SpinBox::valueFromText(const QString &text) const +{ + if (mValueList.isEmpty()) + return -1; + + if (mValueList.contains (text)) + return mValueList.indexOf(text); + + return -1; +} + +void CSVSettings::SpinBox::setValue (const QString &value) +{ + if (!mValueList.isEmpty()) + { + lineEdit()->setText (value); + QSpinBox::setValue(valueFromText(value)); + } + else + QSpinBox::setValue (value.toInt()); +} + +void CSVSettings::SpinBox::setValueList (const QStringList &list) +{ + mValueList = list; + setMaximum (list.size() - 1); +} diff --git a/apps/opencs/view/settings/spinbox.hpp b/apps/opencs/view/settings/spinbox.hpp new file mode 100644 index 000000000..f8e59fa05 --- /dev/null +++ b/apps/opencs/view/settings/spinbox.hpp @@ -0,0 +1,31 @@ +#ifndef CSVSETTINGS_SPINBOX_HPP +#define CSVSETTINGS_SPINBOX_HPP + +#include +#include +#include + +namespace CSVSettings +{ + class SpinBox : public QSpinBox + { + Q_OBJECT + + QStringList mValueList; + + public: + explicit SpinBox(QWidget *parent = 0); + + void setObjectName (const QString &name); + + void setValue (const QString &value); + void setValueList (const QStringList &list); + const QStringList &valueList() const { return mValueList; } + + protected: + + QString textFromValue (int val) const; + int valueFromText (const QString &text) const; + }; +} +#endif // CSVSETTINGS_SPINBOX_HPP From 1c26741c5618c29321748d15b979813b5ee1618e Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 3 May 2014 18:58:43 -0500 Subject: [PATCH 058/121] Implemented rangeview with spinbox as only control. Simplified setting class constructor. --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/model/settings/setting.cpp | 135 ++++++++++++---- apps/opencs/model/settings/setting.hpp | 43 +++-- apps/opencs/model/settings/settingmanager.cpp | 6 +- apps/opencs/model/settings/settingmanager.hpp | 3 +- apps/opencs/model/settings/support.hpp | 43 +++-- apps/opencs/model/settings/usersettings.cpp | 142 +++++++++++----- apps/opencs/view/settings/booleanview.cpp | 13 +- apps/opencs/view/settings/dialog.cpp | 2 - apps/opencs/view/settings/frame.cpp | 2 + apps/opencs/view/settings/page.cpp | 2 + apps/opencs/view/settings/rangeview.cpp | 151 +++++++++++------- apps/opencs/view/settings/rangeview.hpp | 14 +- apps/opencs/view/settings/textview.cpp | 14 +- apps/opencs/view/settings/textview.hpp | 6 - apps/opencs/view/settings/view.cpp | 1 + apps/opencs/view/settings/view.hpp | 2 +- 17 files changed, 398 insertions(+), 182 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 680c8f8b7..38075ac53 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -97,6 +97,7 @@ opencs_units (view/settings listview rangeview resizeablestackedwidget + spinbox ) opencs_units_noqt (view/settings diff --git a/apps/opencs/model/settings/setting.cpp b/apps/opencs/model/settings/setting.cpp index ca682b454..1b265759c 100644 --- a/apps/opencs/model/settings/setting.cpp +++ b/apps/opencs/model/settings/setting.cpp @@ -1,13 +1,8 @@ #include "setting.hpp" #include "support.hpp" -CSMSettings::Setting::Setting() -{ - buildDefaultSetting(); -} - CSMSettings::Setting::Setting(SettingType typ, const QString &settingName, - const QString &pageName, const QStringList &values) + const QString &pageName) : mIsEditorSetting (false) { buildDefaultSetting(); @@ -19,10 +14,9 @@ CSMSettings::Setting::Setting(SettingType typ, const QString &settingName, setProperty (Property_IsMultiValue, QVariant(true).toString()); //view type is related to setting type by an order of magnitude - setProperty (Property_ViewType, QVariant (settingType / 10).toString()); + setProperty (Property_SettingType, QVariant (settingType).toString()); setProperty (Property_Page, pageName); setProperty (Property_Name, settingName); - setProperty (Property_DeclaredValues, values); } void CSMSettings::Setting::buildDefaultSetting() @@ -73,6 +67,11 @@ int CSMSettings::Setting::columnSpan() const return property (Property_ColumnSpan).at(0).toInt(); } +void CSMSettings::Setting::setDeclaredValues (QStringList list) +{ + setProperty (Property_DeclaredValues, list); +} + QStringList CSMSettings::Setting::declaredValues() const { return property (Property_DeclaredValues); @@ -165,6 +164,16 @@ bool CSMSettings::Setting::serializable() const return (property (Property_Serializable).at(0) == "true"); } +void CSMSettings::Setting::setSpecialValueText(const QString &text) +{ + setProperty (Property_SpecialValueText, text); +} + +QString CSMSettings::Setting::specialValueText() const +{ + return property (Property_SpecialValueText).at(0); +} + void CSMSettings::Setting::setName (const QString &value) { setProperty (Property_Name, value); @@ -185,6 +194,16 @@ QString CSMSettings::Setting::page() const return property (Property_Page).at(0); } +void CSMSettings::Setting::setPrefix (const QString &value) +{ + setProperty (Property_Prefix, value); +} + +QString CSMSettings::Setting::prefix() const +{ + return property (Property_Prefix).at(0); +} + void CSMSettings::Setting::setRowSpan (const int value) { setProperty (Property_RowSpan, value); @@ -195,15 +214,76 @@ int CSMSettings::Setting::rowSpan () const return property (Property_RowSpan).at(0).toInt(); } -void CSMSettings::Setting::setViewType (int vType) +void CSMSettings::Setting::setSingleStep (int value) { - setProperty (Property_ViewType, vType); + setProperty (Property_SingleStep, value); +} + +void CSMSettings::Setting::setSingleStep (double value) +{ + setProperty (Property_SingleStep, value); +} + +QString CSMSettings::Setting::singleStep() const +{ + return property (Property_SingleStep).at(0); +} + +void CSMSettings::Setting::setSuffix (const QString &value) +{ + setProperty (Property_Suffix, value); +} + +QString CSMSettings::Setting::suffix() const +{ + return property (Property_Suffix).at(0); +} + +void CSMSettings::Setting::setType (int settingType) +{ + setProperty (Property_SettingType, settingType); +} + +CSMSettings::SettingType CSMSettings::Setting::type() const +{ + return static_cast ( property ( + Property_SettingType).at(0).toInt()); +} + +void CSMSettings::Setting::setMaximum (int value) +{ + setProperty (Property_Maximum, value); +} + +void CSMSettings::Setting::setMaximum (double value) +{ + setProperty (Property_Maximum, value); +} + +QString CSMSettings::Setting::maximum() const +{ + return property (Property_Maximum).at(0); +} + +void CSMSettings::Setting::setMinimum (int value) +{ + setProperty (Property_Minimum, value); +} + +void CSMSettings::Setting::setMinimum (double value) +{ + setProperty (Property_Minimum, value); +} + +QString CSMSettings::Setting::minimum() const +{ + return property (Property_Minimum).at(0); } CSVSettings::ViewType CSMSettings::Setting::viewType() const { - return static_cast - (property(Property_ViewType).at(0).toInt()); + return static_cast ( property ( + Property_SettingType).at(0).toInt() / 10); } void CSMSettings::Setting::setViewColumn (int value) @@ -241,6 +321,17 @@ int CSMSettings::Setting::widgetWidth() const { return property (Property_WidgetWidth).at(0).toInt(); } + +void CSMSettings::Setting::setWrapping (bool state) +{ + setProperty (Property_Wrapping, state); +} + +bool CSMSettings::Setting::wrapping() const +{ + return (property (Property_Wrapping).at(0) == "true"); +} + void CSMSettings::Setting::setProperty (SettingProperty prop, bool value) { setProperty (prop, QStringList() << QVariant (value).toString()); @@ -251,6 +342,11 @@ void CSMSettings::Setting::setProperty (SettingProperty prop, int value) setProperty (prop, QStringList() << QVariant (value).toString()); } +void CSMSettings::Setting::setProperty (SettingProperty prop, double value) +{ + setProperty (prop, QStringList() << QVariant (value).toString()); +} + void CSMSettings::Setting::setProperty (SettingProperty prop, const QString &value) { @@ -263,18 +359,3 @@ void CSMSettings::Setting::setProperty (SettingProperty prop, if (prop < mProperties.size()) mProperties.replace (prop, value); } - -QDataStream &operator <<(QDataStream &stream, const CSMSettings::Setting& setting) -{ - // stream << setting.properties(); - - // stream << setting.proxies(); - return stream; -} - -QDataStream &operator >>(QDataStream& stream, CSMSettings::Setting& setting) -{ - // stream >> setting.properties(); - // stream >> setting.proxies(); - return stream; -} diff --git a/apps/opencs/model/settings/setting.hpp b/apps/opencs/model/settings/setting.hpp index 1463e4d7d..4e28a2348 100644 --- a/apps/opencs/model/settings/setting.hpp +++ b/apps/opencs/model/settings/setting.hpp @@ -27,12 +27,8 @@ namespace CSMSettings public: - - explicit Setting(); - explicit Setting(SettingType typ, const QString &settingName, - const QString &pageName, - const QStringList &values = QStringList()); + const QString &pageName); void addProxy (const Setting *setting, const QStringList &vals); void addProxy (const Setting *setting, const QList &list); @@ -66,12 +62,18 @@ namespace CSMSettings void setIsMultiValue (bool state); bool isMultiValue() const; + void setMask (const QString &value); + QString mask() const; + void setName (const QString &value); QString name() const; void setPage (const QString &value); QString page() const; + void setPrefix (const QString &value); + QString prefix() const; + void setRowSpan (const int value); int rowSpan() const; @@ -80,6 +82,24 @@ namespace CSMSettings void setSerializable (bool state); bool serializable() const; + void setSpecialValueText (const QString &text); + QString specialValueText() const; + + void setSingleStep (int value); + void setSingleStep (double value); + QString singleStep() const; + + void setSuffix (const QString &value); + QString suffix() const; + + void setMaximum (int value); + void setMaximum (double value); + QString maximum() const; + + void setMinimum (int value); + void setMinimum (double value); + QString minimum() const; + void setViewColumn (int value); int viewColumn() const; @@ -88,9 +108,14 @@ namespace CSMSettings void setViewRow (int value); int viewRow() const; - void setViewType (int vType); + void setType (int settingType); + CSMSettings::SettingType type() const; + CSVSettings::ViewType viewType() const; + void setWrapping (bool state); + bool wrapping() const; + void setWidgetWidth (int value); int widgetWidth() const; @@ -100,6 +125,7 @@ namespace CSMSettings ///boilerplate code to convert setting values of common types void setProperty (SettingProperty prop, bool value); void setProperty (SettingProperty prop, int value); + void setProperty (SettingProperty prop, double value); void setProperty (SettingProperty prop, const QString &value); void setProperty (SettingProperty prop, const QStringList &value); @@ -111,9 +137,4 @@ namespace CSMSettings }; } -Q_DECLARE_METATYPE(CSMSettings::Setting) - -QDataStream &operator <<(QDataStream &stream, const CSMSettings::Setting& setting); -QDataStream &operator >>(QDataStream &stream, CSMSettings::Setting& setting); - #endif // CSMSETTINGS_SETTING_HPP diff --git a/apps/opencs/model/settings/settingmanager.cpp b/apps/opencs/model/settings/settingmanager.cpp index eec4c54cf..36ca1ae03 100644 --- a/apps/opencs/model/settings/settingmanager.cpp +++ b/apps/opencs/model/settings/settingmanager.cpp @@ -30,8 +30,7 @@ void CSMSettings::SettingManager::dumpModel() } CSMSettings::Setting *CSMSettings::SettingManager::createSetting - (CSMSettings::SettingType typ, const QString &page, const QString &name, - const QStringList &values) + (CSMSettings::SettingType typ, const QString &page, const QString &name) { //get list of all settings for the current setting name if (findSetting (page, name)) @@ -41,7 +40,8 @@ CSMSettings::Setting *CSMSettings::SettingManager::createSetting return 0; } - Setting *setting = new Setting (typ, name, page, values); + Setting *setting = new Setting (typ, name, page); + //add declaration to the model mSettings.append (setting); diff --git a/apps/opencs/model/settings/settingmanager.hpp b/apps/opencs/model/settings/settingmanager.hpp index ca8a2cc7b..2efc2929f 100644 --- a/apps/opencs/model/settings/settingmanager.hpp +++ b/apps/opencs/model/settings/settingmanager.hpp @@ -46,8 +46,7 @@ namespace CSMSettings ///add a new setting to the model and return it Setting *createSetting (CSMSettings::SettingType typ, - const QString &page, const QString &name, - const QStringList &values = QStringList()); + const QString &page, const QString &name); ///add definitions to the settings specified in the page map void addDefinitions (DefinitionPageMap &pageMap); diff --git a/apps/opencs/model/settings/support.hpp b/apps/opencs/model/settings/support.hpp index ce808587f..be5a407ad 100644 --- a/apps/opencs/model/settings/support.hpp +++ b/apps/opencs/model/settings/support.hpp @@ -27,7 +27,7 @@ namespace CSMSettings { Property_Name = 0, Property_Page = 1, - Property_ViewType = 2, + Property_SettingType = 2, Property_IsMultiValue = 3, Property_IsMultiLine = 4, Property_WidgetWidth = 5, @@ -37,12 +37,19 @@ namespace CSMSettings Property_Serializable = 9, Property_ColumnSpan = 10, Property_RowSpan = 11, + Property_Minimum = 12, + Property_Maximum = 13, + Property_SpecialValueText = 14, + Property_Prefix = 15, + Property_Suffix = 16, + Property_SingleStep = 17, + Property_Wrapping = 18, //Stringlists should always be the last items - Property_DefaultValues = 12, - Property_DeclaredValues = 13, - Property_DefinedValues = 14, - Property_Proxies = 15 + Property_DefaultValues = 19, + Property_DeclaredValues = 20, + Property_DefinedValues = 21, + Property_Proxies = 22 }; enum SettingType @@ -64,10 +71,12 @@ namespace CSMSettings Type_ListView = 10, Type_ComboBox = 11, Type_SpinBox = 21, - Type_Slider = 23, - Type_Dial = 24, + Type_DoubleSpinBox = 23, + Type_Slider = 25, + Type_Dial = 27, Type_TextArea = 30, - Type_LineEdit = 31 + Type_LineEdit = 31, + Type_Undefined = 40 }; enum MergeMethod @@ -97,7 +106,7 @@ namespace CSVSettings }; } -// + namespace CSMSettings { struct PropertyDefaultValues @@ -109,9 +118,10 @@ namespace CSMSettings const QString sPropertyNames[] = { - "name", "page", "view_type", "is_multi_value", + "name", "page", "setting_type", "is_multi_value", "is_multi_line", "widget_width", "view_row", "view_column", "delimiter", - "is_serializable","column_span", "row_span", + "is_serializable","column_span", "row_span", "minimum", "maximum", + "special_value_text", "prefix", "suffix", "single_step", "wrapping", "defaults", "declarations", "definitions", "proxies" }; @@ -119,16 +129,23 @@ namespace CSMSettings { "", //name "", //page - "0", //view type + "40", //setting type "false", //multivalue "false", //multiline - "0", //widget width + "7", //widget width "-1", //view row "-1", //view column ",", //delimiter "true", //serialized "1", //column span "1", //row span + "0", //value range + "0", //value minimum + "0", //value maximum + "", //special text + "", //prefix + "", //suffix + "false", //wrapping "", //default values "", //declared values "", //defined values diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 2f8e8098d..17448f168 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -51,7 +51,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() Setting *height = createSetting (Type_LineEdit, section, "Height"); width->setWidgetWidth (5); - height->setWidgetWidth (5); + height->setWidgetWidth (8); width->setDefaultValues (QStringList() << "1024"); height->setDefaultValues (QStringList() << "768"); @@ -66,13 +66,10 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() *Create the proxy setting for predefined values */ Setting *preDefined = createSetting (Type_ComboBox, section, - "Pre-Defined", - QStringList() - << "640 x 480" - << "800 x 600" - << "1024 x 768" - << "1440 x 900" - ); + "Pre-Defined"); + + preDefined->setDeclaredValues (QStringList() << "640 x 480" + << "800 x 600" << "1024 x 768" << "1440 x 900"); preDefined->setViewLocation (1, 1); preDefined->setWidgetWidth (10); @@ -95,12 +92,13 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() << defaultValue << "Icon Only" << "Text Only"; Setting *rsd = createSetting (Type_RadioButton, - section, "Record Status Display", - values); + section, "Record Status Display"); Setting *ritd = createSetting (Type_RadioButton, - section, "Referenceable ID Type Display", - values); + section, "Referenceable ID Type Display"); + + rsd->setDeclaredValues (values); + ritd->setDeclaredValues (values); rsd->setEditorSetting (true); ritd->setEditorSetting (true); @@ -108,44 +106,63 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() section = "Proxy Selection Test"; { - //create three setting objects, specifying the basic widget type, - //the setting view name, the page name, and the default value + /****************************************************************** + * There are three types of values: + * + * Declared values + * + * Pre-determined values, typically for + * combobox drop downs and boolean (radiobutton / checkbox) labels. + * These values represent the total possible list of values that + * may define a setting. No other values are allowed. + * + * Defined values + * + * Values which represent the actual, current value of + * a setting. For settings with declared values, this must be one or + * several declared values, as appropriate. + * + * Proxy values - values the proxy master updates the proxy slave when + * it's own definition is set / changed. These are definitions for + * proxy slave settings, but must match any declared values the proxy + * slave has, if any. + *******************************************************************/ + + //create setting objects, specifying the basic widget type, + //the page name, and the view name + Setting *masterBoolean = createSetting (Type_RadioButton, section, - "Master Proxy", - QStringList() - << "Profile One" << "Profile Two" - << "Profile Three" << "Profile Four" - ); + "Master Proxy"); Setting *slaveBoolean = createSetting (Type_CheckBox, section, - "Proxy Checkboxes", - QStringList() << "One" << "Two" - << "Three" << "Four" << "Five" - ); + "Proxy Checkboxes"); Setting *slaveSingleText = createSetting (Type_LineEdit, section, - "Proxy TextBox 1" - ); + "Proxy TextBox 1"); Setting *slaveMultiText = createSetting (Type_LineEdit, section, - "ProxyTextBox 2" - ); + "ProxyTextBox 2"); + + Setting *slaveAlphaSpinbox = createSetting (Type_SpinBox, section, + "Alpha Spinbox"); + + Setting *slaveIntegerSpinbox = createSetting (Type_SpinBox, section, + "Int Spinbox"); + + Setting *slaveDoubleSpinbox = createSetting (Type_DoubleSpinBox, + section, "Double Spinbox"); + + //set declared values for selected views + masterBoolean->setDeclaredValues (QStringList() + << "Profile One" << "Profile Two" + << "Profile Three" << "Profile Four"); + + slaveBoolean->setDeclaredValues (QStringList() + << "One" << "Two" << "Three" << "Four" << "Five"); + + slaveAlphaSpinbox->setDeclaredValues (QStringList() + << "One" << "Two" << "Three" << "Four"); - // There are three types of values: - // - // Declared values - Pre-determined values, typically for - // combobox drop downs and boolean (radiobutton / checkbox) labels. - // These values represent the total possible list of values that may - // define a setting. No other values are allowed. - // - // Defined values - Values which represent the atual, current value of - // a setting. For settings with declared values, this must be one or - // several declared values, as appropriate. - // - // Proxy values - values the proxy master updates the proxy slave when - // it's own definition is set / changed. These are definitions for - // proxy slave settings, but must match any declared values the proxy - // slave has, if any. masterBoolean->addProxy (slaveBoolean, QList () << (QStringList() << "One" << "Three") @@ -168,11 +185,32 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() << (QStringList() << "Two" << "Four") ); + masterBoolean->addProxy (slaveAlphaSpinbox, QList () + << (QStringList() << "Four") + << (QStringList() << "Three") + << (QStringList() << "Two") + << (QStringList() << "One")); + + masterBoolean->addProxy (slaveIntegerSpinbox, QList () + << (QStringList() << "0") + << (QStringList() << "7") + << (QStringList() << "14") + << (QStringList() << "21")); + + masterBoolean->addProxy (slaveDoubleSpinbox, QList () + << (QStringList() << "0.17") + << (QStringList() << "0.34") + << (QStringList() << "0.51") + << (QStringList() << "0.68")); + //settings with proxies are not serialized by default //other settings non-serialized for demo purposes slaveBoolean->setSerializable (false); slaveSingleText->setSerializable (false); slaveMultiText->setSerializable (false); + slaveAlphaSpinbox->setSerializable (false); + slaveIntegerSpinbox->setSerializable (false); + slaveDoubleSpinbox->setSerializable (false); slaveBoolean->setDefaultValues (QStringList() << "One" << "Three" << "Five"); @@ -184,7 +222,25 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() slaveSingleText->setWidgetWidth (24); slaveMultiText->setWidgetWidth (24); - } + + slaveAlphaSpinbox->setDefaultValue ("Two"); + slaveAlphaSpinbox->setWidgetWidth (20); + //slaveAlphaSpinbox->setPrefix ("No. "); + //slaveAlphaSpinbox->setSuffix ("!"); + slaveAlphaSpinbox->setWrapping (true); + + slaveIntegerSpinbox->setDefaultValue ("14"); + slaveIntegerSpinbox->setMinimum (0); + slaveIntegerSpinbox->setMaximum (58); + slaveIntegerSpinbox->setPrefix ("$"); + slaveIntegerSpinbox->setSuffix (".00"); + slaveIntegerSpinbox->setWidgetWidth (10); + slaveIntegerSpinbox->setSpecialValueText ("Nothing!"); + + slaveDoubleSpinbox->setDefaultValue ("0.51"); + slaveDoubleSpinbox->setSingleStep(0.17); + slaveDoubleSpinbox->setMaximum(4.0); + } } CSMSettings::UserSettings::~UserSettings() diff --git a/apps/opencs/view/settings/booleanview.cpp b/apps/opencs/view/settings/booleanview.cpp index 1c48199d1..2a3f0cba6 100644 --- a/apps/opencs/view/settings/booleanview.cpp +++ b/apps/opencs/view/settings/booleanview.cpp @@ -18,10 +18,19 @@ CSVSettings::BooleanView::BooleanView (CSMSettings::Setting *setting, { QAbstractButton *button = 0; - if (isMultiValue()) + switch (setting->type()) + { + case CSMSettings::Type_CheckBox: button = new QCheckBox (value, this); - else + break; + + case CSMSettings::Type_RadioButton: button = new QRadioButton (value, this); + break; + + default: + break; + } connect (button, SIGNAL (clicked (bool)), this, SLOT (slotToggled (bool))); diff --git a/apps/opencs/view/settings/dialog.cpp b/apps/opencs/view/settings/dialog.cpp index d9d5830d9..3ed4d3b09 100644 --- a/apps/opencs/view/settings/dialog.cpp +++ b/apps/opencs/view/settings/dialog.cpp @@ -123,10 +123,8 @@ void CSVSettings::Dialog::show() { if (pages().isEmpty()) buildPages(); - QPoint screenCenter = QApplication::desktop()->screenGeometry().center(); move (screenCenter - geometry().center()); - QWidget::show(); } diff --git a/apps/opencs/view/settings/frame.cpp b/apps/opencs/view/settings/frame.cpp index db5091999..019024776 100644 --- a/apps/opencs/view/settings/frame.cpp +++ b/apps/opencs/view/settings/frame.cpp @@ -60,8 +60,10 @@ void CSVSettings::Frame::showWidgets() QWidget *widg = static_cast (obj); if (widg->property("sizePolicy").isValid()) + { widg->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + } } layout()->activate(); setFixedSize(minimumSizeHint()); diff --git a/apps/opencs/view/settings/page.cpp b/apps/opencs/view/settings/page.cpp index e67445873..afd4bff5e 100644 --- a/apps/opencs/view/settings/page.cpp +++ b/apps/opencs/view/settings/page.cpp @@ -7,6 +7,8 @@ #include "../../model/settings/usersettings.hpp" #include "../../model/settings/connector.hpp" +#include "../../model/settings/support.hpp" + #include "settingwindow.hpp" QMap diff --git a/apps/opencs/view/settings/rangeview.cpp b/apps/opencs/view/settings/rangeview.cpp index 2bb5863bc..ac9a5da8b 100644 --- a/apps/opencs/view/settings/rangeview.cpp +++ b/apps/opencs/view/settings/rangeview.cpp @@ -1,88 +1,129 @@ #include #include - -#include -#include #include - -#include +#include +#include +#include #include "rangeview.hpp" +#include "spinbox.hpp" #include "../../model/settings/setting.hpp" - - -#include +#include "../../model/settings/support.hpp" CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting, Page *parent) - : View (setting, parent) + : mRangeWidget (0), mRangeType (setting->type()), View (setting, parent) { - foreach (const QString &value, setting->declaredValues()) - { - QAbstractButton *button = 0; - if (isMultiValue()) - button = new QCheckBox (value, this); - else - button = new QRadioButton (value, this); + mRangeWidget = 0; - connect (button, SIGNAL (clicked (bool)), - this, SLOT (slotToggled (bool))); - - button->setObjectName (value); - - addWidget (button); - - mButtons[value] = button; - } -} - -void CSVSettings::RangeView::slotToggled (bool state) -{ - //test only for true to avoid multiple selection updates with radiobuttons - if (!isMultiValue() && !state) + if (isMultiValue()) return; - QStringList values; + buildSpinBox (setting); - foreach (QString key, mButtons.keys()) + mRangeWidget->setFixedWidth (widgetWidth (setting->widgetWidth())); + mRangeWidget->setObjectName (setting->name()); + + addWidget (mRangeWidget); +} + +void CSVSettings::RangeView::buildSpinBox (CSMSettings::Setting *setting) +{ + SpinBox *sb = 0; + + switch (setting->type()) { - if (mButtons.value(key)->isChecked()) - values.append (key); + case CSMSettings::Type_SpinBox: + + sb = new SpinBox (this); + + if (!setting->declaredValues().isEmpty()) + sb->setValueList (setting->declaredValues()); + + mRangeWidget = sb; + + connect (mRangeWidget, SIGNAL (valueChanged (int)), + this, SLOT (slotUpdateView (int))); + break; + + case CSMSettings::Type_DoubleSpinBox: + mRangeWidget = new QDoubleSpinBox (this); + + connect (mRangeWidget, SIGNAL (valueChanged (double)), + this, SLOT (slotUpdateView (double))); + break; + + default: + break; } - setSelectedValues (values, false); + + //min / max values are set automatically in AlphaSpinBox + if (setting->declaredValues().isEmpty()) + { + mRangeWidget->setProperty ("minimum", setting->minimum()); + mRangeWidget->setProperty ("maximum", setting->maximum()); + mRangeWidget->setProperty ("singleStep", setting->singleStep()); + mRangeWidget->setProperty ("specialValueText", + setting->specialValueText()); + } + + mRangeWidget->setProperty ("prefix", setting->prefix()); + mRangeWidget->setProperty ("suffix", setting->suffix()); + mRangeWidget->setProperty ("wrapping", setting->wrapping()); + +} + +void CSVSettings::RangeView::slotUpdateView (int value) +{ + QString textValue = ""; + + if (mRangeType == CSMSettings::Type_SpinBox) + { + QStringList list = + static_cast (mRangeWidget)->valueList(); + if (!list.isEmpty()) + textValue = list.at(value); + } + + if (textValue.isEmpty()) + textValue = QVariant (value).toString(); + + setSelectedValue (textValue, false); + + View::updateView(); + +} + +void CSVSettings::RangeView::slotUpdateView (double value) +{ + setSelectedValue (QVariant(value).toString(), false); View::updateView(); } void CSVSettings::RangeView::updateView (bool signalUpdate) const { + QString value; - QStringList values = selectedValues(); + if (!selectedValues().isEmpty()) + value = selectedValues().at(0); - foreach (const QString &buttonName, mButtons.keys()) + switch (mRangeType) { - QAbstractButton *button = mButtons[buttonName]; + case CSMSettings::Type_SpinBox: + static_cast (mRangeWidget)->setValue (value); + break; - //if the value is not found in the list, the widget is checked false - bool buttonValue = values.contains(buttonName); + case CSMSettings::Type_DoubleSpinBox: + static_cast (mRangeWidget)->setValue (value.toDouble()); + break; - //skip if the butotn value will not change - if (button->isChecked() == buttonValue) - continue; + default: + break; - //disable autoexclusive if it's enabled and we're setting - //the button value to false - bool switchExclusive = (!buttonValue && button->autoExclusive()); - - if (switchExclusive) - button->setAutoExclusive (false); - - button->setChecked (buttonValue); - - if (switchExclusive) - button->setAutoExclusive(true); } + View::updateView (signalUpdate); } diff --git a/apps/opencs/view/settings/rangeview.hpp b/apps/opencs/view/settings/rangeview.hpp index 1df0c7bd6..6515c9168 100644 --- a/apps/opencs/view/settings/rangeview.hpp +++ b/apps/opencs/view/settings/rangeview.hpp @@ -1,13 +1,11 @@ #ifndef CSVSETTINGS_RANGEVIEW_HPP #define CSVSETTINGS_RANGEVIEW_HPP -#include -#include - #include "view.hpp" #include "../../model/settings/support.hpp" class QStringListModel; +class QAbstractSpinBox; namespace CSVSettings { @@ -15,7 +13,8 @@ namespace CSVSettings { Q_OBJECT - QMap mButtons; + QAbstractSpinBox *mRangeWidget; + CSMSettings::SettingType mRangeType; public: explicit RangeView (CSMSettings::Setting *setting, @@ -24,8 +23,13 @@ namespace CSVSettings protected: void updateView (bool signalUpdate = true) const; + void buildSpinBox (CSMSettings::Setting *setting); + private slots: - void slotToggled (bool state); + + void slotUpdateView (int value); + void slotUpdateView (double value); + }; class RangeViewFactory : public QObject, public IViewFactory diff --git a/apps/opencs/view/settings/textview.cpp b/apps/opencs/view/settings/textview.cpp index 5e10c346f..6886732db 100644 --- a/apps/opencs/view/settings/textview.cpp +++ b/apps/opencs/view/settings/textview.cpp @@ -28,11 +28,6 @@ bool CSVSettings::TextView::isEquivalent return (lhs.trimmed() == rhs.trimmed()); } -void CSVSettings::TextView::setWidgetText (const QString &value) const -{ - mTextWidget->setProperty ("text", value); -} - void CSVSettings::TextView::slotTextEdited (QString value) { QStringList values = value.split (mDelimiter, QString::SkipEmptyParts); @@ -51,19 +46,14 @@ void CSVSettings::TextView::updateView(bool signalUpdate) const { QString values = selectedValues().join (mDelimiter); - if (isEquivalent (widgetText(), values)) + if (isEquivalent (mTextWidget->property("text").toString(), values)) return; - setWidgetText (values); + mTextWidget->setProperty("text", values); View::updateView (signalUpdate); } -QString CSVSettings::TextView::widgetText() const -{ - return mTextWidget->property("text").toString(); -} - CSVSettings::TextView *CSVSettings::TextViewFactory::createView (CSMSettings::Setting *setting, Page *parent) diff --git a/apps/opencs/view/settings/textview.hpp b/apps/opencs/view/settings/textview.hpp index 6d718aad8..c485e7fcf 100644 --- a/apps/opencs/view/settings/textview.hpp +++ b/apps/opencs/view/settings/textview.hpp @@ -32,12 +32,6 @@ namespace CSVSettings ///Comparison function that returns true if the trimmed() strings ///are equal bool isEquivalent (const QString &lhs, const QString &rhs) const; - - ///Convenience function to return the text of the widget - QString widgetText() const; - - ///Convenience function to set the text of the widget - void setWidgetText (const QString &value) const; }; class TextViewFactory : public QObject, public IViewFactory diff --git a/apps/opencs/view/settings/view.cpp b/apps/opencs/view/settings/view.cpp index 4f93b1c0f..2a70152c2 100644 --- a/apps/opencs/view/settings/view.cpp +++ b/apps/opencs/view/settings/view.cpp @@ -192,6 +192,7 @@ bool CSVSettings::View::stringListsMatch ( QList CSVSettings::View::toStandardItemList (const QStringList &list) const { + QList itemList; foreach (const QString &value, list) diff --git a/apps/opencs/view/settings/view.hpp b/apps/opencs/view/settings/view.hpp index c99879762..23357e45f 100644 --- a/apps/opencs/view/settings/view.hpp +++ b/apps/opencs/view/settings/view.hpp @@ -101,7 +101,7 @@ namespace CSVSettings void showEvent ( QShowEvent * event ); ///Virtual for updating a specific View subclass - ///bool indicates whether a signal is emitted that the view was updated + ///bool indicates whether viewUpdated() signal is emitted virtual void updateView (bool signalUpdate = true) const; ///Returns the pixel width corresponding to the specified number of From c4a9c180452bdf6a343ef059b78882548b1f350f Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 3 May 2014 19:36:52 -0500 Subject: [PATCH 059/121] Commented out "proxy selection test" demo page in user settings --- apps/opencs/model/settings/usersettings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 6e05e9dff..92ac627c4 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -127,7 +127,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() * proxy slave settings, but must match any declared values the proxy * slave has, if any. *******************************************************************/ - +/* //create setting objects, specifying the basic widget type, //the page name, and the view name @@ -240,7 +240,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() slaveDoubleSpinbox->setDefaultValue ("0.51"); slaveDoubleSpinbox->setSingleStep(0.17); slaveDoubleSpinbox->setMaximum(4.0); - } + }*/ } CSMSettings::UserSettings::~UserSettings() From 0a3ab3dcd13eeaec25d2404f050243b5ed7991be Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 3 May 2014 19:36:52 -0500 Subject: [PATCH 060/121] Commented out "proxy selection test" demo page in user settings --- apps/opencs/model/settings/usersettings.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 6e05e9dff..8bfdadf15 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -127,7 +127,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() * proxy slave settings, but must match any declared values the proxy * slave has, if any. *******************************************************************/ - +/* //create setting objects, specifying the basic widget type, //the page name, and the view name @@ -240,6 +240,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() slaveDoubleSpinbox->setDefaultValue ("0.51"); slaveDoubleSpinbox->setSingleStep(0.17); slaveDoubleSpinbox->setMaximum(4.0); +*/ } } From 4f876574c15e05a152baeb9788fa21f8dcab65fb Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 3 May 2014 21:50:08 -0500 Subject: [PATCH 061/121] Implemented slider widget in rangeView class --- apps/opencs/model/settings/setting.cpp | 30 ++++++++ apps/opencs/model/settings/setting.hpp | 21 ++++-- apps/opencs/model/settings/support.hpp | 15 ++-- apps/opencs/model/settings/usersettings.cpp | 22 +++++- apps/opencs/view/settings/rangeview.cpp | 79 +++++++++++++++++++-- apps/opencs/view/settings/rangeview.hpp | 3 +- 6 files changed, 151 insertions(+), 19 deletions(-) diff --git a/apps/opencs/model/settings/setting.cpp b/apps/opencs/model/settings/setting.cpp index 1b265759c..fe5a26bbc 100644 --- a/apps/opencs/model/settings/setting.cpp +++ b/apps/opencs/model/settings/setting.cpp @@ -239,6 +239,36 @@ QString CSMSettings::Setting::suffix() const return property (Property_Suffix).at(0); } +void CSMSettings::Setting::setTickInterval (int value) +{ + setProperty (Property_TickInterval, value); +} + +int CSMSettings::Setting::tickInterval () const +{ + return property (Property_TickInterval).at(0).toInt(); +} + +void CSMSettings::Setting::setTicksAbove (bool state) +{ + setProperty (Property_TicksAbove, state); +} + +bool CSMSettings::Setting::ticksAbove() const +{ + return (property (Property_TicksAbove).at(0) == "true"); +} + +void CSMSettings::Setting::setTicksBelow (bool state) +{ + setProperty (Property_TicksBelow, state); +} + +bool CSMSettings::Setting::ticksBelow() const +{ + return (property (Property_TicksBelow).at(0) == "true"); +} + void CSMSettings::Setting::setType (int settingType) { setProperty (Property_SettingType, settingType); diff --git a/apps/opencs/model/settings/setting.hpp b/apps/opencs/model/settings/setting.hpp index 4e28a2348..8efe33034 100644 --- a/apps/opencs/model/settings/setting.hpp +++ b/apps/opencs/model/settings/setting.hpp @@ -65,6 +65,14 @@ namespace CSMSettings void setMask (const QString &value); QString mask() const; + void setMaximum (int value); + void setMaximum (double value); + QString maximum() const; + + void setMinimum (int value); + void setMinimum (double value); + QString minimum() const; + void setName (const QString &value); QString name() const; @@ -92,13 +100,14 @@ namespace CSMSettings void setSuffix (const QString &value); QString suffix() const; - void setMaximum (int value); - void setMaximum (double value); - QString maximum() const; + void setTickInterval (int value); + int tickInterval() const; - void setMinimum (int value); - void setMinimum (double value); - QString minimum() const; + void setTicksAbove (bool state); + bool ticksAbove() const; + + void setTicksBelow (bool state); + bool ticksBelow() const; void setViewColumn (int value); int viewColumn() const; diff --git a/apps/opencs/model/settings/support.hpp b/apps/opencs/model/settings/support.hpp index be5a407ad..d65de2b91 100644 --- a/apps/opencs/model/settings/support.hpp +++ b/apps/opencs/model/settings/support.hpp @@ -44,12 +44,15 @@ namespace CSMSettings Property_Suffix = 16, Property_SingleStep = 17, Property_Wrapping = 18, + Property_TickInterval = 19, + Property_TicksAbove = 20, + Property_TicksBelow = 21, //Stringlists should always be the last items - Property_DefaultValues = 19, - Property_DeclaredValues = 20, - Property_DefinedValues = 21, - Property_Proxies = 22 + Property_DefaultValues = 22, + Property_DeclaredValues = 23, + Property_DefinedValues = 24, + Property_Proxies = 25 }; enum SettingType @@ -122,6 +125,7 @@ namespace CSMSettings "is_multi_line", "widget_width", "view_row", "view_column", "delimiter", "is_serializable","column_span", "row_span", "minimum", "maximum", "special_value_text", "prefix", "suffix", "single_step", "wrapping", + "tick_interval", "ticks_above", "ticks_below", "defaults", "declarations", "definitions", "proxies" }; @@ -146,6 +150,9 @@ namespace CSMSettings "", //prefix "", //suffix "false", //wrapping + "1", //tick interval + "false", //ticks above + "true", //ticks below "", //default values "", //declared values "", //defined values diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 8bfdadf15..787e26650 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -127,10 +127,10 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() * proxy slave settings, but must match any declared values the proxy * slave has, if any. *******************************************************************/ -/* + //create setting objects, specifying the basic widget type, //the page name, and the view name - +/* Setting *masterBoolean = createSetting (Type_RadioButton, section, "Master Proxy"); @@ -152,6 +152,8 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() Setting *slaveDoubleSpinbox = createSetting (Type_DoubleSpinBox, section, "Double Spinbox"); + Setting *slaveSlider = createSetting (Type_Slider, section, "Slider"); + //set declared values for selected views masterBoolean->setDeclaredValues (QStringList() << "Profile One" << "Profile Two" @@ -203,6 +205,13 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() << (QStringList() << "0.51") << (QStringList() << "0.68")); + masterBoolean->addProxy (slaveSlider, QList () + << (QStringList() << "25") + << (QStringList() << "50") + << (QStringList() << "75") + << (QStringList() << "100") + ); + //settings with proxies are not serialized by default //other settings non-serialized for demo purposes slaveBoolean->setSerializable (false); @@ -211,6 +220,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() slaveAlphaSpinbox->setSerializable (false); slaveIntegerSpinbox->setSerializable (false); slaveDoubleSpinbox->setSerializable (false); + slaveSlider->setSerializable (false); slaveBoolean->setDefaultValues (QStringList() << "One" << "Three" << "Five"); @@ -240,7 +250,13 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() slaveDoubleSpinbox->setDefaultValue ("0.51"); slaveDoubleSpinbox->setSingleStep(0.17); slaveDoubleSpinbox->setMaximum(4.0); -*/ + + slaveSlider->setMinimum (0); + slaveSlider->setMaximum (100); + slaveSlider->setDefaultValue ("75"); + slaveSlider->setWidgetWidth (100); + slaveSlider->setTicksAbove (true); + slaveSlider->setTickInterval (25);*/ } } diff --git a/apps/opencs/view/settings/rangeview.cpp b/apps/opencs/view/settings/rangeview.cpp index ac9a5da8b..b2701c7bf 100644 --- a/apps/opencs/view/settings/rangeview.cpp +++ b/apps/opencs/view/settings/rangeview.cpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include "rangeview.hpp" #include "spinbox.hpp" @@ -20,7 +23,21 @@ CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting, if (isMultiValue()) return; - buildSpinBox (setting); + switch (mRangeType) + { + case CSMSettings::Type_SpinBox: + case CSMSettings::Type_DoubleSpinBox: + buildSpinBox (setting); + break; + + case CSMSettings::Type_Dial: + case CSMSettings::Type_Slider: + buildSlider (setting); + break; + + default: + break; + } mRangeWidget->setFixedWidth (widgetWidth (setting->widgetWidth())); mRangeWidget->setObjectName (setting->name()); @@ -28,6 +45,48 @@ CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting, addWidget (mRangeWidget); } +void CSVSettings::RangeView::buildSlider (CSMSettings::Setting *setting) +{ + switch (setting->type()) + { + case CSMSettings::Type_Slider: + mRangeWidget = new QSlider (Qt::Horizontal, this); + mRangeWidget->setProperty ("tickInterval", setting->tickInterval()); + + if (setting->ticksAbove()) + { + if (setting->ticksBelow()) + mRangeWidget->setProperty ("tickPosition", QSlider::TicksBothSides); + else + mRangeWidget->setProperty ("tickPosition", QSlider::TicksAbove); + } + else if (setting->ticksBelow()) + mRangeWidget->setProperty ("tickPosition", QSlider::TicksBelow); + else + mRangeWidget->setProperty ("tickPosition", QSlider::NoTicks); + + break; + + case CSMSettings::Type_Dial: + mRangeWidget = new QDial (this); + mRangeWidget->setProperty ("wrapping", setting->wrapping()); + mRangeWidget->setProperty ("notchesVisible", + (setting->ticksAbove() || setting->ticksBelow())); + break; + + default: + break; + } + + mRangeWidget->setProperty ("minimum", setting->minimum()); + mRangeWidget->setProperty ("maximum", setting->maximum()); + mRangeWidget->setProperty ("tracking", false); + mRangeWidget->setProperty ("singleStep", setting->singleStep()); + + connect (mRangeWidget, SIGNAL (valueChanged (int)), + this, SLOT (slotUpdateView (int))); +} + void CSVSettings::RangeView::buildSpinBox (CSMSettings::Setting *setting) { SpinBox *sb = 0; @@ -77,13 +136,18 @@ void CSVSettings::RangeView::buildSpinBox (CSMSettings::Setting *setting) void CSVSettings::RangeView::slotUpdateView (int value) { QString textValue = ""; + QStringList list; - if (mRangeType == CSMSettings::Type_SpinBox) + switch (mRangeType) { - QStringList list = - static_cast (mRangeWidget)->valueList(); + case CSMSettings::Type_SpinBox: + list = static_cast (mRangeWidget)->valueList(); if (!list.isEmpty()) textValue = list.at(value); + break; + + default: + break; } if (textValue.isEmpty()) @@ -92,7 +156,6 @@ void CSVSettings::RangeView::slotUpdateView (int value) setSelectedValue (textValue, false); View::updateView(); - } void CSVSettings::RangeView::slotUpdateView (double value) @@ -119,6 +182,12 @@ void CSVSettings::RangeView::updateView (bool signalUpdate) const static_cast (mRangeWidget)->setValue (value.toDouble()); break; + case CSMSettings::Type_Slider: + case CSMSettings::Type_Dial: + mRangeWidget->setProperty ("value", value.toInt()); + mRangeWidget->setProperty ("sliderPosition", value.toInt()); + break; + default: break; diff --git a/apps/opencs/view/settings/rangeview.hpp b/apps/opencs/view/settings/rangeview.hpp index 6515c9168..e8d6df88e 100644 --- a/apps/opencs/view/settings/rangeview.hpp +++ b/apps/opencs/view/settings/rangeview.hpp @@ -13,7 +13,7 @@ namespace CSVSettings { Q_OBJECT - QAbstractSpinBox *mRangeWidget; + QWidget *mRangeWidget; CSMSettings::SettingType mRangeType; public: @@ -23,6 +23,7 @@ namespace CSVSettings protected: void updateView (bool signalUpdate = true) const; + void buildSlider (CSMSettings::Setting *setting); void buildSpinBox (CSMSettings::Setting *setting); private slots: From 3f737bbb44c73fd6833bea73bfadcc05b9eda6fa Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 3 May 2014 22:02:16 -0500 Subject: [PATCH 062/121] implemented QDial into RangeView class --- apps/opencs/model/settings/setting.cpp | 10 ++++++ apps/opencs/model/settings/setting.hpp | 2 ++ apps/opencs/model/settings/usersettings.cpp | 36 +++++++++++++++------ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/settings/setting.cpp b/apps/opencs/model/settings/setting.cpp index fe5a26bbc..fe15cf7f6 100644 --- a/apps/opencs/model/settings/setting.cpp +++ b/apps/opencs/model/settings/setting.cpp @@ -95,6 +95,16 @@ QStringList CSMSettings::Setting::property (SettingProperty prop) const return mProperties.at(prop); } +void CSMSettings::Setting::setDefaultValue (int value) +{ + setDefaultValues (QStringList() << QVariant (value).toString()); +} + +void CSMSettings::Setting::setDefaultValue (double value) +{ + setDefaultValues (QStringList() << QVariant (value).toString()); +} + void CSMSettings::Setting::setDefaultValue (const QString &value) { setDefaultValues (QStringList() << value); diff --git a/apps/opencs/model/settings/setting.hpp b/apps/opencs/model/settings/setting.hpp index 8efe33034..cf5dd2a06 100644 --- a/apps/opencs/model/settings/setting.hpp +++ b/apps/opencs/model/settings/setting.hpp @@ -45,6 +45,8 @@ namespace CSMSettings void setDefinedValues (QStringList list); QStringList definedValues() const; + void setDefaultValue (int value); + void setDefaultValue (double value); void setDefaultValue (const QString &value); void setDefaultValues (const QStringList &values); diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 787e26650..a8fd752e3 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -132,28 +132,30 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() //the page name, and the view name /* Setting *masterBoolean = createSetting (Type_RadioButton, section, - "Master Proxy"); + "Master Proxy"); Setting *slaveBoolean = createSetting (Type_CheckBox, section, - "Proxy Checkboxes"); + "Proxy Checkboxes"); Setting *slaveSingleText = createSetting (Type_LineEdit, section, - "Proxy TextBox 1"); + "Proxy TextBox 1"); Setting *slaveMultiText = createSetting (Type_LineEdit, section, - "ProxyTextBox 2"); + "ProxyTextBox 2"); Setting *slaveAlphaSpinbox = createSetting (Type_SpinBox, section, - "Alpha Spinbox"); + "Alpha Spinbox"); Setting *slaveIntegerSpinbox = createSetting (Type_SpinBox, section, - "Int Spinbox"); + "Int Spinbox"); Setting *slaveDoubleSpinbox = createSetting (Type_DoubleSpinBox, section, "Double Spinbox"); Setting *slaveSlider = createSetting (Type_Slider, section, "Slider"); + Setting *slaveDial = createSetting (Type_Dial, section, "Dial"); + //set declared values for selected views masterBoolean->setDeclaredValues (QStringList() << "Profile One" << "Profile Two" @@ -212,6 +214,13 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() << (QStringList() << "100") ); + masterBoolean->addProxy (slaveDial, QList () + << (QStringList() << "25") + << (QStringList() << "50") + << (QStringList() << "75") + << (QStringList() << "100") + ); + //settings with proxies are not serialized by default //other settings non-serialized for demo purposes slaveBoolean->setSerializable (false); @@ -239,7 +248,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() //slaveAlphaSpinbox->setSuffix ("!"); slaveAlphaSpinbox->setWrapping (true); - slaveIntegerSpinbox->setDefaultValue ("14"); + slaveIntegerSpinbox->setDefaultValue (14); slaveIntegerSpinbox->setMinimum (0); slaveIntegerSpinbox->setMaximum (58); slaveIntegerSpinbox->setPrefix ("$"); @@ -247,16 +256,23 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() slaveIntegerSpinbox->setWidgetWidth (10); slaveIntegerSpinbox->setSpecialValueText ("Nothing!"); - slaveDoubleSpinbox->setDefaultValue ("0.51"); + slaveDoubleSpinbox->setDefaultValue (0.51); slaveDoubleSpinbox->setSingleStep(0.17); slaveDoubleSpinbox->setMaximum(4.0); slaveSlider->setMinimum (0); slaveSlider->setMaximum (100); - slaveSlider->setDefaultValue ("75"); + slaveSlider->setDefaultValue (75); slaveSlider->setWidgetWidth (100); slaveSlider->setTicksAbove (true); - slaveSlider->setTickInterval (25);*/ + slaveSlider->setTickInterval (25); + + slaveDial->setMinimum (0); + slaveDial->setMaximum (100); + slaveDial->setSingleStep (5); + slaveDial->setDefaultValue (75); + slaveDial->setTickInterval (25); +*/ } } From 4a502226e6fc3c4441491fda2d6c9a6be69c5b80 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 4 May 2014 12:30:15 +0200 Subject: [PATCH 063/121] added flag to distingiush widgets --- apps/opencs/view/world/scenesubview.cpp | 25 +++++++++++++++++++++---- apps/opencs/view/world/scenesubview.hpp | 7 ++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 34008c9a8..36cce9ecd 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -35,9 +35,12 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); CSVRender::WorldspaceWidget* wordspaceWidget = NULL; + widgetType whatWidget; if (id.getId()=="sys::default") { + whatWidget = widget_Paged; + CSVRender::PagedWorldspaceWidget *newWidget = new CSVRender::PagedWorldspaceWidget (this, document); wordspaceWidget = newWidget; @@ -46,6 +49,8 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D } else { + whatWidget = widget_Unpaged; + CSVRender::UnpagedWorldspaceWidget *newWidget = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); wordspaceWidget = newWidget; @@ -53,7 +58,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D makeConnections(newWidget); } - replaceToolbarAndWorldspace(wordspaceWidget, makeToolbar(wordspaceWidget)); + replaceToolbarAndWorldspace(wordspaceWidget, makeToolbar(wordspaceWidget, whatWidget)); layout->insertLayout (0, mLayout, 1); @@ -90,7 +95,7 @@ void CSVWorld::SceneSubView::makeConnections (CSVRender::PagedWorldspaceWidget* this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); } -CSVWorld::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget) +CSVWorld::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget, widgetType type) { CSVWorld::SceneToolbar* toolbar = new SceneToolbar (48+6, this); @@ -100,6 +105,18 @@ CSVWorld::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldspa SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar); toolbar->addTool (lightingTool); +/* Add buttons specific to the type. For now no need for it. + * + switch (type) + { + case widget_Paged: + break; + + case widget_Unpaged: + break; + + } +*/ return toolbar; } @@ -181,7 +198,7 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI case CSVRender::WorldspaceWidget::needPaged: pagedNewWidget = new CSVRender::PagedWorldspaceWidget(this, mDocument); - toolbar = makeToolbar(pagedNewWidget); + toolbar = makeToolbar(pagedNewWidget, widget_Paged); makeConnections(pagedNewWidget); replaceToolbarAndWorldspace(pagedNewWidget, toolbar); mScene->handleDrop(data); @@ -189,7 +206,7 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI case CSVRender::WorldspaceWidget::needUnpaged: unPagedNewWidget = new CSVRender::UnpagedWorldspaceWidget(data.begin()->getId(), mDocument, this); - toolbar = makeToolbar(unPagedNewWidget); + toolbar = makeToolbar(unPagedNewWidget, widget_Unpaged); makeConnections(unPagedNewWidget); replaceToolbarAndWorldspace(unPagedNewWidget, toolbar); cellSelectionChanged(*(data.begin())); diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 251ddae1f..b9ecbe931 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -61,7 +61,12 @@ namespace CSVWorld void replaceToolbarAndWorldspace(CSVRender::WorldspaceWidget* widget, SceneToolbar* toolbar); - SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget); + enum widgetType + { + widget_Paged, + widget_Unpaged + }; + SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget, widgetType type); private slots: From a469444e5301d2bbe8b7efc0a3d470cfd2221cc4 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sun, 4 May 2014 08:05:32 -0400 Subject: [PATCH 064/121] Player can't detect self --- apps/openmw/mwmechanics/actors.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 71ccf7ff2..1d3b45b2d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -724,7 +724,8 @@ namespace MWMechanics void Actors::updateSneak (const MWWorld::Ptr& ptr) { const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - if (player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak)) + if ( player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak) + && ptr != player) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); int radius = esmStore.get().find("fSneakUseDist")->getInt(); From f51f826dad20e3d9b9f4798f401950b8a153137c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 4 May 2014 15:13:03 +0200 Subject: [PATCH 065/121] fixed compilation --- apps/opencs/view/render/pagedworldspacewidget.cpp | 2 +- apps/opencs/view/render/unpagedworldspacewidget.cpp | 2 +- apps/opencs/view/render/worldspacewidget.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index c9308fbfb..a3f34d218 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -3,7 +3,7 @@ #include -#include +#include #include diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index de4dde9dd..166c85f44 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -3,7 +3,7 @@ #include -#include +#include #include "../../model/doc/document.hpp" diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index c83a5a3e1..59b82bb67 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include "../world/scenetoolmode.hpp" #include From 7d5dab214c4a9911f8d1f1e3ea12de80c3eabce5 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sun, 4 May 2014 16:20:09 -0400 Subject: [PATCH 066/121] #58 - Sneak Skill: functional sneaking Removed sneak checking from individual actor update. Added sneak checking to Actors::update() --- apps/openmw/mwmechanics/actors.cpp | 68 ++++++++++++++++-------------- apps/openmw/mwmechanics/actors.hpp | 2 - apps/openmw/mwworld/player.cpp | 3 -- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index bf02a8c30..3693d70b0 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -226,7 +226,6 @@ namespace MWMechanics updateDrowning(ptr, duration); calculateNpcStatModifiers(ptr); updateEquippedLight(ptr, duration); - updateSneak(ptr); } } @@ -711,27 +710,6 @@ namespace MWMechanics } } - void Actors::updateSneak (const MWWorld::Ptr& ptr) - { - const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - if ( player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak) - && ptr != player) - { - const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - int radius = esmStore.get().find("fSneakUseDist")->getInt(); - bool seen = false; - - // am I close enough and can I see the player? - if ( (Ogre::Vector3(ptr.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) <= radius*radius) - && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr) - && MWBase::Environment::get().getWorld()->getLOS(player, ptr)) - - seen = true; - - MWBase::Environment::get().getWindowManager()->setSneakVisibility(seen); - } - } - void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration) { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); @@ -872,12 +850,12 @@ namespace MWMechanics } // AI and magic effects update - for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) + for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) { if (!iter->first.getClass().getCreatureStats(iter->first).isDead()) { updateActor(iter->first, duration); - if(iter->first.getTypeName() == typeid(ESM::NPC).name()) + if (iter->first.getTypeName() == typeid(ESM::NPC).name()) updateNpc(iter->first, duration, paused); } } @@ -887,11 +865,11 @@ namespace MWMechanics // Reaching the text keys may trigger Hit / Spellcast (and as such, particles), // so updating VFX immediately after that would just remove the particle effects instantly. // There needs to be a magic effect update in between. - for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) + for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) iter->second->updateContinuousVfx(); // Animation/movement update - for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) + for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) { if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects().get( ESM::MagicEffect::Paralyze).mMagnitude > 0) @@ -900,7 +878,7 @@ namespace MWMechanics } // Kill dead actors, update some variables - for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++) + for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++) { const MWWorld::Class &cls = MWWorld::Class::get(iter->first); CreatureStats &stats = cls.getCreatureStats(iter->first); @@ -908,7 +886,7 @@ namespace MWMechanics //KnockedOutOneFrameLogic //Used for "OnKnockedOut" command //Put here to ensure that it's run for PRECISELY one frame. - if(stats.getKnockedDown() && !stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) { //Start it for one frame if nessesary + if (stats.getKnockedDown() && !stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) { //Start it for one frame if nessesary stats.setKnockedDownOneFrame(true); } else if (stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) { //Turn off KnockedOutOneframe @@ -926,7 +904,7 @@ namespace MWMechanics } // If it's the player and God Mode is turned on, keep it alive - if(iter->first.getRefData().getHandle()=="player" && + if (iter->first.getRefData().getHandle()=="player" && MWBase::Environment::get().getWorld()->getGodModeState()) { MWMechanics::DynamicStat stat (stats.getHealth()); @@ -942,7 +920,7 @@ namespace MWMechanics // Make sure spell effects with CasterLinked flag are removed // TODO: would be nice not to do this all the time... - for(PtrControllerMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2) + for (PtrControllerMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2) { MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells(); spells.purge(iter->first.getRefData().getHandle()); @@ -967,10 +945,38 @@ namespace MWMechanics stats.setMagicEffects(MWMechanics::MagicEffects()); calculateCreatureStatModifiers(iter->first, 0); - if(cls.isEssential(iter->first)) + if (cls.isEssential(iter->first)) MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); } } + + // if player is in sneak state see if anyone detects him + const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + if (player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak)) + { + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); + const int radius = esmStore.get().find("fSneakUseDist")->getInt(); + bool detected = false; + + for (PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) + { + if (iter->first == player) // not the player + continue; + + // is the player in range and can they be detected + if ( (Ogre::Vector3(iter->first.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) <= radius*radius) + && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, iter->first) + && MWBase::Environment::get().getWorld()->getLOS(player, iter->first)) + { + detected = true; + MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); + break; + } + } + + if (!detected) + MWBase::Environment::get().getWindowManager()->setSneakVisibility(true); + } } } void Actors::restoreDynamicStats(bool sleep) diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index ddd7a47d3..f7dff1058 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -44,8 +44,6 @@ namespace MWMechanics void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration); - void updateSneak (const MWWorld::Ptr& ptr); - public: Actors(); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 1ad43e360..1f994d013 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -131,9 +131,6 @@ namespace MWWorld { MWWorld::Ptr ptr = getPlayer(); ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak); - - if(!sneak) - MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); } void Player::yaw(float yaw) From 78f76842a6a413a96245d9fe1f1812005cb5ff07 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sun, 4 May 2014 16:56:30 -0400 Subject: [PATCH 067/121] Added else statement Its still dodgy though --- apps/openmw/mwmechanics/actors.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 3693d70b0..8f6ac5274 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -976,6 +976,8 @@ namespace MWMechanics if (!detected) MWBase::Environment::get().getWindowManager()->setSneakVisibility(true); + else + MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); } } } From d4812c3af988dabe189576c24dff212fc960c733 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sun, 4 May 2014 17:54:33 -0400 Subject: [PATCH 068/121] fixed placement of else statement --- apps/openmw/mwmechanics/actors.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 8f6ac5274..4f291c36e 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -976,9 +976,9 @@ namespace MWMechanics if (!detected) MWBase::Environment::get().getWindowManager()->setSneakVisibility(true); - else - MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); } + else + MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); } } void Actors::restoreDynamicStats(bool sleep) From 475214ab627f4a77d6e73566799fc0bb3e32de62 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Mon, 5 May 2014 05:56:03 -0500 Subject: [PATCH 069/121] Implmented QSettings for loading / saving file definitions. Also renamed opencs.cfg to opencs.ini to follow Ini format standards --- CMakeLists.txt | 2 +- apps/opencs/editor.cpp | 2 +- apps/opencs/model/settings/setting.cpp | 4 +- apps/opencs/model/settings/settingmanager.cpp | 232 ++---------------- apps/opencs/model/settings/settingmanager.hpp | 21 +- apps/opencs/model/settings/usersettings.cpp | 52 ++-- apps/opencs/model/settings/usersettings.hpp | 3 + apps/opencs/view/settings/settingwindow.cpp | 2 +- apps/opencs/view/settings/view.cpp | 2 +- apps/opencs/view/settings/view.hpp | 2 + files/{opencs.cfg => opencs.conf} | 0 11 files changed, 63 insertions(+), 259 deletions(-) rename files/{opencs.cfg => opencs.conf} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd45a207c..3d5923647 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,7 +368,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg "${OpenMW_BINARY_DIR}/openmw.cfg.install") -configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg +configure_file(${OpenMW_SOURCE_DIR}/files/opencs.conf "${OpenMW_BINARY_DIR}/opencs.cfg") configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index f6370ac51..480e91e30 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -27,7 +27,7 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) setupDataFiles (config.first); - CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg"); + CSMSettings::UserSettings::instance().loadSettings ("opencs.ini"); mSettings.setModel (CSMSettings::UserSettings::instance()); ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string()); diff --git a/apps/opencs/model/settings/setting.cpp b/apps/opencs/model/settings/setting.cpp index fe15cf7f6..2ef829f86 100644 --- a/apps/opencs/model/settings/setting.cpp +++ b/apps/opencs/model/settings/setting.cpp @@ -45,7 +45,7 @@ void CSMSettings::Setting::addProxy (const Setting *setting, foreach (const QString &val, vals) list << (QStringList() << val); - mProxies [setting->page() + '.' + setting->name()] = list; + mProxies [setting->page() + '/' + setting->name()] = list; } void CSMSettings::Setting::addProxy (const Setting *setting, @@ -54,7 +54,7 @@ void CSMSettings::Setting::addProxy (const Setting *setting, if (serializable()) setProperty (Property_Serializable, false); - mProxies [setting->page() + '.' + setting->name()] = list; + mProxies [setting->page() + '/' + setting->name()] = list; } void CSMSettings::Setting::setColumnSpan (int value) diff --git a/apps/opencs/model/settings/settingmanager.cpp b/apps/opencs/model/settings/settingmanager.cpp index 36ca1ae03..e48dd6e26 100644 --- a/apps/opencs/model/settings/settingmanager.cpp +++ b/apps/opencs/model/settings/settingmanager.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "setting.hpp" #include "settingmanager.hpp" @@ -20,15 +21,6 @@ CSMSettings::SettingManager::SettingManager(QObject *parent) : } -void CSMSettings::SettingManager::dumpModel() -{ - foreach (Setting *setting, mSettings) - { - if (setting->proxyLists().isEmpty()) - continue; - } -} - CSMSettings::Setting *CSMSettings::SettingManager::createSetting (CSMSettings::SettingType typ, const QString &page, const QString &name) { @@ -36,7 +28,7 @@ CSMSettings::Setting *CSMSettings::SettingManager::createSetting if (findSetting (page, name)) { qWarning() << "Duplicate declaration encountered: " - << (name + '.' + page); + << (name + '/' + page); return 0; } @@ -49,182 +41,6 @@ CSMSettings::Setting *CSMSettings::SettingManager::createSetting return setting; } -CSMSettings::DefinitionPageMap - CSMSettings::SettingManager::readFilestream (QTextStream *stream) -{ - //regEx's for page names and keys / values - QRegExp pageRegEx ("^\\[([^]]+)\\]"); - QRegExp keyRegEx ("^([^=]+)\\s*=\\s*(.+)$"); - - QString currPage = "Unassigned"; - - DefinitionPageMap pageMap; - - if (!stream) - { - displayFileErrorMessage(mReadWriteMessage, false); - return pageMap; - } - - if (stream->atEnd()) - return pageMap; - - DefinitionMap *settingMap = new DefinitionMap(); - pageMap[currPage] = settingMap; - - while (!stream->atEnd()) - { - QString line = stream->readLine().simplified(); - - if (line.isEmpty() || line.startsWith("#")) - continue; - - //page name found - if (pageRegEx.exactMatch(line)) - { - currPage = pageRegEx.cap(1).simplified().trimmed(); - settingMap = new DefinitionMap(); - pageMap[currPage] = settingMap; - continue; - } - - //setting definition found - if ( (keyRegEx.indexIn(line) != -1)) - { - QString settingName = keyRegEx.cap(1).simplified(); - QString settingValue = keyRegEx.cap(2).simplified(); - - if (!settingMap->contains (settingName)) - settingMap->insert (settingName, new QStringList()); - - settingMap->value(settingName)->append(settingValue); - } - } - - //return empty map if no settings were ever added to - if (pageMap.size() == 1) - { - QString pageKey = pageMap.keys().at(0); - if (pageMap[pageKey]->size() == 0) - pageMap.clear(); - } - - return pageMap; -} - -bool CSMSettings::SettingManager::writeFilestream(QTextStream *stream, - const QMap &settingListMap) -{ - if (!stream) - { - displayFileErrorMessage(mReadWriteMessage, false); - return false; - } - //disabled after rolling selector class into view. Need to - //iterate views to get setting definitions before writing to file - - QStringList sectionKeys; - - foreach (const QString &key, settingListMap.keys()) - { - QStringList names = key.split('.'); - QString section = names.at(0); - - if (!sectionKeys.contains(section)) - if (!settingListMap.value(key).isEmpty()) - sectionKeys.append (section); - } - - foreach (const QString §ion, sectionKeys) - { - *stream << '[' << section << "]\n"; - foreach (const QString &key, settingListMap.keys()) - { - QStringList names = key.split('.'); - - if (names.at(0) != section) - continue; - - QStringList list = settingListMap.value(key); - - if (list.isEmpty()) - continue; - - QString name = names.at(1); - - foreach (const QString value, list) - { - if (value.isEmpty()) - continue; - - *stream << name << " = " << value << '\n'; - } - } - } - - destroyStream (stream); - return true; -} - -void CSMSettings::SettingManager::mergeSettings(DefinitionPageMap &destMap, DefinitionPageMap &srcMap) -{ - if (srcMap.isEmpty()) - return; - - foreach (const QString &pageKey, srcMap.keys()) - { - DefinitionMap *srcSetting = srcMap.value(pageKey); - //Unique Page: - //insertfrom the source map - if (!destMap.keys().contains (pageKey)) - { - destMap.insert (pageKey, srcSetting); - continue; - } - - DefinitionMap *destSetting = destMap.value(pageKey); - - //Duplicate Page: - //iterate the settings in the source and check for duplicates in the - //destination - foreach (const QString &srcKey, srcSetting->keys()) - { - //insert into destination if unique - if (!destSetting->keys().contains (srcKey)) - destSetting->insert(srcKey, srcSetting->value (srcKey)); - } - } -} - -QTextStream *CSMSettings::SettingManager::openFilestream (const QString &filePath, - bool isReadOnly) const -{ - QIODevice::OpenMode openFlags = QIODevice::Text; - - if (isReadOnly) - openFlags = QIODevice::ReadOnly | openFlags; - else - openFlags = QIODevice::ReadWrite | QIODevice::Truncate | openFlags; - - QFile *file = new QFile(filePath); - QTextStream *stream = 0; - - if (file->open(openFlags)) - stream = new QTextStream(file); - - if (stream) - stream->setCodec(QTextCodec::codecForName("UTF-8")); - - return stream; -} - -void CSMSettings::SettingManager::destroyStream(QTextStream *stream) const -{ - stream->device()->close(); - - delete stream; -} - void CSMSettings::SettingManager::displayFileErrorMessage(const QString &message, bool isReadOnly) const { @@ -242,29 +58,29 @@ void CSMSettings::SettingManager::displayFileErrorMessage(const QString &message msgBox.exec(); } -void CSMSettings::SettingManager::addDefinitions (DefinitionPageMap &pageMap) +void CSMSettings::SettingManager::addDefinitions (const QSettings *settings) { - foreach (QString pageName, pageMap.keys()) + foreach (const QString &key, settings->allKeys()) { - DefinitionMap *settingMap = pageMap.value (pageName); + QStringList names = key.split('/'); - foreach (QString settingName, (*settingMap).keys()) + Setting *setting = findSetting (names.at(0), names.at(1)); + + if (!setting) { - QStringList *values = settingMap->value (settingName); - Setting *setting = findSetting (pageName, settingName); - - if (!setting) - { - qWarning() << "Found definitions for undeclared setting " - << pageName << "." << settingName; - continue; - } - - if (values->size() == 0) - values->append (setting->defaultValues()); - - setting->setDefinedValues (*values); + qWarning() << "Found definitions for undeclared setting " + << names.at(0) << "." << names.at(1); + continue; } + + QStringList values = settings->value (key).toStringList(); + + if (values.isEmpty()) + values.append (setting->defaultValues()); + + setting->setDefinedValues (values); + + qDebug() << "added definitons " << values; } } @@ -297,7 +113,7 @@ CSMSettings::Setting *CSMSettings::SettingManager::findSetting { foreach (Setting *setting, mSettings) { - if (setting->name() == settingName) + if (settingName.isEmpty() || (setting->name() == settingName)) { if (setting->page() == pageName) return setting; @@ -305,7 +121,7 @@ CSMSettings::Setting *CSMSettings::SettingManager::findSetting } return 0; } - +/* QList CSMSettings::SettingManager::findSettings (const QString &pageName) { @@ -318,7 +134,7 @@ QList CSMSettings::SettingManager::findSettings } return settings; } - +*/ CSMSettings::SettingPageMap CSMSettings::SettingManager::settingPageMap() const { SettingPageMap pageMap; @@ -332,7 +148,7 @@ CSMSettings::SettingPageMap CSMSettings::SettingManager::settingPageMap() const void CSMSettings::SettingManager::updateUserSetting(const QString &settingKey, const QStringList &list) { - QStringList names = settingKey.split('.'); + QStringList names = settingKey.split('/'); Setting *setting = findSetting (names.at(0), names.at(1)); diff --git a/apps/opencs/model/settings/settingmanager.hpp b/apps/opencs/model/settings/settingmanager.hpp index 2efc2929f..9342c66e4 100644 --- a/apps/opencs/model/settings/settingmanager.hpp +++ b/apps/opencs/model/settings/settingmanager.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "support.hpp" #include "setting.hpp" @@ -30,7 +31,7 @@ namespace CSMSettings ///retrieve a setting object from a given page and setting name Setting *findSetting - (const QString &pageName, const QString &settingName); + (const QString &pageName, const QString &settingName = QString()); ///retrieve all settings for a specified page QList findSettings (const QString &pageName); @@ -49,28 +50,12 @@ namespace CSMSettings const QString &page, const QString &name); ///add definitions to the settings specified in the page map - void addDefinitions (DefinitionPageMap &pageMap); - - ///read setting definitions from file - DefinitionPageMap readFilestream(QTextStream *stream); - - ///write setting definitions to file - bool writeFilestream (QTextStream *stream, - const QMap &settingMap); - - ///merge PageMaps of settings when loading from multiple files - void mergeSettings (DefinitionPageMap &destMap, DefinitionPageMap &srcMap); - - QTextStream *openFilestream (const QString &filePath, - bool isReadOnly) const; - - void destroyStream(QTextStream *stream) const; + void addDefinitions (const QSettings *settings); void displayFileErrorMessage(const QString &message, bool isReadOnly) const; QList settings() const { return mSettings; } - void dumpModel(); signals: diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index a8fd752e3..bd24b7df0 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,7 @@ #include "setting.hpp" #include "support.hpp" +#include /** * Workaround for problems with whitespaces in paths in older versions of Boost library @@ -40,6 +42,8 @@ CSMSettings::UserSettings::UserSettings() assert(!mUserSettingsInstance); mUserSettingsInstance = this; + mSettings = 0; + buildSettingModelDefaults(); } @@ -293,16 +297,16 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) (mCfgMgr.getLocalPath().string().c_str()) + fileName.toUtf8(); //open user and global streams - QTextStream *userStream = openFilestream (mUserFilePath, true); - QTextStream *otherStream = openFilestream (global, true); + //QTextStream *userStream = openFilestream (mUserFilePath, true); + // QTextStream *otherStream = openFilestream (global, true); //failed stream, try for local - if (!otherStream) - otherStream = openFilestream (local, true); + // if (!otherStream) + // otherStream = openFilestream (local, true); //error condition - notify and return - if (!otherStream || !userStream) - { + // if (!otherStream || !userStream) + /* { QString message = QObject::tr("
An error was encountered loading \ user settings files.

One or several files could not \ be read. This may be caused by a missing configuration file, \ @@ -316,40 +320,34 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) displayFileErrorMessage ( message, true); return; } +*/ + //QSETTINGS TEST + qDebug() << mCfgMgr.getUserConfigPath().string().c_str() << ',' << mCfgMgr.getGlobalPath().string().c_str(); - //success condition - merge the two streams into a single map and save - DefinitionPageMap totalMap = readFilestream (userStream); - DefinitionPageMap otherMap = readFilestream(otherStream); + QSettings::setPath (QSettings::IniFormat, QSettings::UserScope, mCfgMgr.getUserConfigPath().string().c_str()); + QSettings::setPath (QSettings::IniFormat, QSettings::SystemScope, mCfgMgr.getGlobalPath().string().c_str()); - //merging other settings file in and ignore duplicate settings to - //avoid overwriting user-level settings - mergeSettings (totalMap, otherMap); + if (mSettings) + delete mSettings; - if (!totalMap.isEmpty()) - addDefinitions (totalMap); + mSettings = new QSettings + (QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this); + + addDefinitions (mSettings); } void CSMSettings::UserSettings::saveSettings (const QMap &settingMap) { - for (int i = 0; i < settings().size(); i++) - { - Setting* setting = settings().at(i); + foreach (const QString &key, settingMap.keys()) + mSettings->setValue (key, settingMap.value (key)); - QString key = setting->page() + '.' + setting->name(); - - if (!settingMap.keys().contains(key)) - continue; - - setting->setDefinedValues (settingMap.value(key)); - } - - writeFilestream (openFilestream (mUserFilePath, false), settingMap); + delete mSettings; } QString CSMSettings::UserSettings::settingValue (const QString &settingKey) { - QStringList names = settingKey.split('.'); + QStringList names = settingKey.split('/'); Setting *setting = findSetting(names.at(0), names.at(1)); diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index f0ed7af41..ade14c50c 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -18,6 +18,7 @@ namespace Files { typedef std::vector PathContainer; struct ConfigurationManager;} class QFile; +class QSettings; namespace CSMSettings { @@ -32,6 +33,8 @@ namespace CSMSettings { QString mReadOnlyMessage; QString mReadWriteMessage; + QSettings *mSettings; + public: diff --git a/apps/opencs/view/settings/settingwindow.cpp b/apps/opencs/view/settings/settingwindow.cpp index 7bd0b228e..aeb652b3b 100644 --- a/apps/opencs/view/settings/settingwindow.cpp +++ b/apps/opencs/view/settings/settingwindow.cpp @@ -57,7 +57,7 @@ void CSVSettings::SettingWindow::createConnections foreach (const QString &key, proxyMap.keys()) { - QStringList keyPair = key.split('.'); + QStringList keyPair = key.split('/'); if (keyPair.size() != 2) continue; diff --git a/apps/opencs/view/settings/view.cpp b/apps/opencs/view/settings/view.cpp index 2a70152c2..9e595478d 100644 --- a/apps/opencs/view/settings/view.cpp +++ b/apps/opencs/view/settings/view.cpp @@ -14,7 +14,7 @@ CSVSettings::View::View(CSMSettings::Setting *setting, : mDataModel(0), mParentPage (parent), mHasFixedValues (!setting->declaredValues().isEmpty()), mIsMultiValue (setting->isMultiValue()), - mViewKey (setting->page() + '.' + setting->name()), + mViewKey (setting->page() + '/' + setting->name()), mSerializable (setting->serializable()), Frame(true, setting->name(), parent) { diff --git a/apps/opencs/view/settings/view.hpp b/apps/opencs/view/settings/view.hpp index 23357e45f..4f3af9ae5 100644 --- a/apps/opencs/view/settings/view.hpp +++ b/apps/opencs/view/settings/view.hpp @@ -42,8 +42,10 @@ namespace CSVSettings ///State indicating whether the view will allow multiple values bool mIsMultiValue; + ///'pagename.settingname' form of the view's id QString mViewKey; + ///indicates whether or not the setting is written to file bool mSerializable; public: diff --git a/files/opencs.cfg b/files/opencs.conf similarity index 100% rename from files/opencs.cfg rename to files/opencs.conf From 74fa115d205b320f2d259efcd5bc54416bc18153 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Mon, 5 May 2014 06:07:41 -0500 Subject: [PATCH 070/121] fixed check for missing ini files --- apps/opencs/model/settings/settingmanager.cpp | 7 +-- apps/opencs/model/settings/usersettings.cpp | 44 ++++++++++--------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/apps/opencs/model/settings/settingmanager.cpp b/apps/opencs/model/settings/settingmanager.cpp index e48dd6e26..afb80c206 100644 --- a/apps/opencs/model/settings/settingmanager.cpp +++ b/apps/opencs/model/settings/settingmanager.cpp @@ -21,6 +21,7 @@ CSMSettings::SettingManager::SettingManager(QObject *parent) : } + CSMSettings::Setting *CSMSettings::SettingManager::createSetting (CSMSettings::SettingType typ, const QString &page, const QString &name) { @@ -113,7 +114,7 @@ CSMSettings::Setting *CSMSettings::SettingManager::findSetting { foreach (Setting *setting, mSettings) { - if (settingName.isEmpty() || (setting->name() == settingName)) + if (setting->name() == settingName) { if (setting->page() == pageName) return setting; @@ -121,7 +122,7 @@ CSMSettings::Setting *CSMSettings::SettingManager::findSetting } return 0; } -/* + QList CSMSettings::SettingManager::findSettings (const QString &pageName) { @@ -134,7 +135,7 @@ QList CSMSettings::SettingManager::findSettings } return settings; } -*/ + CSMSettings::SettingPageMap CSMSettings::SettingManager::settingPageMap() const { SettingPageMap pageMap; diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index bd24b7df0..7764cc2c2 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -288,44 +288,48 @@ CSMSettings::UserSettings::~UserSettings() void CSMSettings::UserSettings::loadSettings (const QString &fileName) { mUserFilePath = QString::fromUtf8 - (mCfgMgr.getUserConfigPath().string().c_str()) + fileName.toUtf8(); + (mCfgMgr.getUserConfigPath().string().c_str()); - QString global = QString::fromUtf8 - (mCfgMgr.getGlobalPath().string().c_str()) + fileName.toUtf8(); + QString globalFilePath = QString::fromUtf8 + (mCfgMgr.getGlobalPath().string().c_str()); - QString local = QString::fromUtf8 - (mCfgMgr.getLocalPath().string().c_str()) + fileName.toUtf8(); + QString localFilePath = QString::fromUtf8 + (mCfgMgr.getLocalPath().string().c_str()); - //open user and global streams - //QTextStream *userStream = openFilestream (mUserFilePath, true); - // QTextStream *otherStream = openFilestream (global, true); + bool isUser = QFile (mUserFilePath + fileName).exists(); + bool isSystem = QFile (globalFilePath + fileName).exists(); - //failed stream, try for local - // if (!otherStream) - // otherStream = openFilestream (local, true); + QString otherFilePath = globalFilePath; + + //test for local only if global fails (uninstalled copy) + if (!isSystem) + { + isSystem = QFile (localFilePath + fileName).exists(); + otherFilePath = localFilePath; + } //error condition - notify and return - // if (!otherStream || !userStream) - /* { + if (!isUser || !isSystem) + { QString message = QObject::tr("
An error was encountered loading \ user settings files.

One or several files could not \ be read. This may be caused by a missing configuration file, \ incorrect file permissions or a corrupted installation of \ OpenCS.
"); - message += QObject::tr("
Global filepath: ") + global; - message += QObject::tr("
Local filepath: ") + local; + message += QObject::tr("
Global filepath: ") + globalFilePath; + message += QObject::tr("
Local filepath: ") + localFilePath; message += QObject::tr("
User filepath: ") + mUserFilePath; displayFileErrorMessage ( message, true); return; } -*/ - //QSETTINGS TEST - qDebug() << mCfgMgr.getUserConfigPath().string().c_str() << ',' << mCfgMgr.getGlobalPath().string().c_str(); - QSettings::setPath (QSettings::IniFormat, QSettings::UserScope, mCfgMgr.getUserConfigPath().string().c_str()); - QSettings::setPath (QSettings::IniFormat, QSettings::SystemScope, mCfgMgr.getGlobalPath().string().c_str()); + QSettings::setPath + (QSettings::IniFormat, QSettings::UserScope, mUserFilePath); + + QSettings::setPath + (QSettings::IniFormat, QSettings::SystemScope, otherFilePath); if (mSettings) delete mSettings; From 5cba828cc9e496d00f547c6e4475b7d1b8c5e910 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Mon, 5 May 2014 06:26:00 -0500 Subject: [PATCH 071/121] Removed unneeded code from setting manager. Moved some code to user settings --- apps/opencs/model/settings/settingmanager.cpp | 68 +------------------ apps/opencs/model/settings/settingmanager.hpp | 14 ---- apps/opencs/model/settings/usersettings.cpp | 56 ++++++++++----- apps/opencs/model/settings/usersettings.hpp | 9 ++- 4 files changed, 45 insertions(+), 102 deletions(-) diff --git a/apps/opencs/model/settings/settingmanager.cpp b/apps/opencs/model/settings/settingmanager.cpp index afb80c206..b0e5cba98 100644 --- a/apps/opencs/model/settings/settingmanager.cpp +++ b/apps/opencs/model/settings/settingmanager.cpp @@ -10,17 +10,7 @@ CSMSettings::SettingManager::SettingManager(QObject *parent) : QObject(parent) -{ - mReadWriteMessage = QObject::tr("
Could not open or create file for \ - writing

Please make sure you have the right\ - permissions and try again.
"); - - mReadOnlyMessage = QObject::tr("
Could not open file for \ - reading

Please make sure you have the \ - right permissions and try again.
"); - -} - +{} CSMSettings::Setting *CSMSettings::SettingManager::createSetting (CSMSettings::SettingType typ, const QString &page, const QString &name) @@ -42,23 +32,6 @@ CSMSettings::Setting *CSMSettings::SettingManager::createSetting return setting; } -void CSMSettings::SettingManager::displayFileErrorMessage(const QString &message, - bool isReadOnly) const -{ - // File cannot be opened or created - QMessageBox msgBox; - msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - - if (!isReadOnly) - msgBox.setText (mReadWriteMessage + message); - else - msgBox.setText (message); - - msgBox.exec(); -} - void CSMSettings::SettingManager::addDefinitions (const QSettings *settings) { foreach (const QString &key, settings->allKeys()) @@ -80,35 +53,9 @@ void CSMSettings::SettingManager::addDefinitions (const QSettings *settings) values.append (setting->defaultValues()); setting->setDefinedValues (values); - - qDebug() << "added definitons " << values; } } -QList CSMSettings::SettingManager::findSettings - (const QStringList &list) -{ - QList settings; - - foreach (const QString &value, list) - { - QStringList names = value.split(".", QString::SkipEmptyParts); - - if (names.size() != 2) - continue; - - Setting *setting = findSetting (names.at(0), names.at(1)); - - if (!setting) - continue; - - settings.append (setting); - } - - return settings; -} - - CSMSettings::Setting *CSMSettings::SettingManager::findSetting (const QString &pageName, const QString &settingName) { @@ -123,19 +70,6 @@ CSMSettings::Setting *CSMSettings::SettingManager::findSetting return 0; } -QList CSMSettings::SettingManager::findSettings - (const QString &pageName) -{ - QList settings; - - foreach (Setting *setting, mSettings) - { - if (setting->page() == pageName) - settings.append (setting); - } - return settings; -} - CSMSettings::SettingPageMap CSMSettings::SettingManager::settingPageMap() const { SettingPageMap pageMap; diff --git a/apps/opencs/model/settings/settingmanager.hpp b/apps/opencs/model/settings/settingmanager.hpp index 9342c66e4..95f55106e 100644 --- a/apps/opencs/model/settings/settingmanager.hpp +++ b/apps/opencs/model/settings/settingmanager.hpp @@ -22,8 +22,6 @@ namespace CSMSettings { Q_OBJECT - QString mReadOnlyMessage; - QString mReadWriteMessage; QList mSettings; public: @@ -33,13 +31,6 @@ namespace CSMSettings Setting *findSetting (const QString &pageName, const QString &settingName = QString()); - ///retrieve all settings for a specified page - QList findSettings (const QString &pageName); - - ///retrieve all settings named in the attached list. - ///Setting names are specified in "PageName.SettingName" format. - QList findSettings (const QStringList &list); - ///Retreive a map of the settings, keyed by page name SettingPageMap settingPageMap() const; @@ -52,11 +43,6 @@ namespace CSMSettings ///add definitions to the settings specified in the page map void addDefinitions (const QSettings *settings); - void displayFileErrorMessage(const QString &message, - bool isReadOnly) const; - - QList settings() const { return mSettings; } - signals: void userSettingUpdated (const QString &, const QStringList &); diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 7764cc2c2..178104982 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -44,6 +44,14 @@ CSMSettings::UserSettings::UserSettings() mSettings = 0; + mReadWriteMessage = QObject::tr("
Could not open or create file for \ + writing

Please make sure you have the right\ + permissions and try again.
"); + + mReadOnlyMessage = QObject::tr("
Could not open file for \ + reading

Please make sure you have the \ + right permissions and try again.
"); + buildSettingModelDefaults(); } @@ -131,10 +139,10 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() * proxy slave settings, but must match any declared values the proxy * slave has, if any. *******************************************************************/ - +/* //create setting objects, specifying the basic widget type, //the page name, and the view name -/* + Setting *masterBoolean = createSetting (Type_RadioButton, section, "Master Proxy"); @@ -234,6 +242,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() slaveIntegerSpinbox->setSerializable (false); slaveDoubleSpinbox->setSerializable (false); slaveSlider->setSerializable (false); + slaveDial->setSerializable (false); slaveBoolean->setDefaultValues (QStringList() << "One" << "Three" << "Five"); @@ -285,9 +294,34 @@ CSMSettings::UserSettings::~UserSettings() mUserSettingsInstance = 0; } +void CSMSettings::UserSettings::displayFileErrorMessage + (const QString &userpath, + const QString &globalpath, + const QString &localpath) const +{ + QString message = QObject::tr("
An error was encountered loading \ + user settings files.

One or several files could not \ + be read. This may be caused by a missing configuration file, \ + incorrect file permissions or a corrupted installation of \ + OpenCS.
"); + + message += QObject::tr("
Global filepath: ") + globalpath; + message += QObject::tr("
Local filepath: ") + localpath; + message += QObject::tr("
User filepath: ") + userpath; + + QMessageBox msgBox; + + msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + + msgBox.setText (mReadWriteMessage + message); + msgBox.exec(); +} + void CSMSettings::UserSettings::loadSettings (const QString &fileName) { - mUserFilePath = QString::fromUtf8 + QString userFilePath = QString::fromUtf8 (mCfgMgr.getUserConfigPath().string().c_str()); QString globalFilePath = QString::fromUtf8 @@ -296,7 +330,7 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) QString localFilePath = QString::fromUtf8 (mCfgMgr.getLocalPath().string().c_str()); - bool isUser = QFile (mUserFilePath + fileName).exists(); + bool isUser = QFile (userFilePath + fileName).exists(); bool isSystem = QFile (globalFilePath + fileName).exists(); QString otherFilePath = globalFilePath; @@ -311,22 +345,12 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) //error condition - notify and return if (!isUser || !isSystem) { - QString message = QObject::tr("
An error was encountered loading \ - user settings files.

One or several files could not \ - be read. This may be caused by a missing configuration file, \ - incorrect file permissions or a corrupted installation of \ - OpenCS.
"); - - message += QObject::tr("
Global filepath: ") + globalFilePath; - message += QObject::tr("
Local filepath: ") + localFilePath; - message += QObject::tr("
User filepath: ") + mUserFilePath; - - displayFileErrorMessage ( message, true); + displayFileErrorMessage (userFilePath, globalFilePath, localFilePath); return; } QSettings::setPath - (QSettings::IniFormat, QSettings::UserScope, mUserFilePath); + (QSettings::IniFormat, QSettings::UserScope, userFilePath); QSettings::setPath (QSettings::IniFormat, QSettings::SystemScope, otherFilePath); diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index ade14c50c..826bb6d6b 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -28,14 +28,12 @@ namespace CSMSettings { Q_OBJECT static UserSettings *mUserSettingsInstance; - QString mUserFilePath; Files::ConfigurationManager mCfgMgr; QString mReadOnlyMessage; QString mReadWriteMessage; QSettings *mSettings; - public: /// Singleton implementation @@ -47,9 +45,6 @@ namespace CSMSettings { UserSettings (UserSettings const &); //not implemented void operator= (UserSettings const &); //not implemented - /// Writes settings to the last loaded settings file - bool writeSettings(); - /// Retrieves the settings file at all three levels (global, local and user). void loadSettings (const QString &fileName); @@ -61,6 +56,10 @@ namespace CSMSettings { private: void buildSettingModelDefaults(); + void displayFileErrorMessage(const QString &userpath, + const QString &globalpath, + const QString &localpath) const; + }; } #endif // USERSETTINGS_HPP From 536fc5e1928f00329a55e61e74a8affcdc46ba24 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 4 May 2014 18:25:41 +0200 Subject: [PATCH 072/121] Fix autosaves --- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index d2a31e8d1..6a15c8e33 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1447,7 +1447,7 @@ namespace MWGui { return !MyGUI::InputManager::getInstance().isModalAny() // TODO: remove this, once we have properly serialized the state of open windows - && (!isGuiMode() || (mGuiModes.size() == 1 && getMode() == GM_MainMenu)); + && (!isGuiMode() || (mGuiModes.size() == 1 && (getMode() == GM_MainMenu || getMode() == GM_Rest || getMode() == GM_RestBed))); } void WindowManager::playVideo(const std::string &name, bool allowSkipping) From d4492b56dbe106d824a902d2a37a568a6919c1b9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 5 May 2014 23:52:09 +0200 Subject: [PATCH 073/121] Added header file missing from CMakeLists --- apps/openmw/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 89e40c9b1..7a5283125 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -48,7 +48,7 @@ add_openmw_dir (mwscript ) add_openmw_dir (mwsound - soundmanagerimp openal_output ffmpeg_decoder + soundmanagerimp openal_output ffmpeg_decoder sound ) add_openmw_dir (mwworld From dd9117809de91d32ca49a9aacf2a44c27b590089 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 6 May 2014 00:13:31 +0200 Subject: [PATCH 074/121] Say an attack phrase when combat starts Move combat start to a helper method Added some todo comments --- apps/openmw/mwbase/mechanicsmanager.hpp | 3 +++ apps/openmw/mwmechanics/actors.cpp | 14 ++++++++------ apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 10 ++++++++++ apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 3 +++ apps/openmw/mwscript/aiextensions.cpp | 9 ++------- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index d5f9e30cd..f31241bdb 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -96,6 +96,9 @@ namespace MWBase /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) = 0; + /// Makes \a ptr fight \a target. Also shouts a combat taunt. + virtual void startCombat (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) = 0; + enum OffenseType { OT_Theft, // Taking items owned by an NPC or a faction you are not a member of diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index bf02a8c30..c3957f72f 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -206,8 +206,7 @@ namespace MWMechanics if (LOS) { - creatureStats.getAiSequence().stack(AiCombat(MWBase::Environment::get().getWorld()->getPlayerPtr()), ptr); - creatureStats.setHostile(true); + MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player); } } } @@ -784,15 +783,16 @@ namespace MWMechanics if (ptr.getClass().isClass(ptr, "Guard")) creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr); else - creatureStats.getAiSequence().stack(AiCombat(player), ptr); - creatureStats.setHostile(true); + { + MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player); + } } } // if I didn't report a crime was I attacked? + // TODO: this is incorrect, getAttacked also triggers if attacked by other non-player actors. else if (creatureStats.getAttacked() && !creatureStats.isHostile()) { - creatureStats.getAiSequence().stack(AiCombat(player), ptr); - creatureStats.setHostile(true); + MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player); } } } @@ -1073,6 +1073,8 @@ namespace MWMechanics if(!stats.isDead() && stats.getAiSequence().getTypeId() == AiPackage::TypeIdCombat) { MWMechanics::AiCombat* package = static_cast(stats.getAiSequence().getActivePackage()); + // TODO: This is wrong! It's comparing Ref IDs with Ogre handles. The only case where this (coincidentally) works is the player. + // possibly applies to other code using getTargetId. if(package->getTargetId() == actor.getCellRef().mRefID) list.push_front(*iter); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 396e710be..e69f39a19 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -13,6 +13,8 @@ #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" +#include "../mwmechanics/aicombat.hpp" + #include #include "spellcasting.hpp" @@ -1007,6 +1009,14 @@ namespace MWMechanics return (roll >= target); } + void MechanicsManager::startCombat(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target) + { + MWBase::Environment::get().getDialogueManager()->say(ptr, "attack"); + ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(MWMechanics::AiCombat(target), ptr); + if (target == MWBase::Environment::get().getWorld()->getPlayerPtr()) + ptr.getClass().getCreatureStats(ptr).setHostile(true); + } + void MechanicsManager::getObjectsInRange(const Ogre::Vector3 &position, float radius, std::vector &objects) { mActors.getObjectsInRange(position, radius, objects); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 1c9bab25e..dcd12ee14 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -105,6 +105,9 @@ namespace MWMechanics /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer); + /// Makes \a ptr fight \a target. Also shouts a combat taunt. + virtual void startCombat (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target); + /** * @brief Commit a crime. If any actors witness the crime and report it, * reportCrime will be called automatically. diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 43da111bf..e53b53e58 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -16,7 +16,6 @@ #include "../mwmechanics/aifollow.hpp" #include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aiwander.hpp" -#include "../mwmechanics/aicombat.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -435,12 +434,8 @@ namespace MWScript std::string targetID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); - - - creatureStats.setHostile(true); - creatureStats.getAiSequence().stack( - MWMechanics::AiCombat(MWBase::Environment::get().getWorld()->getPtr(targetID, true) ), actor); + MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr(targetID, true); + MWBase::Environment::get().getMechanicsManager()->startCombat(actor, target); } }; From 492620c8cf0f4436d31f46061bd6f37c82391b91 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 6 May 2014 09:39:39 +0200 Subject: [PATCH 075/121] handle exceptions thrown during loading and report them to the user --- apps/opencs/model/doc/documentmanager.cpp | 8 +-- apps/opencs/model/doc/documentmanager.hpp | 8 +-- apps/opencs/view/doc/loader.cpp | 63 +++++++++++++++++------ apps/opencs/view/doc/loader.hpp | 12 +++++ apps/opencs/view/doc/viewmanager.cpp | 4 ++ 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index d44da15c5..fe6aaef27 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -59,7 +59,7 @@ void CSMDoc::DocumentManager::addDocument (const std::vector::iterator iter = std::find (mDocuments.begin(), mDocuments.end(), document); @@ -86,6 +86,8 @@ void CSMDoc::DocumentManager::documentLoaded (Document *document) void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::string& error) { -// emit loadingStopped (document, false, error); - removeDocument (document); + emit loadingStopped (document, false, error); + + if (error.empty()) // do not remove the document yet, if we have an error + removeDocument (document); } \ No newline at end of file diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index d834d85d4..de4a5e94b 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -43,9 +43,6 @@ namespace CSMDoc ///< \param new_ Do not load the last content file in \a files and instead create in an /// appropriate way. - void removeDocument (Document *document); - ///< Emits the lastDocumentDeleted signal, if applicable. - void setResourceDir (const boost::filesystem::path& parResDir); private: @@ -61,6 +58,11 @@ namespace CSMDoc ///< Document load has been interrupted either because of a call to abortLoading /// or a problem during loading). In the former case error will be an empty string. + public slots: + + void removeDocument (CSMDoc::Document *document); + ///< Emits the lastDocumentDeleted signal, if applicable. + signals: void documentAdded (CSMDoc::Document *document); diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 3b5890479..1b2ca8ad5 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -13,11 +13,11 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) { event->ignore(); - emit cancel (mDocument); + cancel(); } CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) -: mDocument (document) +: mDocument (document), mAborted (false) { setWindowTitle (("Opening " + document->getSavePath().filename().string()).c_str()); @@ -52,10 +52,16 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) mRecordProgress->setTextVisible (true); mRecordProgress->setValue (0); - QDialogButtonBox *buttonBox = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, - this); + // error message + mError = new QLabel (this); + mError->setWordWrap (true); - layout->addWidget (buttonBox); + layout->addWidget (mError); + + // buttons + mButtons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this); + + layout->addWidget (mButtons); setLayout (layout); @@ -63,7 +69,7 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) show(); - connect (buttonBox, SIGNAL (rejected()), this, SLOT (cancel())); + connect (mButtons, SIGNAL (rejected()), this, SLOT (cancel())); } void CSVDoc::LoadingDocument::nextStage (const std::string& name, int steps) @@ -73,10 +79,9 @@ void CSVDoc::LoadingDocument::nextStage (const std::string& name, int steps) mFileProgress->setValue (mFileProgress->value()+1); mRecordProgress->setValue (0); - mRecordProgress->setMaximum (steps); + mRecordProgress->setMaximum (steps>0 ? steps : 1); } - void CSVDoc::LoadingDocument::nextRecord() { int value = mRecordProgress->value()+1; @@ -85,9 +90,22 @@ void CSVDoc::LoadingDocument::nextRecord() mRecordProgress->setValue (value); } +void CSVDoc::LoadingDocument::abort (const std::string& error) +{ + mAborted = true; + mError->setText (QString::fromUtf8 (("Loading failed: " + error).c_str())); + mButtons->setStandardButtons (QDialogButtonBox::Close); +} + void CSVDoc::LoadingDocument::cancel() { - emit cancel (mDocument); + if (!mAborted) + emit cancel (mDocument); + else + { + emit close (mDocument); + deleteLater(); + } } @@ -107,21 +125,32 @@ void CSVDoc::Loader::add (CSMDoc::Document *document) connect (loading, SIGNAL (cancel (CSMDoc::Document *)), this, SIGNAL (cancel (CSMDoc::Document *))); + connect (loading, SIGNAL (close (CSMDoc::Document *)), + this, SIGNAL (close (CSMDoc::Document *))); } void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed, const std::string& error) { + std::map::iterator iter = mDocuments.begin(); + + for (; iter!=mDocuments.end(); ++iter) + if (iter->first==document) + break; + + if (iter==mDocuments.end()) + return; + if (completed || error.empty()) { - for (std::map::iterator iter (mDocuments.begin()); - iter!=mDocuments.end(); ++iter) - if (iter->first==document) - { - delete iter->second; - mDocuments.erase (iter); - break; - } + delete iter->second; + mDocuments.erase (iter); + } + else if (!completed && !error.empty()) + { + iter->second->abort (error); + // Leave the window open for now (wait for the user to close it) + mDocuments.erase (iter); } } diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index d1c740011..ece071755 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -9,6 +9,7 @@ class QLabel; class QProgressBar; +class QDialogButtonBox; namespace CSMDoc { @@ -25,6 +26,9 @@ namespace CSVDoc QLabel *mFile; QProgressBar *mFileProgress; QProgressBar *mRecordProgress; + bool mAborted; + QDialogButtonBox *mButtons; + QLabel *mError; private: @@ -38,6 +42,8 @@ namespace CSVDoc void nextRecord(); + void abort (const std::string& error); + private slots: void cancel(); @@ -45,6 +51,10 @@ namespace CSVDoc signals: void cancel (CSMDoc::Document *document); + ///< Stop loading process. + + void close (CSMDoc::Document *document); + ///< Close stopped loading process. }; class Loader : public QObject @@ -63,6 +73,8 @@ namespace CSVDoc void cancel (CSMDoc::Document *document); + void close (CSMDoc::Document *document); + public slots: void add (CSMDoc::Document *document); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index b8971a296..816eff791 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -103,6 +103,10 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) connect ( &mLoader, SIGNAL (cancel (CSMDoc::Document *)), &mDocumentManager, SIGNAL (cancelLoading (CSMDoc::Document *))); + + connect ( + &mLoader, SIGNAL (close (CSMDoc::Document *)), + &mDocumentManager, SLOT (removeDocument (CSMDoc::Document *))); } CSVDoc::ViewManager::~ViewManager() From a30d816982f7f8e700661c888c1879bad1adb618 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 6 May 2014 11:44:20 +0200 Subject: [PATCH 076/121] fixed a mixup in CSMTools::Tools constructor/destructor --- apps/opencs/model/tools/tools.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index d3d8f5fad..8104cc3e6 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -87,13 +87,14 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0) { - for (std::map::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter) - delete iter->second; } CSMTools::Tools::~Tools() { delete mVerifier; + + for (std::map::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter) + delete iter->second; } CSMWorld::UniversalId CSMTools::Tools::runVerifier() From 79b13a74a36ce9a0214d43a9d7c7777124902e81 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 6 May 2014 07:33:32 -0500 Subject: [PATCH 077/121] Incorporated SettingManager into UserSettings class. Other minor code changes to support QSettings integration --- apps/opencs/CMakeLists.txt | 1 - apps/opencs/editor.cpp | 5 - apps/opencs/model/settings/settingmanager.cpp | 93 -------------- apps/opencs/model/settings/settingmanager.hpp | 55 -------- apps/opencs/model/settings/usersettings.cpp | 117 ++++++++++++++++-- apps/opencs/model/settings/usersettings.hpp | 36 +++++- apps/opencs/view/doc/view.cpp | 4 +- apps/opencs/view/settings/settingwindow.hpp | 6 +- .../opencs/view/world/datadisplaydelegate.cpp | 9 +- .../opencs/view/world/datadisplaydelegate.hpp | 3 +- apps/opencs/view/world/idtypedelegate.cpp | 2 +- .../view/world/recordstatusdelegate.cpp | 2 +- 12 files changed, 155 insertions(+), 178 deletions(-) delete mode 100644 apps/opencs/model/settings/settingmanager.cpp delete mode 100644 apps/opencs/model/settings/settingmanager.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 38075ac53..22db97206 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -106,7 +106,6 @@ opencs_units_noqt (view/settings opencs_units (model/settings usersettings - settingmanager setting connector ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 480e91e30..f6a13f4f6 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -124,11 +124,6 @@ std::pair > CS::Editor::readConfi QString path = QString::fromUtf8 (iter->string().c_str()); mFileDialog.addFiles(path); } -/* - //load the settings into the userSettings instance. - const QString settingFileName = "opencs.cfg"; - CSMSettings::UserSettings::instance().loadSettings(settingFileName); -*/ return std::make_pair (dataDirs, variables["fallback-archive"].as >()); } diff --git a/apps/opencs/model/settings/settingmanager.cpp b/apps/opencs/model/settings/settingmanager.cpp deleted file mode 100644 index b0e5cba98..000000000 --- a/apps/opencs/model/settings/settingmanager.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "setting.hpp" -#include "settingmanager.hpp" - -CSMSettings::SettingManager::SettingManager(QObject *parent) : - QObject(parent) -{} - -CSMSettings::Setting *CSMSettings::SettingManager::createSetting - (CSMSettings::SettingType typ, const QString &page, const QString &name) -{ - //get list of all settings for the current setting name - if (findSetting (page, name)) - { - qWarning() << "Duplicate declaration encountered: " - << (name + '/' + page); - return 0; - } - - Setting *setting = new Setting (typ, name, page); - - - //add declaration to the model - mSettings.append (setting); - - return setting; -} - -void CSMSettings::SettingManager::addDefinitions (const QSettings *settings) -{ - foreach (const QString &key, settings->allKeys()) - { - QStringList names = key.split('/'); - - Setting *setting = findSetting (names.at(0), names.at(1)); - - if (!setting) - { - qWarning() << "Found definitions for undeclared setting " - << names.at(0) << "." << names.at(1); - continue; - } - - QStringList values = settings->value (key).toStringList(); - - if (values.isEmpty()) - values.append (setting->defaultValues()); - - setting->setDefinedValues (values); - } -} - -CSMSettings::Setting *CSMSettings::SettingManager::findSetting - (const QString &pageName, const QString &settingName) -{ - foreach (Setting *setting, mSettings) - { - if (setting->name() == settingName) - { - if (setting->page() == pageName) - return setting; - } - } - return 0; -} - -CSMSettings::SettingPageMap CSMSettings::SettingManager::settingPageMap() const -{ - SettingPageMap pageMap; - - foreach (Setting *setting, mSettings) - pageMap[setting->page()].append (setting); - - return pageMap; -} - -void CSMSettings::SettingManager::updateUserSetting(const QString &settingKey, - const QStringList &list) -{ - QStringList names = settingKey.split('/'); - - Setting *setting = findSetting (names.at(0), names.at(1)); - - setting->setDefinedValues (list); - - emit userSettingUpdated (settingKey, list); -} diff --git a/apps/opencs/model/settings/settingmanager.hpp b/apps/opencs/model/settings/settingmanager.hpp deleted file mode 100644 index 95f55106e..000000000 --- a/apps/opencs/model/settings/settingmanager.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef CSMSETTINGS_SETTINGMANAGER_HPP -#define CSMSETTINGS_SETTINGMANAGER_HPP - -#include -#include -#include -#include -#include - -#include "support.hpp" -#include "setting.hpp" - -namespace CSMSettings -{ - - typedef QMap DefinitionMap; - typedef QMap DefinitionPageMap; - - typedef QMap > SettingPageMap; - - class SettingManager : public QObject - { - Q_OBJECT - - QList mSettings; - - public: - explicit SettingManager(QObject *parent = 0); - - ///retrieve a setting object from a given page and setting name - Setting *findSetting - (const QString &pageName, const QString &settingName = QString()); - - ///Retreive a map of the settings, keyed by page name - SettingPageMap settingPageMap() const; - - protected: - - ///add a new setting to the model and return it - Setting *createSetting (CSMSettings::SettingType typ, - const QString &page, const QString &name); - - ///add definitions to the settings specified in the page map - void addDefinitions (const QSettings *settings); - - signals: - - void userSettingUpdated (const QString &, const QStringList &); - - public slots: - - void updateUserSetting (const QString &, const QStringList &); - }; -} -#endif // CSMSETTINGS_SETTINGMANAGER_HPP diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 178104982..7e65cb270 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -42,7 +42,7 @@ CSMSettings::UserSettings::UserSettings() assert(!mUserSettingsInstance); mUserSettingsInstance = this; - mSettings = 0; + mSettingDefinitions = 0; mReadWriteMessage = QObject::tr("
Could not open or create file for \ writing

Please make sure you have the right\ @@ -55,6 +55,31 @@ CSMSettings::UserSettings::UserSettings() buildSettingModelDefaults(); } +void CSMSettings::UserSettings::addDefinitions () +{ + foreach (const QString &key, mSettingDefinitions->allKeys()) + { + QStringList names = key.split('/'); + + Setting *setting = findSetting (names.at(0), names.at(1)); + + if (!setting) + { + qWarning() << "Found definitions for undeclared setting " + << names.at(0) << "/" << names.at(1); + removeSetting (names.at(0), names.at(1)); + continue; + } + + QStringList values = mSettingDefinitions->value (key).toStringList(); + + if (values.isEmpty()) + values.append (setting->defaultValues()); + + setting->setDefinedValues (values); + } +} + void CSMSettings::UserSettings::buildSettingModelDefaults() { QString section = "Window Size"; @@ -355,22 +380,19 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) QSettings::setPath (QSettings::IniFormat, QSettings::SystemScope, otherFilePath); - if (mSettings) - delete mSettings; - - mSettings = new QSettings + mSettingDefinitions = new QSettings (QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this); - addDefinitions (mSettings); + addDefinitions(); } void CSMSettings::UserSettings::saveSettings (const QMap &settingMap) { foreach (const QString &key, settingMap.keys()) - mSettings->setValue (key, settingMap.value (key)); + mSettingDefinitions->setValue (key, settingMap.value (key)); - delete mSettings; + mSettingDefinitions->sync(); } QString CSMSettings::UserSettings::settingValue (const QString &settingKey) @@ -392,3 +414,82 @@ CSMSettings::UserSettings& CSMSettings::UserSettings::instance() assert(mUserSettingsInstance); return *mUserSettingsInstance; } + +void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey, + const QStringList &list) +{ + QStringList names = settingKey.split('/'); + + Setting *setting = findSetting (names.at(0), names.at(1)); + + setting->setDefinedValues (list); + + emit userSettingUpdated (settingKey, list); +} + +CSMSettings::Setting *CSMSettings::UserSettings::findSetting + (const QString &pageName, const QString &settingName) +{ + foreach (Setting *setting, mSettings) + { + if (setting->name() == settingName) + { + if (setting->page() == pageName) + return setting; + } + } + return 0; +} + +void CSMSettings::UserSettings::removeSetting + (const QString &pageName, const QString &settingName) +{ + if (mSettings.isEmpty()) + return; + + QList ::iterator removeIterator = mSettings.begin(); + + while (removeIterator != mSettings.end()) + { + if ((*removeIterator)->name() == settingName) + { + if ((*removeIterator)->page() == pageName) + { + mSettings.erase (removeIterator); + break; + } + } + removeIterator++; + } +} + + +CSMSettings::SettingPageMap CSMSettings::UserSettings::settingPageMap() const +{ + SettingPageMap pageMap; + + foreach (Setting *setting, mSettings) + pageMap[setting->page()].append (setting); + + return pageMap; +} + +CSMSettings::Setting *CSMSettings::UserSettings::createSetting + (CSMSettings::SettingType typ, const QString &page, const QString &name) +{ + //get list of all settings for the current setting name + if (findSetting (page, name)) + { + qWarning() << "Duplicate declaration encountered: " + << (name + '/' + page); + return 0; + } + + Setting *setting = new Setting (typ, name, page); + + + //add declaration to the model + mSettings.append (setting); + + return setting; +} diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 826bb6d6b..509c06bfa 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -7,8 +7,7 @@ #include #include - -#include "settingmanager.hpp" +#include "support.hpp" #ifndef Q_MOC_RUN #include @@ -22,7 +21,10 @@ class QSettings; namespace CSMSettings { - class UserSettings: public SettingManager + class Setting; + typedef QMap > SettingPageMap; + + class UserSettings: public QObject { Q_OBJECT @@ -32,7 +34,8 @@ namespace CSMSettings { QString mReadOnlyMessage; QString mReadWriteMessage; - QSettings *mSettings; + QSettings *mSettingDefinitions; + QList mSettings; public: @@ -53,13 +56,38 @@ namespace CSMSettings { QString settingValue (const QString &settingKey); + ///retrieve a setting object from a given page and setting name + Setting *findSetting + (const QString &pageName, const QString &settingName = QString()); + + ///remove a setting from the list + void removeSetting + (const QString &pageName, const QString &settingName); + + ///Retreive a map of the settings, keyed by page name + SettingPageMap settingPageMap() const; + private: + ///add definitions to the settings specified in the page map + void addDefinitions(); + void buildSettingModelDefaults(); void displayFileErrorMessage(const QString &userpath, const QString &globalpath, const QString &localpath) const; + ///add a new setting to the model and return it + Setting *createSetting (CSMSettings::SettingType typ, + const QString &page, const QString &name); + + signals: + + void userSettingUpdated (const QString &, const QStringList &); + + public slots: + + void updateUserSetting (const QString &, const QStringList &); }; } #endif // USERSETTINGS_HPP diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index acb272553..95ab6ca27 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -236,10 +236,10 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to mViewTotal (totalViews) { QString width = CSMSettings::UserSettings::instance().settingValue - ("Window Size.Width"); + ("Window Size/Width"); QString height = CSMSettings::UserSettings::instance().settingValue - ("Window Size.Height"); + ("Window Size/Height"); resize (width.toInt(), height.toInt()); diff --git a/apps/opencs/view/settings/settingwindow.hpp b/apps/opencs/view/settings/settingwindow.hpp index 35ae4c068..8354ced7f 100644 --- a/apps/opencs/view/settings/settingwindow.hpp +++ b/apps/opencs/view/settings/settingwindow.hpp @@ -8,7 +8,7 @@ namespace CSMSettings { class Setting; - class SettingManager; + class UserSettings; } namespace CSVSettings { @@ -23,13 +23,13 @@ namespace CSVSettings { Q_OBJECT PageList mPages; - CSMSettings::SettingManager *mModel; + CSMSettings::UserSettings *mModel; public: explicit SettingWindow(QWidget *parent = 0); View *findView (const QString &pageName, const QString &setting); - void setModel (CSMSettings::SettingManager &model) { mModel = &model; } + void setModel (CSMSettings::UserSettings &model) { mModel = &model; } protected: diff --git a/apps/opencs/view/world/datadisplaydelegate.cpp b/apps/opencs/view/world/datadisplaydelegate.cpp index c3ec68b52..31ec18d52 100644 --- a/apps/opencs/view/world/datadisplaydelegate.cpp +++ b/apps/opencs/view/world/datadisplaydelegate.cpp @@ -7,18 +7,19 @@ CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values, const IconList &icons, QUndoStack &undoStack, - const QString &settingKey, + const QString &pageName, + const QString &settingName, QObject *parent) : EnumDelegate (values, undoStack, parent), mDisplayMode (Mode_TextOnly), mIcons (icons), mIconSize (QSize(16, 16)), mIconLeftOffset(3), - mTextLeftOffset(8), mSettingKey (settingKey) + mTextLeftOffset(8), mSettingKey (pageName + '/' + settingName) { mTextAlignment.setAlignment (Qt::AlignLeft | Qt::AlignVCenter ); buildPixmaps(); QString value = - CSMSettings::UserSettings::instance().settingValue (settingKey); + CSMSettings::UserSettings::instance().settingValue (mSettingKey); updateDisplayMode(value); } @@ -140,7 +141,7 @@ CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate (Q QObject *parent) const { - return new DataDisplayDelegate (mValues, mIcons, undoStack, "", parent); + return new DataDisplayDelegate (mValues, mIcons, undoStack, "", "", parent); } diff --git a/apps/opencs/view/world/datadisplaydelegate.hpp b/apps/opencs/view/world/datadisplaydelegate.hpp index f11c4a2b9..ef453c58f 100755 --- a/apps/opencs/view/world/datadisplaydelegate.hpp +++ b/apps/opencs/view/world/datadisplaydelegate.hpp @@ -41,7 +41,8 @@ namespace CSVWorld explicit DataDisplayDelegate (const ValueList & values, const IconList & icons, QUndoStack& undoStack, - const QString &settingKey, + const QString &pageName, + const QString &settingName, QObject *parent); ~DataDisplayDelegate(); diff --git a/apps/opencs/view/world/idtypedelegate.cpp b/apps/opencs/view/world/idtypedelegate.cpp index 485ca57ac..6b4d442f3 100755 --- a/apps/opencs/view/world/idtypedelegate.cpp +++ b/apps/opencs/view/world/idtypedelegate.cpp @@ -5,7 +5,7 @@ CSVWorld::IdTypeDelegate::IdTypeDelegate (const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent) : DataDisplayDelegate (values, icons, undoStack, - "Display Format.Referenceable ID Type Display", + "Display Format", "Referenceable ID Type Display", parent) {} diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index 206adbdd7..4fe7031ce 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -11,7 +11,7 @@ CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values, const IconList & icons, QUndoStack &undoStack, QObject *parent) : DataDisplayDelegate (values, icons, undoStack, - "Display Format.Record Status Display", + "Display Format", "Record Status Display", parent) {} From a17cb1f389757bfac403a16fef7c2efb5b2c7cc2 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 6 May 2014 07:33:32 -0500 Subject: [PATCH 078/121] Fixed opencs.ini formatting --- CMakeLists.txt | 4 +- apps/opencs/CMakeLists.txt | 1 - apps/opencs/editor.cpp | 5 - apps/opencs/model/settings/settingmanager.cpp | 93 -------------- apps/opencs/model/settings/settingmanager.hpp | 55 -------- apps/opencs/model/settings/usersettings.cpp | 117 ++++++++++++++++-- apps/opencs/model/settings/usersettings.hpp | 36 +++++- apps/opencs/view/doc/view.cpp | 4 +- apps/opencs/view/settings/settingwindow.hpp | 6 +- .../opencs/view/world/datadisplaydelegate.cpp | 9 +- .../opencs/view/world/datadisplaydelegate.hpp | 3 +- apps/opencs/view/world/idtypedelegate.cpp | 2 +- .../view/world/recordstatusdelegate.cpp | 2 +- files/opencs.conf | 5 - files/opencs.ini | 7 ++ 15 files changed, 164 insertions(+), 185 deletions(-) delete mode 100644 apps/opencs/model/settings/settingmanager.cpp delete mode 100644 apps/opencs/model/settings/settingmanager.hpp delete mode 100644 files/opencs.conf create mode 100644 files/opencs.ini diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d5923647..ff0916086 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,8 +368,8 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg "${OpenMW_BINARY_DIR}/openmw.cfg.install") -configure_file(${OpenMW_SOURCE_DIR}/files/opencs.conf - "${OpenMW_BINARY_DIR}/opencs.cfg") +configure_file(${OpenMW_SOURCE_DIR}/files/opencs.ini + "${OpenMW_BINARY_DIR}/opencs.ini") configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters "${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 38075ac53..22db97206 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -106,7 +106,6 @@ opencs_units_noqt (view/settings opencs_units (model/settings usersettings - settingmanager setting connector ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 480e91e30..f6a13f4f6 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -124,11 +124,6 @@ std::pair > CS::Editor::readConfi QString path = QString::fromUtf8 (iter->string().c_str()); mFileDialog.addFiles(path); } -/* - //load the settings into the userSettings instance. - const QString settingFileName = "opencs.cfg"; - CSMSettings::UserSettings::instance().loadSettings(settingFileName); -*/ return std::make_pair (dataDirs, variables["fallback-archive"].as >()); } diff --git a/apps/opencs/model/settings/settingmanager.cpp b/apps/opencs/model/settings/settingmanager.cpp deleted file mode 100644 index b0e5cba98..000000000 --- a/apps/opencs/model/settings/settingmanager.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "setting.hpp" -#include "settingmanager.hpp" - -CSMSettings::SettingManager::SettingManager(QObject *parent) : - QObject(parent) -{} - -CSMSettings::Setting *CSMSettings::SettingManager::createSetting - (CSMSettings::SettingType typ, const QString &page, const QString &name) -{ - //get list of all settings for the current setting name - if (findSetting (page, name)) - { - qWarning() << "Duplicate declaration encountered: " - << (name + '/' + page); - return 0; - } - - Setting *setting = new Setting (typ, name, page); - - - //add declaration to the model - mSettings.append (setting); - - return setting; -} - -void CSMSettings::SettingManager::addDefinitions (const QSettings *settings) -{ - foreach (const QString &key, settings->allKeys()) - { - QStringList names = key.split('/'); - - Setting *setting = findSetting (names.at(0), names.at(1)); - - if (!setting) - { - qWarning() << "Found definitions for undeclared setting " - << names.at(0) << "." << names.at(1); - continue; - } - - QStringList values = settings->value (key).toStringList(); - - if (values.isEmpty()) - values.append (setting->defaultValues()); - - setting->setDefinedValues (values); - } -} - -CSMSettings::Setting *CSMSettings::SettingManager::findSetting - (const QString &pageName, const QString &settingName) -{ - foreach (Setting *setting, mSettings) - { - if (setting->name() == settingName) - { - if (setting->page() == pageName) - return setting; - } - } - return 0; -} - -CSMSettings::SettingPageMap CSMSettings::SettingManager::settingPageMap() const -{ - SettingPageMap pageMap; - - foreach (Setting *setting, mSettings) - pageMap[setting->page()].append (setting); - - return pageMap; -} - -void CSMSettings::SettingManager::updateUserSetting(const QString &settingKey, - const QStringList &list) -{ - QStringList names = settingKey.split('/'); - - Setting *setting = findSetting (names.at(0), names.at(1)); - - setting->setDefinedValues (list); - - emit userSettingUpdated (settingKey, list); -} diff --git a/apps/opencs/model/settings/settingmanager.hpp b/apps/opencs/model/settings/settingmanager.hpp deleted file mode 100644 index 95f55106e..000000000 --- a/apps/opencs/model/settings/settingmanager.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef CSMSETTINGS_SETTINGMANAGER_HPP -#define CSMSETTINGS_SETTINGMANAGER_HPP - -#include -#include -#include -#include -#include - -#include "support.hpp" -#include "setting.hpp" - -namespace CSMSettings -{ - - typedef QMap DefinitionMap; - typedef QMap DefinitionPageMap; - - typedef QMap > SettingPageMap; - - class SettingManager : public QObject - { - Q_OBJECT - - QList mSettings; - - public: - explicit SettingManager(QObject *parent = 0); - - ///retrieve a setting object from a given page and setting name - Setting *findSetting - (const QString &pageName, const QString &settingName = QString()); - - ///Retreive a map of the settings, keyed by page name - SettingPageMap settingPageMap() const; - - protected: - - ///add a new setting to the model and return it - Setting *createSetting (CSMSettings::SettingType typ, - const QString &page, const QString &name); - - ///add definitions to the settings specified in the page map - void addDefinitions (const QSettings *settings); - - signals: - - void userSettingUpdated (const QString &, const QStringList &); - - public slots: - - void updateUserSetting (const QString &, const QStringList &); - }; -} -#endif // CSMSETTINGS_SETTINGMANAGER_HPP diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 178104982..7e65cb270 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -42,7 +42,7 @@ CSMSettings::UserSettings::UserSettings() assert(!mUserSettingsInstance); mUserSettingsInstance = this; - mSettings = 0; + mSettingDefinitions = 0; mReadWriteMessage = QObject::tr("
Could not open or create file for \ writing

Please make sure you have the right\ @@ -55,6 +55,31 @@ CSMSettings::UserSettings::UserSettings() buildSettingModelDefaults(); } +void CSMSettings::UserSettings::addDefinitions () +{ + foreach (const QString &key, mSettingDefinitions->allKeys()) + { + QStringList names = key.split('/'); + + Setting *setting = findSetting (names.at(0), names.at(1)); + + if (!setting) + { + qWarning() << "Found definitions for undeclared setting " + << names.at(0) << "/" << names.at(1); + removeSetting (names.at(0), names.at(1)); + continue; + } + + QStringList values = mSettingDefinitions->value (key).toStringList(); + + if (values.isEmpty()) + values.append (setting->defaultValues()); + + setting->setDefinedValues (values); + } +} + void CSMSettings::UserSettings::buildSettingModelDefaults() { QString section = "Window Size"; @@ -355,22 +380,19 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) QSettings::setPath (QSettings::IniFormat, QSettings::SystemScope, otherFilePath); - if (mSettings) - delete mSettings; - - mSettings = new QSettings + mSettingDefinitions = new QSettings (QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this); - addDefinitions (mSettings); + addDefinitions(); } void CSMSettings::UserSettings::saveSettings (const QMap &settingMap) { foreach (const QString &key, settingMap.keys()) - mSettings->setValue (key, settingMap.value (key)); + mSettingDefinitions->setValue (key, settingMap.value (key)); - delete mSettings; + mSettingDefinitions->sync(); } QString CSMSettings::UserSettings::settingValue (const QString &settingKey) @@ -392,3 +414,82 @@ CSMSettings::UserSettings& CSMSettings::UserSettings::instance() assert(mUserSettingsInstance); return *mUserSettingsInstance; } + +void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey, + const QStringList &list) +{ + QStringList names = settingKey.split('/'); + + Setting *setting = findSetting (names.at(0), names.at(1)); + + setting->setDefinedValues (list); + + emit userSettingUpdated (settingKey, list); +} + +CSMSettings::Setting *CSMSettings::UserSettings::findSetting + (const QString &pageName, const QString &settingName) +{ + foreach (Setting *setting, mSettings) + { + if (setting->name() == settingName) + { + if (setting->page() == pageName) + return setting; + } + } + return 0; +} + +void CSMSettings::UserSettings::removeSetting + (const QString &pageName, const QString &settingName) +{ + if (mSettings.isEmpty()) + return; + + QList ::iterator removeIterator = mSettings.begin(); + + while (removeIterator != mSettings.end()) + { + if ((*removeIterator)->name() == settingName) + { + if ((*removeIterator)->page() == pageName) + { + mSettings.erase (removeIterator); + break; + } + } + removeIterator++; + } +} + + +CSMSettings::SettingPageMap CSMSettings::UserSettings::settingPageMap() const +{ + SettingPageMap pageMap; + + foreach (Setting *setting, mSettings) + pageMap[setting->page()].append (setting); + + return pageMap; +} + +CSMSettings::Setting *CSMSettings::UserSettings::createSetting + (CSMSettings::SettingType typ, const QString &page, const QString &name) +{ + //get list of all settings for the current setting name + if (findSetting (page, name)) + { + qWarning() << "Duplicate declaration encountered: " + << (name + '/' + page); + return 0; + } + + Setting *setting = new Setting (typ, name, page); + + + //add declaration to the model + mSettings.append (setting); + + return setting; +} diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 826bb6d6b..509c06bfa 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -7,8 +7,7 @@ #include #include - -#include "settingmanager.hpp" +#include "support.hpp" #ifndef Q_MOC_RUN #include @@ -22,7 +21,10 @@ class QSettings; namespace CSMSettings { - class UserSettings: public SettingManager + class Setting; + typedef QMap > SettingPageMap; + + class UserSettings: public QObject { Q_OBJECT @@ -32,7 +34,8 @@ namespace CSMSettings { QString mReadOnlyMessage; QString mReadWriteMessage; - QSettings *mSettings; + QSettings *mSettingDefinitions; + QList mSettings; public: @@ -53,13 +56,38 @@ namespace CSMSettings { QString settingValue (const QString &settingKey); + ///retrieve a setting object from a given page and setting name + Setting *findSetting + (const QString &pageName, const QString &settingName = QString()); + + ///remove a setting from the list + void removeSetting + (const QString &pageName, const QString &settingName); + + ///Retreive a map of the settings, keyed by page name + SettingPageMap settingPageMap() const; + private: + ///add definitions to the settings specified in the page map + void addDefinitions(); + void buildSettingModelDefaults(); void displayFileErrorMessage(const QString &userpath, const QString &globalpath, const QString &localpath) const; + ///add a new setting to the model and return it + Setting *createSetting (CSMSettings::SettingType typ, + const QString &page, const QString &name); + + signals: + + void userSettingUpdated (const QString &, const QStringList &); + + public slots: + + void updateUserSetting (const QString &, const QStringList &); }; } #endif // USERSETTINGS_HPP diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index acb272553..95ab6ca27 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -236,10 +236,10 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to mViewTotal (totalViews) { QString width = CSMSettings::UserSettings::instance().settingValue - ("Window Size.Width"); + ("Window Size/Width"); QString height = CSMSettings::UserSettings::instance().settingValue - ("Window Size.Height"); + ("Window Size/Height"); resize (width.toInt(), height.toInt()); diff --git a/apps/opencs/view/settings/settingwindow.hpp b/apps/opencs/view/settings/settingwindow.hpp index 35ae4c068..8354ced7f 100644 --- a/apps/opencs/view/settings/settingwindow.hpp +++ b/apps/opencs/view/settings/settingwindow.hpp @@ -8,7 +8,7 @@ namespace CSMSettings { class Setting; - class SettingManager; + class UserSettings; } namespace CSVSettings { @@ -23,13 +23,13 @@ namespace CSVSettings { Q_OBJECT PageList mPages; - CSMSettings::SettingManager *mModel; + CSMSettings::UserSettings *mModel; public: explicit SettingWindow(QWidget *parent = 0); View *findView (const QString &pageName, const QString &setting); - void setModel (CSMSettings::SettingManager &model) { mModel = &model; } + void setModel (CSMSettings::UserSettings &model) { mModel = &model; } protected: diff --git a/apps/opencs/view/world/datadisplaydelegate.cpp b/apps/opencs/view/world/datadisplaydelegate.cpp index c3ec68b52..31ec18d52 100644 --- a/apps/opencs/view/world/datadisplaydelegate.cpp +++ b/apps/opencs/view/world/datadisplaydelegate.cpp @@ -7,18 +7,19 @@ CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values, const IconList &icons, QUndoStack &undoStack, - const QString &settingKey, + const QString &pageName, + const QString &settingName, QObject *parent) : EnumDelegate (values, undoStack, parent), mDisplayMode (Mode_TextOnly), mIcons (icons), mIconSize (QSize(16, 16)), mIconLeftOffset(3), - mTextLeftOffset(8), mSettingKey (settingKey) + mTextLeftOffset(8), mSettingKey (pageName + '/' + settingName) { mTextAlignment.setAlignment (Qt::AlignLeft | Qt::AlignVCenter ); buildPixmaps(); QString value = - CSMSettings::UserSettings::instance().settingValue (settingKey); + CSMSettings::UserSettings::instance().settingValue (mSettingKey); updateDisplayMode(value); } @@ -140,7 +141,7 @@ CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate (Q QObject *parent) const { - return new DataDisplayDelegate (mValues, mIcons, undoStack, "", parent); + return new DataDisplayDelegate (mValues, mIcons, undoStack, "", "", parent); } diff --git a/apps/opencs/view/world/datadisplaydelegate.hpp b/apps/opencs/view/world/datadisplaydelegate.hpp index f11c4a2b9..ef453c58f 100755 --- a/apps/opencs/view/world/datadisplaydelegate.hpp +++ b/apps/opencs/view/world/datadisplaydelegate.hpp @@ -41,7 +41,8 @@ namespace CSVWorld explicit DataDisplayDelegate (const ValueList & values, const IconList & icons, QUndoStack& undoStack, - const QString &settingKey, + const QString &pageName, + const QString &settingName, QObject *parent); ~DataDisplayDelegate(); diff --git a/apps/opencs/view/world/idtypedelegate.cpp b/apps/opencs/view/world/idtypedelegate.cpp index 485ca57ac..6b4d442f3 100755 --- a/apps/opencs/view/world/idtypedelegate.cpp +++ b/apps/opencs/view/world/idtypedelegate.cpp @@ -5,7 +5,7 @@ CSVWorld::IdTypeDelegate::IdTypeDelegate (const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent) : DataDisplayDelegate (values, icons, undoStack, - "Display Format.Referenceable ID Type Display", + "Display Format", "Referenceable ID Type Display", parent) {} diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index 206adbdd7..4fe7031ce 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -11,7 +11,7 @@ CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values, const IconList & icons, QUndoStack &undoStack, QObject *parent) : DataDisplayDelegate (values, icons, undoStack, - "Display Format.Record Status Display", + "Display Format", "Record Status Display", parent) {} diff --git a/files/opencs.conf b/files/opencs.conf deleted file mode 100644 index 3faac7c8e..000000000 --- a/files/opencs.conf +++ /dev/null @@ -1,5 +0,0 @@ -[Editor] -Record Status Display = Icon and Text -[Window Size] -Width = 640 -Height = 480 diff --git a/files/opencs.ini b/files/opencs.ini new file mode 100644 index 000000000..065f11a88 --- /dev/null +++ b/files/opencs.ini @@ -0,0 +1,7 @@ +[Display%20Format] +Record%20Status%20Display=Icon Only +Referenceable%20ID%20Type%20Display=Text Only + +[Window%20Size] +Height=900 +Width=1440 From d2beb814e75a59e7200e39888c6a008847ab69aa Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 6 May 2014 18:05:53 +0200 Subject: [PATCH 079/121] Remove superfluous attack phrases (already done by startCombat) --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index e69f39a19..dc04f92d4 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -885,8 +885,6 @@ namespace MWMechanics // TODO: Add more messages if (type == OT_Theft) MWBase::Environment::get().getDialogueManager()->say(*it1, "thief"); - else if (type == OT_Assault) - MWBase::Environment::get().getDialogueManager()->say(*it1, "attack"); // Will other witnesses paticipate in crime if ( it1->getClass().getCreatureStats(*it1).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm From 1c8c26072dc74d916000dafe4fd589b1158009a6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 6 May 2014 18:23:17 +0200 Subject: [PATCH 080/121] Crime and self defense fixes - NPCs should still shout messages such as "thief" even if they did not report the crime - Fixed self defense for NPCs (they no longer attack the player when they were attacked by a non-player actor) - Fixed self defense for creatures (Fixes #1203) --- apps/openmw/mwclass/creature.cpp | 6 +++ apps/openmw/mwclass/npc.cpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 6 --- apps/openmw/mwmechanics/aisequence.hpp | 1 + .../mwmechanics/mechanicsmanagerimp.cpp | 37 +++++++++++++------ 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 94238e6d5..4c6ab1c75 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -337,6 +337,12 @@ namespace MWClass { // NOTE: 'object' and/or 'attacker' may be empty. + getCreatureStats(ptr).setAttacked(true); + + // Self defense + if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() < 80) + MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker); + if(!successful) { // TODO: Handle HitAttemptOnMe script function diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 5222eac44..6a96c955f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -621,7 +621,7 @@ namespace MWClass // NOTE: 'object' and/or 'attacker' may be empty. // Attacking peaceful NPCs is a crime - if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) + if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); getCreatureStats(ptr).setAttacked(true); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index c3957f72f..295f00d21 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -788,12 +788,6 @@ namespace MWMechanics } } } - // if I didn't report a crime was I attacked? - // TODO: this is incorrect, getAttacked also triggers if attacked by other non-player actors. - else if (creatureStats.getAttacked() && !creatureStats.isHostile()) - { - MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player); - } } } diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp index 614eb4154..37e0c7f17 100644 --- a/apps/openmw/mwmechanics/aisequence.hpp +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -64,6 +64,7 @@ namespace MWMechanics void stack (const AiPackage& package, const MWWorld::Ptr& actor); ///< Add \a package to the front of the sequence (suspends current package) + /// @param actor The actor that owns this AiSequence void queue (const AiPackage& package); ///< Add \a package to the end of the sequence (executed after all other packages have been diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index dc04f92d4..5381af8da 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -854,27 +854,45 @@ namespace MWMechanics // Innocent until proven guilty bool reported = false; - // Find all the NPCs within the alarm radius + // Find all the actors within the alarm radius std::vector neighbors; mActors.getObjectsInRange(Ogre::Vector3(ptr.getRefData().getPosition().pos), esmStore.get().find("fAlarmRadius")->getInt(), neighbors); - // Find an actor who witnessed the crime + int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId(); + + // Find actors who witnessed the crime for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { - if ( *it == ptr - || !it->getClass().isNpc()) continue; // not the player and is an NPC + if (*it == ptr) continue; // not the player // Was the crime seen? - if ( ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) || - type == OT_Assault ) + if (MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) { + // TODO: Add more messages + if (type == OT_Theft) + MWBase::Environment::get().getDialogueManager()->say(*it, "thief"); + + if (*it == victim) + { + // Self-defense + // The victim is aware of the criminal/assailant. If being assaulted, fight back now + // (regardless of whether the assault is reported or not) + // This applies to both NPCs and creatures + + // ... except if this is a guard: then the player is given a chance to pay a fine / go to jail instead + if (type == OT_Assault && !ptr.getClass().isClass(ptr, "guard")) + MWBase::Environment::get().getMechanicsManager()->startCombat(victim, ptr); + } + + // Crime reporting only applies to NPCs + if (!it->getClass().isNpc()) + continue; // Will the witness report the crime? if (it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm) { reported = true; - int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId(); // Tell everyone, including yourself for (std::vector::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1) @@ -882,10 +900,6 @@ namespace MWMechanics if ( *it1 == ptr || !it1->getClass().isNpc()) continue; // not the player and is an NPC - // TODO: Add more messages - if (type == OT_Theft) - MWBase::Environment::get().getDialogueManager()->say(*it1, "thief"); - // Will other witnesses paticipate in crime if ( it1->getClass().getCreatureStats(*it1).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm || type == OT_Assault ) @@ -896,7 +910,6 @@ namespace MWMechanics // Mark as Alarmed for dialogue it1->getClass().getCreatureStats(*it1).setAlarmed(true); } - break; // Someone saw the crime and everyone has been told } } } From 8fb96e1be32817ca506b084fe5611eb54effeb78 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 6 May 2014 19:22:45 -0500 Subject: [PATCH 081/121] Removed error code for missing opencs.ini files. --- apps/opencs/model/settings/usersettings.cpp | 8 ++++---- apps/opencs/model/settings/usersettings.hpp | 3 --- apps/opencs/view/settings/dialog.cpp | 1 + 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 7e65cb270..e26b1de5c 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -318,7 +318,7 @@ CSMSettings::UserSettings::~UserSettings() { mUserSettingsInstance = 0; } - +/* void CSMSettings::UserSettings::displayFileErrorMessage (const QString &userpath, const QString &globalpath, @@ -343,7 +343,7 @@ void CSMSettings::UserSettings::displayFileErrorMessage msgBox.setText (mReadWriteMessage + message); msgBox.exec(); } - +*/ void CSMSettings::UserSettings::loadSettings (const QString &fileName) { QString userFilePath = QString::fromUtf8 @@ -366,14 +366,14 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) isSystem = QFile (localFilePath + fileName).exists(); otherFilePath = localFilePath; } - +/* //error condition - notify and return if (!isUser || !isSystem) { displayFileErrorMessage (userFilePath, globalFilePath, localFilePath); return; } - +*/ QSettings::setPath (QSettings::IniFormat, QSettings::UserScope, userFilePath); diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 509c06bfa..7bb15e598 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -73,9 +73,6 @@ namespace CSMSettings { void addDefinitions(); void buildSettingModelDefaults(); - void displayFileErrorMessage(const QString &userpath, - const QString &globalpath, - const QString &localpath) const; ///add a new setting to the model and return it Setting *createSetting (CSMSettings::SettingType typ, diff --git a/apps/opencs/view/settings/dialog.cpp b/apps/opencs/view/settings/dialog.cpp index 3ed4d3b09..32fc7a46a 100644 --- a/apps/opencs/view/settings/dialog.cpp +++ b/apps/opencs/view/settings/dialog.cpp @@ -123,6 +123,7 @@ void CSVSettings::Dialog::show() { if (pages().isEmpty()) buildPages(); + QPoint screenCenter = QApplication::desktop()->screenGeometry().center(); move (screenCenter - geometry().center()); From e47e3de3d2b1cf4a42feac8c85af9b8a0545114b Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 6 May 2014 21:58:50 -0500 Subject: [PATCH 082/121] Removed unneeded includes, cleaned up code, added comments --- apps/opencs/model/settings/connector.hpp | 18 +++++- apps/opencs/model/settings/setting.hpp | 16 +++-- apps/opencs/model/settings/support.hpp | 34 +++------- apps/opencs/model/settings/usersettings.cpp | 64 ++----------------- apps/opencs/model/settings/usersettings.hpp | 4 +- apps/opencs/view/settings/dialog.cpp | 13 ---- apps/opencs/view/settings/dialog.hpp | 1 - apps/opencs/view/settings/frame.hpp | 2 + apps/opencs/view/settings/page.hpp | 2 +- apps/opencs/view/settings/rangeview.cpp | 3 - apps/opencs/view/settings/rangeview.hpp | 6 ++ .../view/settings/resizeablestackedwidget.hpp | 2 + apps/opencs/view/settings/settingwindow.hpp | 8 +++ apps/opencs/view/settings/spinbox.cpp | 3 +- apps/opencs/view/settings/spinbox.hpp | 11 +++- apps/opencs/view/settings/textview.hpp | 1 + apps/opencs/view/settings/view.cpp | 21 +++--- apps/opencs/view/settings/view.hpp | 5 -- 18 files changed, 76 insertions(+), 138 deletions(-) diff --git a/apps/opencs/model/settings/connector.hpp b/apps/opencs/model/settings/connector.hpp index da4c36d44..aaf9936d5 100644 --- a/apps/opencs/model/settings/connector.hpp +++ b/apps/opencs/model/settings/connector.hpp @@ -20,34 +20,46 @@ namespace CSMSettings { CSVSettings::View *mMasterView; - //map using the view pointer as a key to it's index value + ///map using the view pointer as a key to it's index value QList mSlaveViews; - //list of proxy values for each master value. - //value list order is indexed to the master value index. + ///list of proxy values for each master value. + ///value list order is indexed to the master value index. QMap < QString, QList > mProxyListMap; public: explicit Connector(CSVSettings::View *master, QObject *parent = 0); + ///Set the view which acts as a proxy for other setting views void setMasterView (CSVSettings::View *view); + + ///Add a view to be updated / update to the master void addSlaveView (CSVSettings::View *view, QList &masterProxyValues); private: + ///loosely matches lists of proxy values across registered slaves + ///against a proxy value list for a given master value bool proxyListsMatch (const QList &list1, const QList &list2) const; + ///loosely matches two string lists bool stringListsMatch (const QStringList &list1, const QStringList &list2) const; + ///retrieves current values of registered slave views QList getSlaveViewValues() const; public slots: + ///updates slave views with proxy values associated with current + ///master value void slotUpdateSlaves() const; + + ///updates master value associated with the currently selected + ///slave values, if applicable. void slotUpdateMaster() const; }; } diff --git a/apps/opencs/model/settings/setting.hpp b/apps/opencs/model/settings/setting.hpp index cf5dd2a06..89d6cc2c4 100644 --- a/apps/opencs/model/settings/setting.hpp +++ b/apps/opencs/model/settings/setting.hpp @@ -7,11 +7,17 @@ namespace CSMSettings { - //Maps setting id ("page.name") to a list of corresponding proxy values. - //Order of proxy value stringlists corresponds to order of master proxy's - //values in it's declared value list + //QString is the setting id in the form of "page/name" + //QList is a list of stringlists of proxy values. + //Order is important! Proxy stringlists are matched against + //master values by their position in the QList. typedef QMap > ProxyValueMap; + ///Setting class is the interface for the User Settings. It contains + ///a great deal of boiler plate to provide the core API functions, as + ///well as the property() functions which use enumeration to be iterable. + ///This makes the Setting class capable of being manipulated by script. + ///See CSMSettings::support.hpp for enumerations / string values. class Setting { QList mProperties; @@ -19,10 +25,6 @@ namespace CSMSettings bool mIsEditorSetting; - //QString is the setting id in the form of "page.name" - //QList is a list of stringlists of proxy values. - //Order is important! Proxy stringlists are matched against - //master values by their position in the QList. ProxyValueMap mProxies; public: diff --git a/apps/opencs/model/settings/support.hpp b/apps/opencs/model/settings/support.hpp index d65de2b91..229e293b8 100644 --- a/apps/opencs/model/settings/support.hpp +++ b/apps/opencs/model/settings/support.hpp @@ -7,22 +7,10 @@ #include #include -//Typedefs -namespace CSMSettings -{ - // Definition / Declaration model typedefs - // "Pair" = Setting name and specific data - // "ListItem" = Page name and associated setting pair - - typedef QPair StringPair; - typedef QPair StringListPair; - typedef QList StringListPairs; - -} - //Enums namespace CSMSettings { + ///Enumerated properties for scripting enum SettingProperty { Property_Name = 0, @@ -55,6 +43,7 @@ namespace CSMSettings Property_Proxies = 25 }; + ///Basic setting widget types. enum SettingType { /* @@ -82,16 +71,11 @@ namespace CSMSettings Type_Undefined = 40 }; - enum MergeMethod - { - Merge_Accept, - Merge_Ignore, - Merge_Overwrite - }; } namespace CSVSettings { + ///Categorical view types which encompass the setting widget types enum ViewType { ViewType_Boolean = 0, @@ -100,18 +84,12 @@ namespace CSVSettings ViewType_Text = 3, ViewType_Undefined = 4 }; - - enum Alignment - { - Align_Left = Qt::AlignLeft, - Align_Center = Qt::AlignHCenter, - Align_Right = Qt::AlignRight - }; } namespace CSMSettings { + ///used to construct default settings in the Setting class struct PropertyDefaultValues { int id; @@ -119,6 +97,9 @@ namespace CSMSettings QVariant value; }; + ///strings which correspond to setting values. These strings represent + ///the script language keywords which would be used to declare setting + ///views for 3rd party addons const QString sPropertyNames[] = { "name", "page", "setting_type", "is_multi_value", @@ -129,6 +110,7 @@ namespace CSMSettings "defaults", "declarations", "definitions", "proxies" }; + ///Default values for a setting. Used in setting creation. const QString sPropertyDefaults[] = { "", //name diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index e26b1de5c..8d71dbe82 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -1,16 +1,7 @@ #include "usersettings.hpp" -#include -#include -#include -#include -#include -#include -#include #include - #include -#include #include #include @@ -44,14 +35,6 @@ CSMSettings::UserSettings::UserSettings() mSettingDefinitions = 0; - mReadWriteMessage = QObject::tr("
Could not open or create file for \ - writing

Please make sure you have the right\ - permissions and try again.
"); - - mReadOnlyMessage = QObject::tr("
Could not open file for \ - reading

Please make sure you have the \ - right permissions and try again.
"); - buildSettingModelDefaults(); } @@ -318,32 +301,7 @@ CSMSettings::UserSettings::~UserSettings() { mUserSettingsInstance = 0; } -/* -void CSMSettings::UserSettings::displayFileErrorMessage - (const QString &userpath, - const QString &globalpath, - const QString &localpath) const -{ - QString message = QObject::tr("
An error was encountered loading \ - user settings files.

One or several files could not \ - be read. This may be caused by a missing configuration file, \ - incorrect file permissions or a corrupted installation of \ - OpenCS.
"); - message += QObject::tr("
Global filepath: ") + globalpath; - message += QObject::tr("
Local filepath: ") + localpath; - message += QObject::tr("
User filepath: ") + userpath; - - QMessageBox msgBox; - - msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - - msgBox.setText (mReadWriteMessage + message); - msgBox.exec(); -} -*/ void CSMSettings::UserSettings::loadSettings (const QString &fileName) { QString userFilePath = QString::fromUtf8 @@ -352,28 +310,16 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) QString globalFilePath = QString::fromUtf8 (mCfgMgr.getGlobalPath().string().c_str()); - QString localFilePath = QString::fromUtf8 - (mCfgMgr.getLocalPath().string().c_str()); - - bool isUser = QFile (userFilePath + fileName).exists(); - bool isSystem = QFile (globalFilePath + fileName).exists(); - QString otherFilePath = globalFilePath; //test for local only if global fails (uninstalled copy) - if (!isSystem) + if (!QFile (globalFilePath + fileName).exists()) { - isSystem = QFile (localFilePath + fileName).exists(); - otherFilePath = localFilePath; + //if global is invalid, use the local path + otherFilePath = QString::fromUtf8 + (mCfgMgr.getLocalPath().string().c_str()); } -/* - //error condition - notify and return - if (!isUser || !isSystem) - { - displayFileErrorMessage (userFilePath, globalFilePath, localFilePath); - return; - } -*/ + QSettings::setPath (QSettings::IniFormat, QSettings::UserScope, userFilePath); diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 7bb15e598..3ac348760 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -1,7 +1,7 @@ #ifndef USERSETTINGS_HPP #define USERSETTINGS_HPP -#include +#include #include #include #include @@ -32,8 +32,6 @@ namespace CSMSettings { static UserSettings *mUserSettingsInstance; Files::ConfigurationManager mCfgMgr; - QString mReadOnlyMessage; - QString mReadWriteMessage; QSettings *mSettingDefinitions; QList mSettings; diff --git a/apps/opencs/view/settings/dialog.cpp b/apps/opencs/view/settings/dialog.cpp index 32fc7a46a..4e7b08aff 100644 --- a/apps/opencs/view/settings/dialog.cpp +++ b/apps/opencs/view/settings/dialog.cpp @@ -76,22 +76,9 @@ void CSVSettings::Dialog::buildPages() mStackedWidget->addWidget (&dynamic_cast(*(page))); } - addDebugPage(); - resize (mStackedWidget->sizeHint()); } -void CSVSettings::Dialog::addDebugPage() -{ - /* - QTreeView *tree = new QTreeView(); - - //tree->setModel( &CSMSettings::UserSettings::instance().model() ); - - mStackedWidget->addWidget(tree); - new QListWidgetItem ("Standard Item Model", mPageListWidget);*/ -} - void CSVSettings::Dialog::buildPageListWidget (QWidget *centralWidget) { mPageListWidget = new QListWidget (centralWidget); diff --git a/apps/opencs/view/settings/dialog.hpp b/apps/opencs/view/settings/dialog.hpp index 0cfd415ac..b0e12c461 100644 --- a/apps/opencs/view/settings/dialog.hpp +++ b/apps/opencs/view/settings/dialog.hpp @@ -41,7 +41,6 @@ namespace CSVSettings { void buildPages(); void buildPageListWidget (QWidget *centralWidget); void buildStackedWidget (QWidget *centralWidget); - void addDebugPage(); public slots: diff --git a/apps/opencs/view/settings/frame.hpp b/apps/opencs/view/settings/frame.hpp index 2b52dfd1f..bbb92f34f 100644 --- a/apps/opencs/view/settings/frame.hpp +++ b/apps/opencs/view/settings/frame.hpp @@ -44,11 +44,13 @@ namespace CSVSettings void setHLayout() { mIsHorizontal = true; } void setVLayout() { mIsHorizontal = false; } + ///show / hide widgets (when stacked widget page changes) void showWidgets(); void hideWidgets(); private: + ///functions which return the index for the next layout row / column int getNextColumn() const; int getNextRow() const; diff --git a/apps/opencs/view/settings/page.hpp b/apps/opencs/view/settings/page.hpp index 7f24f6a62..877d4bef8 100644 --- a/apps/opencs/view/settings/page.hpp +++ b/apps/opencs/view/settings/page.hpp @@ -1,7 +1,6 @@ #ifndef CSVSETTINGS_PAGE_HPP #define CSVSETTINGS_PAGE_HPP -#include #include #include #include @@ -40,6 +39,7 @@ namespace CSVSettings ///and returns it. View *findView (const QString &page, const QString &setting) const; + ///returns the list of views associated with the page const QList &views () const { return mViews; } private: diff --git a/apps/opencs/view/settings/rangeview.cpp b/apps/opencs/view/settings/rangeview.cpp index b2701c7bf..8ae6caca0 100644 --- a/apps/opencs/view/settings/rangeview.cpp +++ b/apps/opencs/view/settings/rangeview.cpp @@ -1,6 +1,3 @@ -#include -#include -#include #include #include #include diff --git a/apps/opencs/view/settings/rangeview.hpp b/apps/opencs/view/settings/rangeview.hpp index e8d6df88e..2ab343f1f 100644 --- a/apps/opencs/view/settings/rangeview.hpp +++ b/apps/opencs/view/settings/rangeview.hpp @@ -21,13 +21,19 @@ namespace CSVSettings Page *parent); protected: + + ///virtual function called through View void updateView (bool signalUpdate = true) const; + ///construct a slider-based view void buildSlider (CSMSettings::Setting *setting); + + ///construct a spinbox-based view void buildSpinBox (CSMSettings::Setting *setting); private slots: + ///responds to valueChanged signals void slotUpdateView (int value); void slotUpdateView (double value); diff --git a/apps/opencs/view/settings/resizeablestackedwidget.hpp b/apps/opencs/view/settings/resizeablestackedwidget.hpp index 5e894d8df..2d0c71a23 100644 --- a/apps/opencs/view/settings/resizeablestackedwidget.hpp +++ b/apps/opencs/view/settings/resizeablestackedwidget.hpp @@ -14,8 +14,10 @@ namespace CSVSettings public: explicit ResizeableStackedWidget(QWidget *parent = 0); + ///add a widget to the stacked widget void addWidget(QWidget* pWidget); + ///called whenever the stacked widget page is changed void changePage (int, int); }; } diff --git a/apps/opencs/view/settings/settingwindow.hpp b/apps/opencs/view/settings/settingwindow.hpp index 8354ced7f..071f1b45e 100644 --- a/apps/opencs/view/settings/settingwindow.hpp +++ b/apps/opencs/view/settings/settingwindow.hpp @@ -28,20 +28,28 @@ namespace CSVSettings { public: explicit SettingWindow(QWidget *parent = 0); + ///retrieve a reference to a view based on it's page and setting name View *findView (const QString &pageName, const QString &setting); + + ///set the model the view uses (instance of UserSettings) void setModel (CSMSettings::UserSettings &model) { mModel = &model; } protected: virtual void closeEvent (QCloseEvent *event); + ///construct the pages to be displayed in the dialog void createPages(); + ///return the list of constructed pages const PageList &pages() const { return mPages; } + ///save settings from the GUI to file void saveSettings(); private: + + ///create connections between settings (used for proxy settings) void createConnections (const QList &list); }; } diff --git a/apps/opencs/view/settings/spinbox.cpp b/apps/opencs/view/settings/spinbox.cpp index bfb166370..4b1447f8f 100644 --- a/apps/opencs/view/settings/spinbox.cpp +++ b/apps/opencs/view/settings/spinbox.cpp @@ -1,6 +1,5 @@ #include "spinbox.hpp" -#include #include CSVSettings::SpinBox::SpinBox(QWidget *parent) @@ -14,7 +13,7 @@ QString CSVSettings::SpinBox::textFromValue(int val) const if (mValueList.isEmpty()) return QVariant (val).toString(); - QString value = ""; + QString value; if (val < mValueList.size()) value = mValueList.at (val); diff --git a/apps/opencs/view/settings/spinbox.hpp b/apps/opencs/view/settings/spinbox.hpp index f8e59fa05..e887e8c93 100644 --- a/apps/opencs/view/settings/spinbox.hpp +++ b/apps/opencs/view/settings/spinbox.hpp @@ -16,15 +16,22 @@ namespace CSVSettings public: explicit SpinBox(QWidget *parent = 0); - void setObjectName (const QString &name); - + ///set the value displayed in the spin box void setValue (const QString &value); + + ///set the stringlist that's used as a list of pre-defined values + ///to be displayed as the user scrolls void setValueList (const QStringList &list); + + ///returns the pre-defined value list. const QStringList &valueList() const { return mValueList; } protected: + ///converts an index value to corresponding text to be displayed QString textFromValue (int val) const; + + ///converts a text value to a corresponding index int valueFromText (const QString &text) const; }; } diff --git a/apps/opencs/view/settings/textview.hpp b/apps/opencs/view/settings/textview.hpp index c485e7fcf..f4cd03d2f 100644 --- a/apps/opencs/view/settings/textview.hpp +++ b/apps/opencs/view/settings/textview.hpp @@ -20,6 +20,7 @@ namespace CSVSettings protected: + /// virtual function called through View void updateView (bool signalUpdate = true) const; protected slots: diff --git a/apps/opencs/view/settings/view.cpp b/apps/opencs/view/settings/view.cpp index 9e595478d..c3b33cf84 100644 --- a/apps/opencs/view/settings/view.cpp +++ b/apps/opencs/view/settings/view.cpp @@ -1,7 +1,8 @@ -#include -#include +#include #include #include +#include +#include #include "view.hpp" #include "../../model/settings/support.hpp" @@ -42,24 +43,22 @@ void CSVSettings::View::buildModel (const CSMSettings::Setting *setting) void CSVSettings::View::buildFixedValueModel (const QStringList &values) { + //fixed value models are simple string list models, since they are read-only mDataModel = new QStringListModel (values, this); } void CSVSettings::View::buildUpdatableValueModel (const QStringList &values) { + //updateable models are standard item models because they support + //replacing entire columns QList itemList; foreach (const QString &value, values) itemList.append (new QStandardItem(value)); -// QSortFilterProxyModel *filter = new QSortFilterProxyModel (this); QStandardItemModel *model = new QStandardItemModel (this); model->appendColumn (itemList); -// filter->setSourceModel (model); - /* filter->setFilterRegExp ("*"); - filter->setFilterKeyColumn (0); - filter->setFilterRole (Qt::DisplayRole);*/ mDataModel = model; } @@ -151,9 +150,6 @@ void CSVSettings::View::setSelectedValues (const QStringList &list, } select (selection); - //push changes to model side - - //update the view if the selection was set from the model side, not by the //user if (doViewUpdate) @@ -192,7 +188,6 @@ bool CSVSettings::View::stringListsMatch ( QList CSVSettings::View::toStandardItemList (const QStringList &list) const { - QList itemList; foreach (const QString &value, list) @@ -212,12 +207,12 @@ QString CSVSettings::View::value (int row) const if (row > -1 && row < mDataModel->rowCount()) return mDataModel->data (mDataModel->index(row, 0)).toString(); - return ""; + return QString(); } int CSVSettings::View::widgetWidth(int characterCount) const { - QString widthToken = QString().fill ('P', characterCount); + QString widthToken = QString().fill ('m', characterCount); QFontMetrics fm (QApplication::font()); return (fm.width (widthToken)); diff --git a/apps/opencs/view/settings/view.hpp b/apps/opencs/view/settings/view.hpp index 4f3af9ae5..5106d8d90 100644 --- a/apps/opencs/view/settings/view.hpp +++ b/apps/opencs/view/settings/view.hpp @@ -11,8 +11,6 @@ class QGroupBox; class QStringList; class QStandardItem; class QItemSelection; -class QStringListModel; -class QStandardItemModel; class QAbstractItemModel; class QItemSelectionModel; @@ -52,9 +50,6 @@ namespace CSVSettings explicit View (CSMSettings::Setting *setting, Page *parent); - ///Physical frame in which the view UI is contained - void addViewWidget (QWidget *widget, int row = -1, int col = -1) const; - ///Returns the index / row of the passed value, -1 if not found. int currentIndex () const; From 224f5cf7db31532b6acf7b6467b47563de80b10c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 7 May 2014 19:14:04 +0200 Subject: [PATCH 083/121] updated changelog --- readme.txt | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/readme.txt b/readme.txt index a054626dd..44f15fbcf 100644 --- a/readme.txt +++ b/readme.txt @@ -96,6 +96,86 @@ Allowed options: CHANGELOG +0.30.0 + +Bug #416: Extreme shaking can occur during cell transitions while moving +Bug #1003: Province Cyrodiil: Ogre Exception in Stirk +Bug #1071: Crash when given a non-existent content file +Bug #1080: OpenMW allows resting/using a bed while in combat +Bug #1097: Wrong punishment for stealing in Census and Excise Office at the start of a new game +Bug #1098: Unlocked evidence chests should get locked after new evidence is put into them +Bug #1099: NPCs that you attacked still fight you after you went to jail/paid your fine +Bug #1100: Taking items from a corpse is considered stealing +Bug #1126: Some creatures can't get close enough to attack +Bug #1144: Killed creatures seem to die again each time player transitions indoors/outdoors +Bug #1181: loading a saved game does not reset the player control status +Bug #1185: Collision issues in Addamasartus +Bug #1187: Athyn Sarethi mission, rescuing varvur sarethi from the doesnt end the mission +Bug #1189: Crash when entering interior cell "Gnisis, Arvs-Drelen" +Bug #1191: Picking up papers without inventory in new game +Bug #1195: NPCs do not equip torches in certain interiors +Bug #1197: mouse wheel makes things scroll too fast +Bug #1200: door blocked by monsters +Bug #1201: item's magical charges are only refreshed when they are used +Bug #1203: Scribs do not defend themselves +Bug #1204: creatures life is not empty when they are dead +Bug #1205: armor experience does not progress when hits are taken +Bug #1206: blood particules always red. Undeads and mechanicals should have a different one. +Bug #1209: Tarhiel never falls +Bug #1210: journal adding script is ran again after having saved/loaded +Bug #1224: Names of custom classes are not properly handled in save games +Bug #1227: Editor: Fixed case handling for broken localised versions of Morrowind.esm +Bug #1235: Indoors walk stutter +Bug #1236: Aborting intro movie brings up the menu +Bug #1239: NPCs get stuck when walking past each other +Bug #1240: BTB - Settings 14.1 and Health Bar. +Bug #1241: BTB - Character and Khajiit Prejudice +Bug #1248: GUI Weapon icon is changed to hand-to-hand after save load +Bug #1254: Guild ranks do not show in dialogue +Bug #1255: When opening a container and selecting "Take All", the screen flashes blue +Bug #1260: Level Up menu doesn't show image when using a custom class +Bug #1265: Quit Menu Has Misaligned Buttons +Bug #1270: Active weapon icon is not updated when weapon is repaired +Bug #1271: NPC Stuck in hovering "Jumping" animation +Bug #1272: Crash when attempting to load Big City esm file. +Bug #1276: Editor: Dropping a region into the filter of a cell subview fails +Bug #1286: Dialogue topic list clips with window frame +Bug #1291: Saved game: store faction membership +Bug #1293: Pluginless Khajiit Head Pack by ashiraniir makes OpenMW close. +Bug #1294: Pasting in console adds text to end, not at cursor +Bug #1295: Conversation loop when asking about "specific place" in Vivec +Bug #1296: Caius doesn't leave at start of quest "Mehra Milo and the Lost Prophecies" +Bug #1297: Saved game: map markers +Bug #1302: ring_keley script causes vector::_M_range_check exception +Bug #1309: Bug on "You violated the law" dialog +Feature #50: Ranged Combat +Feature #58: Sneaking Skill +Feature #73: Crime and Punishment +Feature #135: Editor: OGRE integration +Feature #541: Editor: Dialogue Sub-Views +Feature #944: Editor: lighting modes +Feature #945: Editor: Camera navigation mode +Feature #953: Trader gold +Feature #1140: AI: summoned creatures +Feature #1142: AI follow: Run stance +Feature #1154: Not all NPCs get aggressive when one is attacked +Feature #1169: Terrain threading +Feature #1172: Loading screen and progress bars during saved/loading game +Feature #1173: Saved Game: include weather state +Feature #1207: Class creation form does not remember +Feature #1220: Editor: Preview Subview +Feature #1223: Saved Game: Local Variables +Feature #1229: Quicksave, quickload, autosave +Feature #1230: Deleting saves +Feature #1233: Bribe gold is placed into NPCs inventory +Feature #1252: Saved Game: quick key bindings +Feature #1273: Editor: Region Map context menu +Feature #1274: Editor: Region Map drag & drop +Feature #1275: Editor: Scene subview drop +Feature #1282: Non-faction member crime recognition. +Feature #1289: NPCs return to default position +Task #941: Remove unused cmake files + 0.29.0 Bug #556: Video soundtrack not played when music volume is set to zero From cd7983adb5f04140e72ad157b03b1eb931293259 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 7 May 2014 21:59:26 -0500 Subject: [PATCH 084/121] Decoupled setting definitions from the Setting class. QSettings implementation is now fully responsible for managing user settings. --- apps/opencs/model/settings/connector.cpp | 1 + apps/opencs/model/settings/setting.cpp | 10 --- apps/opencs/model/settings/setting.hpp | 3 - apps/opencs/model/settings/usersettings.cpp | 85 +++++++++------------ apps/opencs/model/settings/usersettings.hpp | 17 +++-- apps/opencs/view/settings/dialog.cpp | 3 + apps/opencs/view/settings/settingwindow.cpp | 31 ++++++-- apps/opencs/view/settings/settingwindow.hpp | 3 + apps/opencs/view/settings/view.cpp | 7 +- apps/opencs/view/settings/view.hpp | 2 +- 10 files changed, 83 insertions(+), 79 deletions(-) diff --git a/apps/opencs/model/settings/connector.cpp b/apps/opencs/model/settings/connector.cpp index 05a9ba8f9..5e1d64544 100644 --- a/apps/opencs/model/settings/connector.cpp +++ b/apps/opencs/model/settings/connector.cpp @@ -81,6 +81,7 @@ void CSMSettings::Connector::slotUpdateMaster() const } QString masterValue = mMasterView->value (masterColumn); + mMasterView->setSelectedValue (masterValue); } diff --git a/apps/opencs/model/settings/setting.cpp b/apps/opencs/model/settings/setting.cpp index 2ef829f86..2f86d4ff8 100644 --- a/apps/opencs/model/settings/setting.cpp +++ b/apps/opencs/model/settings/setting.cpp @@ -77,16 +77,6 @@ QStringList CSMSettings::Setting::declaredValues() const return property (Property_DeclaredValues); } -void CSMSettings::Setting::setDefinedValues (QStringList list) -{ - setProperty (Property_DefinedValues, list); -} - -QStringList CSMSettings::Setting::definedValues() const -{ - return property (Property_DefinedValues); -} - QStringList CSMSettings::Setting::property (SettingProperty prop) const { if (prop >= mProperties.size()) diff --git a/apps/opencs/model/settings/setting.hpp b/apps/opencs/model/settings/setting.hpp index 89d6cc2c4..e40302f00 100644 --- a/apps/opencs/model/settings/setting.hpp +++ b/apps/opencs/model/settings/setting.hpp @@ -44,9 +44,6 @@ namespace CSMSettings void setDeclaredValues (QStringList list); QStringList declaredValues() const; - void setDefinedValues (QStringList list); - QStringList definedValues() const; - void setDefaultValue (int value); void setDefaultValue (double value); void setDefaultValue (const QString &value); diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 8d71dbe82..1a9125439 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -38,31 +38,6 @@ CSMSettings::UserSettings::UserSettings() buildSettingModelDefaults(); } -void CSMSettings::UserSettings::addDefinitions () -{ - foreach (const QString &key, mSettingDefinitions->allKeys()) - { - QStringList names = key.split('/'); - - Setting *setting = findSetting (names.at(0), names.at(1)); - - if (!setting) - { - qWarning() << "Found definitions for undeclared setting " - << names.at(0) << "/" << names.at(1); - removeSetting (names.at(0), names.at(1)); - continue; - } - - QStringList values = mSettingDefinitions->value (key).toStringList(); - - if (values.isEmpty()) - values.append (setting->defaultValues()); - - setting->setDefinedValues (values); - } -} - void CSMSettings::UserSettings::buildSettingModelDefaults() { QString section = "Window Size"; @@ -139,13 +114,14 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() * Defined values * * Values which represent the actual, current value of - * a setting. For settings with declared values, this must be one or - * several declared values, as appropriate. + * a setting. For settings with declared values, this must be one + * or several declared values, as appropriate. * - * Proxy values - values the proxy master updates the proxy slave when - * it's own definition is set / changed. These are definitions for - * proxy slave settings, but must match any declared values the proxy - * slave has, if any. + * Proxy values + * Values the proxy master updates the proxy slave when + * it's own definition is set / changed. These are definitions for + * proxy slave settings, but must match any declared values the + * proxy slave has, if any. *******************************************************************/ /* //create setting objects, specifying the basic widget type, @@ -328,31 +304,36 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) mSettingDefinitions = new QSettings (QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this); - - addDefinitions(); } -void CSMSettings::UserSettings::saveSettings - (const QMap &settingMap) +bool CSMSettings::UserSettings::hasSettingDefinitions + (const QString &viewKey) const { - foreach (const QString &key, settingMap.keys()) - mSettingDefinitions->setValue (key, settingMap.value (key)); + return (mSettingDefinitions->contains (viewKey)); +} +void CSMSettings::UserSettings::setDefinitions + (const QString &key, const QStringList &list) +{ + mSettingDefinitions->setValue (key, list); +} + +void CSMSettings::UserSettings::saveDefinitions() const +{ mSettingDefinitions->sync(); } QString CSMSettings::UserSettings::settingValue (const QString &settingKey) { - QStringList names = settingKey.split('/'); + if (!mSettingDefinitions->contains (settingKey)) + return QString(); - Setting *setting = findSetting(names.at(0), names.at(1)); + QStringList defs = mSettingDefinitions->value (settingKey).toStringList(); - if (setting) - { - if (!setting->definedValues().isEmpty()) - return setting->definedValues().at(0); - } - return ""; + if (defs.isEmpty()) + return QString(); + + return defs.at(0); } CSMSettings::UserSettings& CSMSettings::UserSettings::instance() @@ -364,11 +345,7 @@ CSMSettings::UserSettings& CSMSettings::UserSettings::instance() void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey, const QStringList &list) { - QStringList names = settingKey.split('/'); - - Setting *setting = findSetting (names.at(0), names.at(1)); - - setting->setDefinedValues (list); + mSettingDefinitions->setValue (settingKey ,list); emit userSettingUpdated (settingKey, list); } @@ -439,3 +416,11 @@ CSMSettings::Setting *CSMSettings::UserSettings::createSetting return setting; } + +QStringList CSMSettings::UserSettings::definitions (const QString &viewKey) const +{ + if (mSettingDefinitions->contains (viewKey)) + return mSettingDefinitions->value (viewKey).toStringList(); + + return QStringList(); +} diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 3ac348760..830cc8c69 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -49,8 +49,8 @@ namespace CSMSettings { /// Retrieves the settings file at all three levels (global, local and user). void loadSettings (const QString &fileName); - /// Writes settings to the user's config file path - void saveSettings (const QMap &settingMap); + /// Updates QSettings and syncs with the ini file + void setDefinitions (const QString &key, const QStringList &defs); QString settingValue (const QString &settingKey); @@ -65,10 +65,17 @@ namespace CSMSettings { ///Retreive a map of the settings, keyed by page name SettingPageMap settingPageMap() const; - private: + ///Returns a string list of defined vlaues for the specified setting + ///in "page/name" format. + QStringList definitions (const QString &viewKey) const; - ///add definitions to the settings specified in the page map - void addDefinitions(); + ///Test to indicate whether or not a setting has any definitions + bool hasSettingDefinitions (const QString &viewKey) const; + + ///Save any unsaved changes in the QSettings object + void saveDefinitions() const; + + private: void buildSettingModelDefaults(); diff --git a/apps/opencs/view/settings/dialog.cpp b/apps/opencs/view/settings/dialog.cpp index 4e7b08aff..56bc1fdfe 100644 --- a/apps/opencs/view/settings/dialog.cpp +++ b/apps/opencs/view/settings/dialog.cpp @@ -109,7 +109,10 @@ void CSVSettings::Dialog::closeEvent (QCloseEvent *event) void CSVSettings::Dialog::show() { if (pages().isEmpty()) + { buildPages(); + setViewValues(); + } QPoint screenCenter = QApplication::desktop()->screenGeometry().center(); diff --git a/apps/opencs/view/settings/settingwindow.cpp b/apps/opencs/view/settings/settingwindow.cpp index aeb652b3b..7cdf2bded 100644 --- a/apps/opencs/view/settings/settingwindow.cpp +++ b/apps/opencs/view/settings/settingwindow.cpp @@ -82,6 +82,25 @@ void CSVSettings::SettingWindow::createConnections } } +void CSVSettings::SettingWindow::setViewValues() +{ + //iterate each page and view, setting their definintions + //if they exist in the model + foreach (const Page *page, mPages) + { + foreach (const View *view, page->views()) + { + //testing beforehand prevents overwriting a proxy setting + if (!mModel->hasSettingDefinitions (view->viewKey())) + continue; + + QStringList defs = mModel->definitions (view->viewKey()); + + view->setSelectedValues(defs); + } + } +} + CSVSettings::View *CSVSettings::SettingWindow::findView (const QString &pageName, const QString &setting) { @@ -95,17 +114,19 @@ CSVSettings::View *CSVSettings::SettingWindow::findView void CSVSettings::SettingWindow::saveSettings() { - QMap settingMap; - + //setting the definition in the model automatically syncs with the file foreach (const Page *page, mPages) { foreach (const View *view, page->views()) { - if (view->serializable()) - settingMap[view->viewKey()] = view->selectedValues(); + if (!view->serializable()) + continue; + + mModel->setDefinitions (view->viewKey(), view->selectedValues()); } } - CSMSettings::UserSettings::instance().saveSettings (settingMap); + + mModel->saveDefinitions(); } void CSVSettings::SettingWindow::closeEvent (QCloseEvent *event) diff --git a/apps/opencs/view/settings/settingwindow.hpp b/apps/opencs/view/settings/settingwindow.hpp index 071f1b45e..2266f130d 100644 --- a/apps/opencs/view/settings/settingwindow.hpp +++ b/apps/opencs/view/settings/settingwindow.hpp @@ -47,6 +47,9 @@ namespace CSVSettings { ///save settings from the GUI to file void saveSettings(); + ///sets the defined values for the views that have been created + void setViewValues(); + private: ///create connections between settings (used for proxy settings) diff --git a/apps/opencs/view/settings/view.cpp b/apps/opencs/view/settings/view.cpp index c3b33cf84..69109e2b3 100644 --- a/apps/opencs/view/settings/view.cpp +++ b/apps/opencs/view/settings/view.cpp @@ -26,10 +26,7 @@ CSVSettings::View::View(CSMSettings::Setting *setting, void CSVSettings::View::buildModel (const CSMSettings::Setting *setting) { - QStringList values = setting->definedValues(); - - if (values.isEmpty()) - values.append (setting->defaultValues()); + QStringList values = setting->defaultValues(); if (mHasFixedValues) buildFixedValueModel (setting->declaredValues()); @@ -116,7 +113,7 @@ void CSVSettings::View::setSelectedValue (const QString &value, } void CSVSettings::View::setSelectedValues (const QStringList &list, - bool doViewUpdate, bool signalUpdate) + bool doViewUpdate, bool signalUpdate) const { QItemSelection selection; diff --git a/apps/opencs/view/settings/view.hpp b/apps/opencs/view/settings/view.hpp index 5106d8d90..84ad62759 100644 --- a/apps/opencs/view/settings/view.hpp +++ b/apps/opencs/view/settings/view.hpp @@ -71,7 +71,7 @@ namespace CSVSettings ///or signaling the view was updatedto avoid viscious cylcing. void setSelectedValues (const QStringList &values, bool updateView = true, - bool signalUpdate = true); + bool signalUpdate = true) const; void setSelectedValue (const QString &value, bool updateView = true, From 205306ee3d9294ace22c46455c195524f447eb97 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 May 2014 12:42:29 +0200 Subject: [PATCH 085/121] changed message passing format from QString to a UniversalId/std::string pair --- apps/opencs/main.cpp | 5 + apps/opencs/model/doc/document.cpp | 10 +- apps/opencs/model/doc/document.hpp | 3 +- apps/opencs/model/doc/operation.cpp | 10 +- apps/opencs/model/doc/operation.hpp | 8 +- apps/opencs/model/doc/savingstages.cpp | 14 +- apps/opencs/model/doc/savingstages.hpp | 18 +- apps/opencs/model/doc/stage.hpp | 6 +- apps/opencs/model/tools/birthsigncheck.cpp | 8 +- apps/opencs/model/tools/birthsigncheck.hpp | 2 +- apps/opencs/model/tools/classcheck.cpp | 25 +- apps/opencs/model/tools/classcheck.hpp | 2 +- apps/opencs/model/tools/factioncheck.cpp | 19 +- apps/opencs/model/tools/factioncheck.hpp | 2 +- apps/opencs/model/tools/mandatoryid.cpp | 5 +- apps/opencs/model/tools/mandatoryid.hpp | 2 +- apps/opencs/model/tools/racecheck.cpp | 20 +- apps/opencs/model/tools/racecheck.hpp | 6 +- .../opencs/model/tools/referenceablecheck.cpp | 488 ++++++------------ .../opencs/model/tools/referenceablecheck.hpp | 75 +-- apps/opencs/model/tools/regioncheck.cpp | 4 +- apps/opencs/model/tools/regioncheck.hpp | 2 +- apps/opencs/model/tools/reportmodel.cpp | 9 +- apps/opencs/model/tools/reportmodel.hpp | 2 +- apps/opencs/model/tools/scriptcheck.cpp | 27 +- apps/opencs/model/tools/scriptcheck.hpp | 4 +- apps/opencs/model/tools/skillcheck.cpp | 8 +- apps/opencs/model/tools/skillcheck.hpp | 2 +- apps/opencs/model/tools/soundcheck.cpp | 4 +- apps/opencs/model/tools/soundcheck.hpp | 2 +- apps/opencs/model/tools/spellcheck.cpp | 6 +- apps/opencs/model/tools/spellcheck.hpp | 2 +- apps/opencs/model/tools/tools.cpp | 10 +- apps/opencs/model/tools/tools.hpp | 3 +- 34 files changed, 316 insertions(+), 497 deletions(-) diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index eded36394..8f5bfbc12 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -6,11 +6,14 @@ #include #include +#include #include #include +#include "model/world/universalid.hpp" + #ifdef Q_OS_MAC #include #endif @@ -42,6 +45,8 @@ int main(int argc, char *argv[]) { Q_INIT_RESOURCE (resources); + qRegisterMetaType ("CSMWorld::UniversalId"); + OgreInit::OgreInit ogreInit; std::auto_ptr shinyFactory; diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 3ef14ee7e..bbce7fa3f 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2288,8 +2288,9 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int))); - connect (&mSaving, SIGNAL (reportMessage (const QString&, int)), - this, SLOT (reportMessage (const QString&, int))); + connect ( + &mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)), + this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, int))); } CSMDoc::Document::~Document() @@ -2358,10 +2359,11 @@ void CSMDoc::Document::modificationStateChanged (bool clean) emit stateChanged (getState(), this); } -void CSMDoc::Document::reportMessage (const QString& message, int type) +void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std::string& message, + int type) { /// \todo find a better way to get these messages to the user. - std::cout << message.toUtf8().constData() << std::endl; + std::cout << message << std::endl; } void CSMDoc::Document::operationDone (int type) diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 201fb4342..33378511b 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -111,7 +111,8 @@ namespace CSMDoc void modificationStateChanged (bool clean); - void reportMessage (const QString& message, int type); + void reportMessage (const CSMWorld::UniversalId& id, const std::string& message, + int type); void operationDone (int type); diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index d29cc2631..42a432043 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -6,6 +6,8 @@ #include +#include "../world/universalid.hpp" + #include "state.hpp" #include "stage.hpp" @@ -80,7 +82,7 @@ void CSMDoc::Operation::abort() void CSMDoc::Operation::executeStage() { - std::vector messages; + Stage::Messages messages; while (mCurrentStage!=mStages.end()) { @@ -97,7 +99,7 @@ void CSMDoc::Operation::executeStage() } catch (const std::exception& e) { - emit reportMessage (e.what(), mType); + emit reportMessage (CSMWorld::UniversalId(), e.what(), mType); abort(); } @@ -108,8 +110,8 @@ void CSMDoc::Operation::executeStage() emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType); - for (std::vector::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter) - emit reportMessage (iter->c_str(), mType); + for (Stage::Messages::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter) + emit reportMessage (iter->first, iter->second, mType); if (mCurrentStage==mStages.end()) exit(); diff --git a/apps/opencs/model/doc/operation.hpp b/apps/opencs/model/doc/operation.hpp index 316eda78f..651283880 100644 --- a/apps/opencs/model/doc/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -5,6 +5,11 @@ #include +namespace CSMWorld +{ + class UniversalId; +} + namespace CSMDoc { class Stage; @@ -46,7 +51,8 @@ namespace CSMDoc void progress (int current, int max, int type); - void reportMessage (const QString& message, int type); + void reportMessage (const CSMWorld::UniversalId& id, const std::string& message, + int type); void done (int type); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index d7df2117d..eb93d9047 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -23,7 +23,7 @@ int CSMDoc::OpenSaveStage::setup() return 1; } -void CSMDoc::OpenSaveStage::perform (int stage, std::vector& messages) +void CSMDoc::OpenSaveStage::perform (int stage, Messages& messages) { mState.start (mDocument, mProjectFile); @@ -43,7 +43,7 @@ int CSMDoc::WriteHeaderStage::setup() return 1; } -void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& messages) +void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages) { mState.getWriter().setVersion(); @@ -96,7 +96,7 @@ int CSMDoc::WriteDialogueCollectionStage::setup() return mTopics.getSize(); } -void CSMDoc::WriteDialogueCollectionStage::perform (int stage, std::vector& messages) +void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& messages) { const CSMWorld::Record& topic = mTopics.getRecord (stage); @@ -191,7 +191,7 @@ int CSMDoc::WriteRefIdCollectionStage::setup() return mDocument.getData().getReferenceables().getSize(); } -void CSMDoc::WriteRefIdCollectionStage::perform (int stage, std::vector& messages) +void CSMDoc::WriteRefIdCollectionStage::perform (int stage, Messages& messages) { mDocument.getData().getReferenceables().save (stage, mState.getWriter()); } @@ -204,7 +204,7 @@ CSMDoc::WriteFilterStage::WriteFilterStage (Document& document, SavingState& sta mDocument (document), mScope (scope) {} -void CSMDoc::WriteFilterStage::perform (int stage, std::vector& messages) +void CSMDoc::WriteFilterStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mDocument.getData().getFilters().getRecord (stage); @@ -223,7 +223,7 @@ int CSMDoc::CloseSaveStage::setup() return 1; } -void CSMDoc::CloseSaveStage::perform (int stage, std::vector& messages) +void CSMDoc::CloseSaveStage::perform (int stage, Messages& messages) { mState.getStream().close(); @@ -241,7 +241,7 @@ int CSMDoc::FinalSavingStage::setup() return 1; } -void CSMDoc::FinalSavingStage::perform (int stage, std::vector& messages) +void CSMDoc::FinalSavingStage::perform (int stage, Messages& messages) { if (mState.hasError()) { diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index b8eb0a3b3..c2f0a150a 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -39,7 +39,7 @@ namespace CSMDoc virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; @@ -57,7 +57,7 @@ namespace CSMDoc virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; @@ -75,7 +75,7 @@ namespace CSMDoc virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; @@ -92,7 +92,7 @@ namespace CSMDoc } template - void WriteCollectionStage::perform (int stage, std::vector& messages) + void WriteCollectionStage::perform (int stage, Messages& messages) { CSMWorld::RecordBase::State state = mCollection.getRecord (stage).mState; @@ -130,7 +130,7 @@ namespace CSMDoc virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; @@ -147,7 +147,7 @@ namespace CSMDoc virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; @@ -161,7 +161,7 @@ namespace CSMDoc WriteFilterStage (Document& document, SavingState& state, CSMFilter::Filter::Scope scope); - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; @@ -177,7 +177,7 @@ namespace CSMDoc virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; @@ -193,7 +193,7 @@ namespace CSMDoc virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/doc/stage.hpp b/apps/opencs/model/doc/stage.hpp index 1f96c60b4..ca34c2229 100644 --- a/apps/opencs/model/doc/stage.hpp +++ b/apps/opencs/model/doc/stage.hpp @@ -4,18 +4,22 @@ #include #include +#include "../world/universalid.hpp" + namespace CSMDoc { class Stage { public: + typedef std::vector > Messages; + virtual ~Stage(); virtual int setup() = 0; ///< \return number of steps - virtual void perform (int stage, std::vector& messages) = 0; + virtual void perform (int stage, Messages& messages) = 0; ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index 59c65086e..db20ce4bc 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -17,7 +17,7 @@ int CSMTools::BirthsignCheckStage::setup() return mBirthsigns.getSize(); } -void CSMTools::BirthsignCheckStage::perform (int stage, std::vector& messages) +void CSMTools::BirthsignCheckStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mBirthsigns.getRecord (stage); @@ -30,13 +30,13 @@ void CSMTools::BirthsignCheckStage::perform (int stage, std::vector // test for empty name, description and texture if (birthsign.mName.empty()) - messages.push_back (id.toString() + "|" + birthsign.mId + " has an empty name"); + messages.push_back (std::make_pair (id, birthsign.mId + " has an empty name")); if (birthsign.mDescription.empty()) - messages.push_back (id.toString() + "|" + birthsign.mId + " has an empty description"); + messages.push_back (std::make_pair (id, birthsign.mId + " has an empty description")); if (birthsign.mTexture.empty()) - messages.push_back (id.toString() + "|" + birthsign.mId + " is missing a texture"); + messages.push_back (std::make_pair (id, birthsign.mId + " is missing a texture")); /// \todo test if the texture exists diff --git a/apps/opencs/model/tools/birthsigncheck.hpp b/apps/opencs/model/tools/birthsigncheck.hpp index bdd65b44a..1030e5c02 100644 --- a/apps/opencs/model/tools/birthsigncheck.hpp +++ b/apps/opencs/model/tools/birthsigncheck.hpp @@ -21,7 +21,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index 6923b3153..cea4f3a68 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -18,7 +18,7 @@ int CSMTools::ClassCheckStage::setup() return mClasses.getSize(); } -void CSMTools::ClassCheckStage::perform (int stage, std::vector& messages) +void CSMTools::ClassCheckStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mClasses.getRecord (stage); @@ -31,10 +31,10 @@ void CSMTools::ClassCheckStage::perform (int stage, std::vector& me // test for empty name and description if (class_.mName.empty()) - messages.push_back (id.toString() + "|" + class_.mId + " has an empty name"); + messages.push_back (std::make_pair (id, class_.mId + " has an empty name")); if (class_.mDescription.empty()) - messages.push_back (id.toString() + "|" + class_.mId + " has an empty description"); + messages.push_back (std::make_pair (id, class_.mId + " has an empty description")); // test for invalid attributes for (int i=0; i<2; ++i) @@ -42,18 +42,14 @@ void CSMTools::ClassCheckStage::perform (int stage, std::vector& me { std::ostringstream stream; - stream << id.toString() << "|Attribute #" << i << " of " << class_.mId << " is not set"; + stream << "Attribute #" << i << " of " << class_.mId << " is not set"; - messages.push_back (stream.str()); + messages.push_back (std::make_pair (id, stream.str())); } if (class_.mData.mAttribute[0]==class_.mData.mAttribute[1] && class_.mData.mAttribute[0]!=-1) { - std::ostringstream stream; - - stream << id.toString() << "|Class lists same attribute twice"; - - messages.push_back (stream.str()); + messages.push_back (std::make_pair (id, "Class lists same attribute twice")); } // test for non-unique skill @@ -66,12 +62,7 @@ void CSMTools::ClassCheckStage::perform (int stage, std::vector& me for (std::map::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter) if (iter->second>1) { - std::ostringstream stream; - - stream - << id.toString() << "|" - << ESM::Skill::indexToId (iter->first) << " is listed more than once"; - - messages.push_back (stream.str()); + messages.push_back (std::make_pair (id, + ESM::Skill::indexToId (iter->first) + " is listed more than once")); } } \ No newline at end of file diff --git a/apps/opencs/model/tools/classcheck.hpp b/apps/opencs/model/tools/classcheck.hpp index 3604b451c..ec50ba35d 100644 --- a/apps/opencs/model/tools/classcheck.hpp +++ b/apps/opencs/model/tools/classcheck.hpp @@ -21,7 +21,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index c219e5610..42d577163 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -18,7 +18,7 @@ int CSMTools::FactionCheckStage::setup() return mFactions.getSize(); } -void CSMTools::FactionCheckStage::perform (int stage, std::vector& messages) +void CSMTools::FactionCheckStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mFactions.getRecord (stage); @@ -31,16 +31,12 @@ void CSMTools::FactionCheckStage::perform (int stage, std::vector& // test for empty name if (faction.mName.empty()) - messages.push_back (id.toString() + "|" + faction.mId + " has an empty name"); + messages.push_back (std::make_pair (id, faction.mId + " has an empty name")); // test for invalid attributes if (faction.mData.mAttribute[0]==faction.mData.mAttribute[1] && faction.mData.mAttribute[0]!=-1) { - std::ostringstream stream; - - stream << id.toString() << "|Faction lists same attribute twice"; - - messages.push_back (stream.str()); + messages.push_back (std::make_pair (id , "Faction lists same attribute twice")); } // test for non-unique skill @@ -53,13 +49,8 @@ void CSMTools::FactionCheckStage::perform (int stage, std::vector& for (std::map::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter) if (iter->second>1) { - std::ostringstream stream; - - stream - << id.toString() << "|" - << ESM::Skill::indexToId (iter->first) << " is listed more than once"; - - messages.push_back (stream.str()); + messages.push_back (std::make_pair (id, + ESM::Skill::indexToId (iter->first) + " is listed more than once")); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/factioncheck.hpp b/apps/opencs/model/tools/factioncheck.hpp index 7cd80347d..ccc44e6a9 100644 --- a/apps/opencs/model/tools/factioncheck.hpp +++ b/apps/opencs/model/tools/factioncheck.hpp @@ -21,7 +21,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/mandatoryid.cpp b/apps/opencs/model/tools/mandatoryid.cpp index b99abec6d..5f245dd4d 100644 --- a/apps/opencs/model/tools/mandatoryid.cpp +++ b/apps/opencs/model/tools/mandatoryid.cpp @@ -15,9 +15,10 @@ int CSMTools::MandatoryIdStage::setup() return mIds.size(); } -void CSMTools::MandatoryIdStage::perform (int stage, std::vector& messages) +void CSMTools::MandatoryIdStage::perform (int stage, Messages& messages) { if (mIdCollection.searchId (mIds.at (stage))==-1 || mIdCollection.getRecord (mIds.at (stage)).isDeleted()) - messages.push_back (mCollectionId.toString() + "|Missing mandatory record: " + mIds.at (stage)); + messages.push_back (std::make_pair (mCollectionId, + "|Missing mandatory record: " + mIds.at (stage))); } \ No newline at end of file diff --git a/apps/opencs/model/tools/mandatoryid.hpp b/apps/opencs/model/tools/mandatoryid.hpp index 5fddf08d3..a8afea62a 100644 --- a/apps/opencs/model/tools/mandatoryid.hpp +++ b/apps/opencs/model/tools/mandatoryid.hpp @@ -30,7 +30,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/racecheck.cpp b/apps/opencs/model/tools/racecheck.cpp index 413de5ef0..47aeda1e6 100644 --- a/apps/opencs/model/tools/racecheck.cpp +++ b/apps/opencs/model/tools/racecheck.cpp @@ -7,7 +7,7 @@ #include "../world/universalid.hpp" -void CSMTools::RaceCheckStage::performPerRecord (int stage, std::vector& messages) +void CSMTools::RaceCheckStage::performPerRecord (int stage, Messages& messages) { const CSMWorld::Record& record = mRaces.getRecord (stage); @@ -20,24 +20,24 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, std::vector& messages) +void CSMTools::RaceCheckStage::performFinal (Messages& messages) { CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races); if (!mPlayable) - messages.push_back (id.toString() + "|No playable race"); + messages.push_back (std::make_pair (id, "No playable race")); } CSMTools::RaceCheckStage::RaceCheckStage (const CSMWorld::IdCollection& races) @@ -64,7 +64,7 @@ int CSMTools::RaceCheckStage::setup() return mRaces.getSize()+1; } -void CSMTools::RaceCheckStage::perform (int stage, std::vector& messages) +void CSMTools::RaceCheckStage::perform (int stage, Messages& messages) { if (stage==mRaces.getSize()) performFinal (messages); diff --git a/apps/opencs/model/tools/racecheck.hpp b/apps/opencs/model/tools/racecheck.hpp index ff9948bf6..c68b283be 100644 --- a/apps/opencs/model/tools/racecheck.hpp +++ b/apps/opencs/model/tools/racecheck.hpp @@ -15,9 +15,9 @@ namespace CSMTools const CSMWorld::IdCollection& mRaces; bool mPlayable; - void performPerRecord (int stage, std::vector& messages); + void performPerRecord (int stage, Messages& messages); - void performFinal (std::vector& messages); + void performFinal (Messages& messages); public: @@ -26,7 +26,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index dab61bfff..488081f46 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1,7 +1,9 @@ #include "referenceablecheck.hpp" + +#include + #include "../world/record.hpp" #include "../world/universalid.hpp" -#include CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, @@ -16,7 +18,7 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( { } -void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::perform (int stage, Messages& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. const int bookSize(mReferencables.getBooks().getSize()); @@ -206,11 +208,11 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str staticCheck(stage, mReferencables.getStatics(), messages); return; } - + stage -= staticSize; const int creatureSize(mReferencables.getCreatures().getSize()); - + if (stage < creatureSize) { creatureCheck(stage, mReferencables.getCreatures(), messages); @@ -230,7 +232,7 @@ int CSMTools::ReferenceableCheckStage::setup() void CSMTools::ReferenceableCheckStage::bookCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -248,7 +250,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck( void CSMTools::ReferenceableCheckStage::activatorCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -262,15 +264,13 @@ void CSMTools::ReferenceableCheckStage::activatorCheck( //Checking for model, IIRC all activators should have a model if (activator.mModel.empty()) - { - messages.push_back(id.toString() + "|" + activator.mId + " has no model"); - } + messages.push_back (std::make_pair (id, activator.mId + " has no model")); } void CSMTools::ReferenceableCheckStage::potionCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Potion >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -290,7 +290,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck( void CSMTools::ReferenceableCheckStage::apparatusCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -310,7 +310,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck( void CSMTools::ReferenceableCheckStage::armorCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Armor >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -326,21 +326,17 @@ void CSMTools::ReferenceableCheckStage::armorCheck( //checking for armor class, armor should have poistive armor class, but 0 is considered legal if (armor.mData.mArmor < 0) - { - messages.push_back(id.toString() + "|" + armor.mId + " has negative armor class"); - } + messages.push_back (std::make_pair (id, armor.mId + " has negative armor class")); //checking for health. Only positive numbers are allowed, or 0 is illegal if (armor.mData.mHealth <= 0) - { - messages.push_back(id.toString() + "|" + armor.mId + " has non positive health"); - } + messages.push_back (std::make_pair (id, armor.mId + " has non positive health")); } void CSMTools::ReferenceableCheckStage::clothingCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Clothing >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -357,7 +353,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck( void CSMTools::ReferenceableCheckStage::containerCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Container >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -371,153 +367,109 @@ void CSMTools::ReferenceableCheckStage::containerCheck( //Checking for model, IIRC all containers should have a model if (container.mModel.empty()) - { - messages.push_back(id.toString() + "|" + container.mId + " has no model"); - } + messages.push_back (std::make_pair (id, container.mId + " has no model")); //Checking for capacity (weight) if (container.mWeight < 0) //0 is allowed - { - messages.push_back(id.toString() + "|" + container.mId + " has negative weight (capacity)"); - } + messages.push_back (std::make_pair (id, + container.mId + " has negative weight (capacity)")); //checking for name if (container.mName.empty()) - { - messages.push_back(id.toString() + "|" + container.mId + " has an empty name"); - } + messages.push_back (std::make_pair (id, container.mId + " has an empty name")); } -void CSMTools::ReferenceableCheckStage::creatureCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Creature >& records, - std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::creatureCheck ( + int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records, + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); if (baseRecord.isDeleted()) - { return; - } const ESM::Creature& creature = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, creature.mId); if (creature.mModel.empty()) - { - messages.push_back(id.toString() + "|" + creature.mId + " has no model"); - } + messages.push_back (std::make_pair (id, creature.mId + " has no model")); if (creature.mName.empty()) - { - messages.push_back(id.toString() + "|" + creature.mId + " has an empty name"); - } + messages.push_back (std::make_pair (id, creature.mId + " has an empty name")); //stats checks if (creature.mData.mLevel < 1) - { - messages.push_back(id.toString() + "|" + creature.mId + " has non-postive level"); - } + messages.push_back (std::make_pair (id, creature.mId + " has non-postive level")); if (creature.mData.mStrength < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative strength"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative strength")); if (creature.mData.mIntelligence < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative intelligence"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative intelligence")); if (creature.mData.mWillpower < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative willpower"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative willpower")); if (creature.mData.mAgility < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative agility"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative agility")); if (creature.mData.mSpeed < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative speed"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative speed")); if (creature.mData.mEndurance < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative endurance"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative endurance")); if (creature.mData.mPersonality < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative personality"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative personality")); if (creature.mData.mLuck < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative luck"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative luck")); if (creature.mData.mHealth < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative health"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative health")); if (creature.mData.mSoul < 0) - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative soul value"); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative soul value")); for (int i = 0; i < 6; ++i) { if (creature.mData.mAttack[i] < 0) { - messages.push_back(id.toString() + "|" + creature.mId + " has negative attack strength"); + messages.push_back (std::make_pair (id, + creature.mId + " has negative attack strength")); break; } } //TODO, find meaning of other values if (creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures - { - messages.push_back(id.toString() + "|" + creature.mId + " has negative gold "); - } + messages.push_back (std::make_pair (id, creature.mId + " has negative gold ")); } void CSMTools::ReferenceableCheckStage::doorCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Door >& records, - std::vector< std::string >& messages) + int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records, + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); if (baseRecord.isDeleted()) - { return; - } const ESM::Door& Door = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, Door.mId); //usual, name or model if (Door.mName.empty()) - { - messages.push_back(id.toString() + "|" + Door.mId + " has an empty name"); - } + messages.push_back (std::make_pair (id, Door.mId + " has an empty name")); if (Door.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Door.mId + " has no model"); - } - - //TODO, check what static unsigned int sRecordId; is for + messages.push_back (std::make_pair (id, Door.mId + " has no model")); } void CSMTools::ReferenceableCheckStage::ingredientCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -535,7 +487,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck( void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -553,7 +505,7 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( void CSMTools::ReferenceableCheckStage::itemLevelledListCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -569,40 +521,33 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck( } void CSMTools::ReferenceableCheckStage::lightCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Light >& records, - std::vector< std::string >& messages) + int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records, + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); if (baseRecord.isDeleted()) - { return; - } const ESM::Light& light = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, light.mId); if (light.mData.mRadius < 0) - { - messages.push_back(id.toString() + "|" + light.mId + " has negative light radius"); - } + messages.push_back (std::make_pair (id, light.mId + " has negative light radius")); if (light.mData.mFlags & ESM::Light::Carry) { inventoryItemCheck(light, messages, id.toString()); if (light.mData.mTime == 0) - { - messages.push_back(id.toString() + "|" + light.mId + " has zero duration"); - } + messages.push_back (std::make_pair (id, light.mId + " has zero duration")); } } void CSMTools::ReferenceableCheckStage::lockpickCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -622,7 +567,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck( void CSMTools::ReferenceableCheckStage::miscCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -637,20 +582,17 @@ void CSMTools::ReferenceableCheckStage::miscCheck( inventoryItemCheck(miscellaneous, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::npcCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::NPC >& records, - std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::npcCheck ( + int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records, + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); if (baseRecord.isDeleted()) - { return; - } const ESM::NPC& npc = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, npc.mId); + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Npc, npc.mId); short level(npc.mNpdt52.mLevel); char disposition(npc.mNpdt52.mDisposition); @@ -661,15 +603,13 @@ void CSMTools::ReferenceableCheckStage::npcCheck( //Detect if player is present if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl? - { mPlayerPresent = true; - } if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated { if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag { - messages.push_back(id.toString() + "|" + npc.mId + " mNpdtType or flags mismatch!"); //should not happend? + messages.push_back (std::make_pair (id, npc.mId + " mNpdtType or flags mismatch!")); //should not happend? return; } @@ -682,145 +622,100 @@ void CSMTools::ReferenceableCheckStage::npcCheck( else { if (npc.mNpdt52.mMana < 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " mana has negative value"); - } + messages.push_back (std::make_pair (id, npc.mId + " mana has negative value")); if (npc.mNpdt52.mFatigue < 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " fatigue has negative value"); - } + messages.push_back (std::make_pair (id, npc.mId + " fatigue has negative value")); if (npc.mNpdt52.mAgility == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " agility has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " agility has zero value")); if (npc.mNpdt52.mEndurance == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " endurance has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " endurance has zero value")); if (npc.mNpdt52.mIntelligence == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " intelligence has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " intelligence has zero value")); if (npc.mNpdt52.mLuck == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " luck has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " luck has zero value")); if (npc.mNpdt52.mPersonality == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " personality has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " personality has zero value")); if (npc.mNpdt52.mStrength == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " strength has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " strength has zero value")); if (npc.mNpdt52.mSpeed == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " speed has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " speed has zero value")); if (npc.mNpdt52.mWillpower == 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " willpower has zero value"); - } + messages.push_back (std::make_pair (id, npc.mId + " willpower has zero value")); } if (level < 1) - { - messages.push_back(id.toString() + "|" + npc.mId + " level is non positive"); - } + messages.push_back (std::make_pair (id, npc.mId + " level is non positive")); if (gold < 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " gold has negative value"); - } + messages.push_back (std::make_pair (id, npc.mId + " gold has negative value")); if (npc.mName.empty()) - { - messages.push_back(id.toString() + "|" + npc.mId + " has any empty name"); - } + messages.push_back (std::make_pair (id, npc.mId + " has any empty name")); if (npc.mClass.empty()) { - messages.push_back(id.toString() + "|" + npc.mId + " has any empty class"); + messages.push_back (std::make_pair (id, npc.mId + " has any empty class")); } - else //checking if there is such class + else if (mClasses.searchId (npc.mClass) == -1) { - if (mClasses.searchId(npc.mClass) == -1) - { - messages.push_back(id.toString() + "|" + npc.mId + " has invalid class"); - } + messages.push_back (std::make_pair (id, npc.mId + " has invalid class")); } if (npc.mRace.empty()) { - messages.push_back(id.toString() + "|" + npc.mId + " has any empty race"); + messages.push_back (std::make_pair (id, npc.mId + " has any empty race")); } - else //checking if there is a such race + else if (mRaces.searchId (npc.mRace) == -1) { - if (mRaces.searchId(npc.mRace) == -1) - { - messages.push_back(id.toString() + "|" + npc.mId + " has invalid race"); - } + messages.push_back (std::make_pair (id, npc.mId + " has invalid race")); } if (disposition < 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " has negative disposition"); - } + messages.push_back (std::make_pair (id, npc.mId + " has negative disposition")); if (reputation < 0) //It seems that no character in Morrowind.esm have negative reputation. I'm assuming that negative reputation is invalid { - messages.push_back(id.toString() + "|" + npc.mId + " has negative reputation"); + messages.push_back (std::make_pair (id, npc.mId + " has negative reputation")); } - if (npc.mFaction.empty() == false) + if (!npc.mFaction.empty()) { if (rank < 0) - { - messages.push_back(id.toString() + "|" + npc.mId + " has negative rank"); - } + messages.push_back (std::make_pair (id, npc.mId + " has negative rank")); if (mFactions.searchId(npc.mFaction) == -1) - { - messages.push_back(id.toString() + "|" + npc.mId + " has invalid faction"); - } + messages.push_back (std::make_pair (id, npc.mId + " has invalid faction")); } if (npc.mHead.empty()) - { - messages.push_back(id.toString() + "|" + npc.mId + " has no head"); - } + messages.push_back (std::make_pair (id, npc.mId + " has no head")); if (npc.mHair.empty()) - { - messages.push_back(id.toString() + "|" + npc.mId + " has no hair"); - } + messages.push_back (std::make_pair (id, npc.mId + " has no hair")); //TODO: reputation, Disposition, rank, everything else } void CSMTools::ReferenceableCheckStage::weaponCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, - std::vector< std::string >& messages) + int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, + Messages& messages) { - const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); if (baseRecord.isDeleted()) - { return; - } const ESM::Weapon& weapon = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Weapon, weapon.mId); + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Weapon, weapon.mId); //TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present if @@ -860,20 +755,17 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( weapon.mData.mType == ESM::Weapon::Bolt)) { if (weapon.mData.mSlash[0] > weapon.mData.mSlash[1]) - { - messages.push_back(id.toString() + "|" + weapon.mId + " has minimum slash damage higher than maximum"); - } + messages.push_back (std::make_pair (id, + weapon.mId + " has minimum slash damage higher than maximum")); if (weapon.mData.mThrust[0] > weapon.mData.mThrust[1]) - { - messages.push_back(id.toString() + "|" + weapon.mId + " has minimum thrust damage higher than maximum"); - } + messages.push_back (std::make_pair (id, + weapon.mId + " has minimum thrust damage higher than maximum")); } if (weapon.mData.mChop[0] > weapon.mData.mChop[1]) - { - messages.push_back(id.toString() + "|" + weapon.mId + " has minimum chop damage higher than maximum"); - } + messages.push_back (std::make_pair (id, + weapon.mId + " has minimum chop damage higher than maximum")); if (!(weapon.mData.mType == ESM::Weapon::Arrow || weapon.mData.mType == ESM::Weapon::Bolt || @@ -881,14 +773,10 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( { //checking of health if (weapon.mData.mHealth <= 0) - { - messages.push_back(id.toString() + "|" + weapon.mId + " has non-positivie health"); - } + messages.push_back (std::make_pair (id, weapon.mId + " has non-positivie health")); if (weapon.mData.mReach < 0) - { - messages.push_back(id.toString() + "|" + weapon.mId + " has negative reach"); - } + messages.push_back (std::make_pair (id, weapon.mId + " has negative reach")); } } } @@ -896,7 +784,7 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( void CSMTools::ReferenceableCheckStage::probeCheck( int stage, const CSMWorld::RefIdDataContainer< ESM::Probe >& records, - std::vector< std::string >& messages) + Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -912,184 +800,128 @@ void CSMTools::ReferenceableCheckStage::probeCheck( toolCheck(probe, messages, id.toString(), true); } -void CSMTools::ReferenceableCheckStage::repairCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Repair >& records, - std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::repairCheck ( + int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records, + Messages& messages) { - const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); if (baseRecord.isDeleted()) - { return; - } const ESM::Repair& repair = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Repair, repair.mId); + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Repair, repair.mId); - inventoryItemCheck(repair, messages, id.toString()); - toolCheck(repair, messages, id.toString(), true); + inventoryItemCheck (repair, messages, id.toString()); + toolCheck (repair, messages, id.toString(), true); } -void CSMTools::ReferenceableCheckStage::staticCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Static >& records, - std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::staticCheck ( + int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records, + Messages& messages) { - const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); if (baseRecord.isDeleted()) - { return; - } const ESM::Static& staticElement = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Static, staticElement.mId); + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Static, staticElement.mId); if (staticElement.mModel.empty()) - { - messages.push_back(id.toString() + "|" + staticElement.mId + " has no model"); - } + messages.push_back (std::make_pair (id, staticElement.mId + " has no model")); } //final check -void CSMTools::ReferenceableCheckStage::finalCheck(std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::finalCheck (Messages& messages) { if (!mPlayerPresent) - { - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc); - messages.push_back(id.toString() + "| There is no player record"); - } + messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables, + "There is no player record")); } //Templates begins here -template void CSMTools::ReferenceableCheckStage::inventoryItemCheck( - const ITEM& someItem, - std::vector< std::string >& messages, - const std::string& someID, bool enchantable) +template void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( + const Item& someItem, Messages& messages, const std::string& someID, bool enchantable) { if (someItem.mName.empty()) - { - messages.push_back(someID + "|" + someItem.mId + " has an empty name"); - } + messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name")); //Checking for weight if (someItem.mData.mWeight < 0) - { - messages.push_back(someID + "|" + someItem.mId + " has negative weight"); - } + messages.push_back (std::make_pair (someID, someItem.mId + " has negative weight")); //Checking for value if (someItem.mData.mValue < 0) - { - messages.push_back(someID + "|" + someItem.mId + " has negative value"); - } - -//checking for model - if (someItem.mModel.empty()) - { - messages.push_back(someID + "|" + someItem.mId + " has no model"); - } - - //checking for icon - if (someItem.mIcon.empty()) - { - messages.push_back(someID + "|" + someItem.mId + " has no icon"); - } - - if (enchantable) - { - if (someItem.mData.mEnchant < 0) - { - messages.push_back(someID + "|" + someItem.mId + " has negative enchantment"); - } - } -} - -template void CSMTools::ReferenceableCheckStage::inventoryItemCheck( - const ITEM& someItem, - std::vector< std::string >& messages, - const std::string& someID) -{ - if (someItem.mName.empty()) - { - messages.push_back(someID + "|" + someItem.mId + " has an empty name"); - } - - //Checking for weight - if (someItem.mData.mWeight < 0) - { - messages.push_back(someID + "|" + someItem.mId + " has negative weight"); - } - - //Checking for value - if (someItem.mData.mValue < 0) - { - messages.push_back(someID + "|" + someItem.mId + " has negative value"); - } + messages.push_back (std::make_pair (someID, someItem.mId + " has negative value")); //checking for model if (someItem.mModel.empty()) - { - messages.push_back(someID + "|" + someItem.mId + " has no model"); - } + messages.push_back (std::make_pair (someID, someItem.mId + " has no model")); //checking for icon if (someItem.mIcon.empty()) - { - messages.push_back(someID + "|" + someItem.mId + " has no icon"); - } + messages.push_back (std::make_pair (someID, someItem.mId + " has no icon")); + + if (enchantable && someItem.mData.mEnchant < 0) + messages.push_back (std::make_pair (someID, someItem.mId + " has negative enchantment")); } -template void CSMTools::ReferenceableCheckStage::toolCheck( - const TOOL& someTool, - std::vector< std::string >& messages, - const std::string& someID, bool canBeBroken) +template void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( + const Item& someItem, Messages& messages, const std::string& someID) +{ + if (someItem.mName.empty()) + messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name")); + + //Checking for weight + if (someItem.mData.mWeight < 0) + messages.push_back (std::make_pair (someID, someItem.mId + " has negative weight")); + + //Checking for value + if (someItem.mData.mValue < 0) + messages.push_back (std::make_pair (someID, someItem.mId + " has negative value")); + + //checking for model + if (someItem.mModel.empty()) + messages.push_back (std::make_pair (someID, someItem.mId + " has no model")); + + //checking for icon + if (someItem.mIcon.empty()) + messages.push_back (std::make_pair (someID, someItem.mId + " has no icon")); +} + +template void CSMTools::ReferenceableCheckStage::toolCheck ( + const Tool& someTool, Messages& messages, const std::string& someID, bool canBeBroken) { if (someTool.mData.mQuality <= 0) - { - messages.push_back(someID + "|" + someTool.mId + " has non-positive quality"); - } + messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality")); - if (canBeBroken) - { - if (someTool.mData.mUses <= 0) - { - messages.push_back(someID + "|" + someTool.mId + " has non-positive uses count"); - } - } + if (canBeBroken && someTool.mData.mUses<=0) + messages.push_back (std::make_pair (someID, + someTool.mId + " has non-positive uses count")); } -template void CSMTools::ReferenceableCheckStage::toolCheck( - const TOOL& someTool, - std::vector< std::string >& messages, - const std::string& someID) +template void CSMTools::ReferenceableCheckStage::toolCheck ( + const Tool& someTool, Messages& messages, const std::string& someID) { if (someTool.mData.mQuality <= 0) - { - messages.push_back(someID + "|" + someTool.mId + " has non-positive quality"); - } + messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality")); } -template void CSMTools::ReferenceableCheckStage::listCheck( - const LIST& someList, - std::vector< std::string >& messages, - const std::string& someID) +template void CSMTools::ReferenceableCheckStage::listCheck ( + const List& someList, Messages& messages, const std::string& someID) { for (unsigned i = 0; i < someList.mList.size(); ++i) { if (mReferencables.searchId(someList.mList[i].mId).first == -1) - { - messages.push_back(someID + "|" + someList.mId + " contains item without referencable"); - } + messages.push_back (std::make_pair (someID, + someList.mId + " contains item without referencable")); if (someList.mList[i].mLevel < 1) - { - messages.push_back(someID + "|" + someList.mId + " contains item with non-positive level"); - } + messages.push_back (std::make_pair (someID, + someList.mId + " contains item with non-positive level")); } } -// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 338983cc7..b0129fc2a 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -11,63 +11,64 @@ namespace CSMTools class ReferenceableCheckStage : public CSMDoc::Stage { public: - ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, - const CSMWorld::IdCollection& races, - const CSMWorld::IdCollection& classes, - const CSMWorld::IdCollection& factions); - virtual void perform(int stage, std::vector< std::string >& messages); + ReferenceableCheckStage (const CSMWorld::RefIdData& referenceable, + const CSMWorld::IdCollection& races, + const CSMWorld::IdCollection& classes, + const CSMWorld::IdCollection& factions); + + virtual void perform(int stage, Messages& messages); virtual int setup(); private: //CONCRETE CHECKS - void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages); - void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages); - void potionCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void clothingCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void lightCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void weaponCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void probeCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void repairCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void staticCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - + void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, Messages& messages); + void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, Messages& messages); + void potionCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void clothingCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void lightCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void weaponCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void probeCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void repairCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + void staticCheck(int stage, const CSMWorld::RefIdDataContainer& records, Messages& messages); + //FINAL CHECK - void finalCheck(std::vector& messages); - + void finalCheck (Messages& messages); + //TEMPLATE CHECKS template void inventoryItemCheck(const ITEM& someItem, - std::vector& messages, + Messages& messages, const std::string& someID, bool enchantable); //for all enchantable items. - + template void inventoryItemCheck(const ITEM& someItem, - std::vector& messages, + Messages& messages, const std::string& someID); //for non-enchantable items. - + template void toolCheck(const TOOL& someTool, - std::vector& messages, + Messages& messages, const std::string& someID, bool canbebroken); //for tools with uses. - + template void toolCheck(const TOOL& someTool, - std::vector& messages, + Messages& messages, const std::string& someID); //for tools without uses. template void listCheck(const LIST& someList, - std::vector< std::string >& messages, + Messages& messages, const std::string& someID); - + const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; const CSMWorld::IdCollection& mClasses; diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index 4398e00ef..07df20470 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -17,7 +17,7 @@ int CSMTools::RegionCheckStage::setup() return mRegions.getSize(); } -void CSMTools::RegionCheckStage::perform (int stage, std::vector& messages) +void CSMTools::RegionCheckStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mRegions.getRecord (stage); @@ -30,7 +30,7 @@ void CSMTools::RegionCheckStage::perform (int stage, std::vector& m // test for empty name if (region.mName.empty()) - messages.push_back (id.toString() + "|" + region.mId + " has an empty name"); + messages.push_back (std::make_pair (id, region.mId + " has an empty name")); /// \todo test that the ID in mSleeplist exists diff --git a/apps/opencs/model/tools/regioncheck.hpp b/apps/opencs/model/tools/regioncheck.hpp index c8c437cbd..a12903e7d 100644 --- a/apps/opencs/model/tools/regioncheck.hpp +++ b/apps/opencs/model/tools/regioncheck.hpp @@ -21,7 +21,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/reportmodel.cpp b/apps/opencs/model/tools/reportmodel.cpp index d88361746..75545a7c7 100644 --- a/apps/opencs/model/tools/reportmodel.cpp +++ b/apps/opencs/model/tools/reportmodel.cpp @@ -51,16 +51,11 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p return true; } -void CSMTools::ReportModel::add (const std::string& row) +void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::string& message) { - std::string::size_type index = row.find ('|'); - - if (index==std::string::npos) - throw std::logic_error ("invalid report message"); - beginInsertRows (QModelIndex(), mRows.size(), mRows.size()); - mRows.push_back (std::make_pair (row.substr (0, index), row.substr (index+1))); + mRows.push_back (std::make_pair (id, message)); endInsertRows(); } diff --git a/apps/opencs/model/tools/reportmodel.hpp b/apps/opencs/model/tools/reportmodel.hpp index 55c25d907..0f000245e 100644 --- a/apps/opencs/model/tools/reportmodel.hpp +++ b/apps/opencs/model/tools/reportmodel.hpp @@ -28,7 +28,7 @@ namespace CSMTools virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); - void add (const std::string& row); + void add (const CSMWorld::UniversalId& id, const std::string& message); const CSMWorld::UniversalId& getUniversalId (int row) const; }; diff --git a/apps/opencs/model/tools/scriptcheck.cpp b/apps/opencs/model/tools/scriptcheck.cpp index a5154d292..b989e22a2 100644 --- a/apps/opencs/model/tools/scriptcheck.cpp +++ b/apps/opencs/model/tools/scriptcheck.cpp @@ -16,8 +16,6 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); - stream << id.toString() << "|"; - if (type==ErrorMessage) stream << "error "; else @@ -28,25 +26,15 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi << ", line " << loc.mLine << ", column " << loc.mColumn << " (" << loc.mLiteral << "): " << message; - mMessages->push_back (stream.str()); + mMessages->push_back (std::make_pair (id, stream.str())); } void CSMTools::ScriptCheckStage::report (const std::string& message, Type type) { - std::ostringstream stream; - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); - stream << id.toString() << "|"; - - if (type==ErrorMessage) - stream << "error: "; - else - stream << "warning: "; - - stream << message; - - mMessages->push_back (stream.str()); + mMessages->push_back (std::make_pair (id, + (type==ErrorMessage ? "error: " : "warning: ") + message)); } CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMWorld::Data& data) @@ -68,7 +56,7 @@ int CSMTools::ScriptCheckStage::setup() return mData.getScripts().getSize(); } -void CSMTools::ScriptCheckStage::perform (int stage, std::vector& messages) +void CSMTools::ScriptCheckStage::perform (int stage, Messages& messages) { mMessages = &messages; mId = mData.getScripts().getId (stage); @@ -90,13 +78,10 @@ void CSMTools::ScriptCheckStage::perform (int stage, std::vector& m } catch (const std::exception& error) { - std::ostringstream stream; - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); - stream << id.toString() << "|Critical compile error: " << error.what(); - - messages.push_back (stream.str()); + messages.push_back (std::make_pair (id, + std::string ("Critical compile error: ") + error.what())); } mMessages = 0; diff --git a/apps/opencs/model/tools/scriptcheck.hpp b/apps/opencs/model/tools/scriptcheck.hpp index 8de8e1a66..ecf8d61b7 100644 --- a/apps/opencs/model/tools/scriptcheck.hpp +++ b/apps/opencs/model/tools/scriptcheck.hpp @@ -18,7 +18,7 @@ namespace CSMTools CSMWorld::ScriptContext mContext; std::string mId; std::string mFile; - std::vector *mMessages; + Messages *mMessages; virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type); ///< Report error to the user. @@ -33,7 +33,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/skillcheck.cpp b/apps/opencs/model/tools/skillcheck.cpp index 28fc24fd3..630516c72 100644 --- a/apps/opencs/model/tools/skillcheck.cpp +++ b/apps/opencs/model/tools/skillcheck.cpp @@ -16,7 +16,7 @@ int CSMTools::SkillCheckStage::setup() return mSkills.getSize(); } -void CSMTools::SkillCheckStage::perform (int stage, std::vector& messages) +void CSMTools::SkillCheckStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mSkills.getRecord (stage); @@ -32,11 +32,11 @@ void CSMTools::SkillCheckStage::perform (int stage, std::vector& me { std::ostringstream stream; - stream << id.toString() << "|Use value #" << i << " of " << skill.mId << " is negative"; + stream << "Use value #" << i << " of " << skill.mId << " is negative"; - messages.push_back (stream.str()); + messages.push_back (std::make_pair (id, stream.str())); } if (skill.mDescription.empty()) - messages.push_back (id.toString() + "|" + skill.mId + " has an empty description"); + messages.push_back (std::make_pair (id, skill.mId + " has an empty description")); } \ No newline at end of file diff --git a/apps/opencs/model/tools/skillcheck.hpp b/apps/opencs/model/tools/skillcheck.hpp index 662bdadee..cf5d53b5c 100644 --- a/apps/opencs/model/tools/skillcheck.hpp +++ b/apps/opencs/model/tools/skillcheck.hpp @@ -21,7 +21,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index dce2d2b6f..3d222e909 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -16,7 +16,7 @@ int CSMTools::SoundCheckStage::setup() return mSounds.getSize(); } -void CSMTools::SoundCheckStage::perform (int stage, std::vector& messages) +void CSMTools::SoundCheckStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mSounds.getRecord (stage); @@ -28,7 +28,7 @@ void CSMTools::SoundCheckStage::perform (int stage, std::vector& me CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId); if (sound.mData.mMinRange>sound.mData.mMaxRange) - messages.push_back (id.toString() + "|Maximum range larger than minimum range"); + messages.push_back (std::make_pair (id, "Maximum range larger than minimum range")); /// \todo check, if the sound file exists } \ No newline at end of file diff --git a/apps/opencs/model/tools/soundcheck.hpp b/apps/opencs/model/tools/soundcheck.hpp index 00b45cd93..a82a0eb6d 100644 --- a/apps/opencs/model/tools/soundcheck.hpp +++ b/apps/opencs/model/tools/soundcheck.hpp @@ -21,7 +21,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/spellcheck.cpp b/apps/opencs/model/tools/spellcheck.cpp index a2cc7c8d2..3d0be46fd 100644 --- a/apps/opencs/model/tools/spellcheck.cpp +++ b/apps/opencs/model/tools/spellcheck.cpp @@ -17,7 +17,7 @@ int CSMTools::SpellCheckStage::setup() return mSpells.getSize(); } -void CSMTools::SpellCheckStage::perform (int stage, std::vector& messages) +void CSMTools::SpellCheckStage::perform (int stage, Messages& messages) { const CSMWorld::Record& record = mSpells.getRecord (stage); @@ -30,11 +30,11 @@ void CSMTools::SpellCheckStage::perform (int stage, std::vector& me // test for empty name and description if (spell.mName.empty()) - messages.push_back (id.toString() + "|" + spell.mId + " has an empty name"); + messages.push_back (std::make_pair (id, spell.mId + " has an empty name")); // test for invalid cost values if (spell.mData.mCost<0) - messages.push_back (id.toString() + "|" + spell.mId + " has a negative spell costs"); + messages.push_back (std::make_pair (id, spell.mId + " has a negative spell costs")); /// \todo check data members that can't be edited in the table view } \ No newline at end of file diff --git a/apps/opencs/model/tools/spellcheck.hpp b/apps/opencs/model/tools/spellcheck.hpp index 880ddafcd..182f1888b 100644 --- a/apps/opencs/model/tools/spellcheck.hpp +++ b/apps/opencs/model/tools/spellcheck.hpp @@ -21,7 +21,7 @@ namespace CSMTools virtual int setup(); ///< \return number of steps - virtual void perform (int stage, std::vector& messages); + virtual void perform (int stage, Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index d3d8f5fad..ea3568fe2 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -45,8 +45,9 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (mVerifier, SIGNAL (done (int)), this, SIGNAL (done (int))); - connect (mVerifier, SIGNAL (reportMessage (const QString&, int)), - this, SLOT (verifierMessage (const QString&, int))); + connect (mVerifier, + SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)), + this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, int))); std::vector mandatoryIds; // I want C++11, damn it! mandatoryIds.push_back ("Day"); @@ -138,11 +139,12 @@ CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& return mReports.at (id.getIndex()); } -void CSMTools::Tools::verifierMessage (const QString& message, int type) +void CSMTools::Tools::verifierMessage (const CSMWorld::UniversalId& id, const std::string& message, + int type) { std::map::iterator iter = mActiveReports.find (type); if (iter!=mActiveReports.end()) - mReports[iter->second]->add (message.toUtf8().constData()); + mReports[iter->second]->add (id, message); } diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 0079fab34..3394d3f62 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -61,7 +61,8 @@ namespace CSMTools private slots: - void verifierMessage (const QString& message, int type); + void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message, + int type); signals: From cf90da6cd8e2254b4d7f6fe359046329c0cec556 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 May 2014 15:23:29 +0200 Subject: [PATCH 086/121] minor fix --- apps/opencs/model/tools/mandatoryid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/mandatoryid.cpp b/apps/opencs/model/tools/mandatoryid.cpp index 5f245dd4d..412e9f2f0 100644 --- a/apps/opencs/model/tools/mandatoryid.cpp +++ b/apps/opencs/model/tools/mandatoryid.cpp @@ -20,5 +20,5 @@ void CSMTools::MandatoryIdStage::perform (int stage, Messages& messages) if (mIdCollection.searchId (mIds.at (stage))==-1 || mIdCollection.getRecord (mIds.at (stage)).isDeleted()) messages.push_back (std::make_pair (mCollectionId, - "|Missing mandatory record: " + mIds.at (stage))); + "Missing mandatory record: " + mIds.at (stage))); } \ No newline at end of file From 3dfd239b839fc78f21c8e234062918df3e8e7bd2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 May 2014 20:39:58 +0200 Subject: [PATCH 087/121] updated changelog --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 44f15fbcf..7f95003af 100644 --- a/readme.txt +++ b/readme.txt @@ -153,6 +153,7 @@ Feature #58: Sneaking Skill Feature #73: Crime and Punishment Feature #135: Editor: OGRE integration Feature #541: Editor: Dialogue Sub-Views +Feature #853: Editor: Rework User Settings Feature #944: Editor: lighting modes Feature #945: Editor: Camera navigation mode Feature #953: Trader gold From 312dc84fa4743f3a8b40725d6afa4e6b1edb0d94 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 May 2014 20:40:45 +0200 Subject: [PATCH 088/121] Fix a bug where the player's inventory could be opened as a container If an NPC uses AiActivate on the player (i.e. to activate dialogue) precisely in the frame where the player just died, the player's inventory would be opened as a container instead. --- apps/openmw/mwclass/npc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 6a96c955f..b548e0844 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -797,6 +797,10 @@ namespace MWClass boost::shared_ptr Npc::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { + // player got activated by another NPC + if(ptr.getRefData().getHandle() == "player") + return boost::shared_ptr(new MWWorld::ActionTalk(actor)); + if(get(actor).isNpc() && get(actor).getNpcStats(actor).isWerewolf()) { const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); @@ -814,10 +818,6 @@ namespace MWClass if(getCreatureStats(actor).getStance(MWMechanics::CreatureStats::Stance_Sneak)) return boost::shared_ptr(new MWWorld::ActionOpen(ptr)); // stealing - // player got activated by another NPC - if(ptr.getRefData().getHandle() == "player") - return boost::shared_ptr(new MWWorld::ActionTalk(actor)); - return boost::shared_ptr(new MWWorld::ActionTalk(ptr)); } From 6e9458c07617423ae6d5b2f59f705aa1dbf19e4e Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 May 2014 21:04:11 +0200 Subject: [PATCH 089/121] Small fix for dropping items from inventory Some widgets prevented clicking through --- files/mygui/openmw_hud.layout | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/files/mygui/openmw_hud.layout b/files/mygui/openmw_hud.layout index 4f93b42f8..90fa1c8a5 100644 --- a/files/mygui/openmw_hud.layout +++ b/files/mygui/openmw_hud.layout @@ -3,10 +3,8 @@ - - - - + + @@ -54,6 +52,7 @@ + @@ -101,6 +100,7 @@ + From cf23721f1b37bed581f64401689f988685915526 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 9 May 2014 20:43:24 +1000 Subject: [PATCH 090/121] Windows debug build crash fix. --- apps/openmw/mwmechanics/aicombat.cpp | 60 ++++++++++++++-------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index fdaec28b4..84a155225 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -167,7 +167,7 @@ namespace MWMechanics mCombatMove = false; } } - + actor.getClass().getMovementSettings(actor) = mMovement; actor.getClass().getMovementSettings(actor).mRotation[0] = 0; actor.getClass().getMovementSettings(actor).mRotation[2] = 0; @@ -176,7 +176,7 @@ namespace MWMechanics { if(zTurn(actor, Ogre::Degree(mMovement.mRotation[2]))) mMovement.mRotation[2] = 0; } - + if(mMovement.mRotation[0] != 0) { if(smoothTurn(actor, Ogre::Degree(mMovement.mRotation[0]), 0)) mMovement.mRotation[0] = 0; @@ -193,7 +193,7 @@ namespace MWMechanics } //Update with period = tReaction - + mTimerReact = 0; bool cellChange = mCell && (actor.getCell() != mCell); @@ -282,7 +282,7 @@ namespace MWMechanics * * - Distance where attack using the actor's weapon is possible: * longer for ranged weapons (obviously?) vs. melee weapons - * - Determined by weapon's reach parameter; hardcoded value + * - Determined by weapon's reach parameter; hardcoded value * for ranged weapon and for creatures * - Once within this distance mFollowTarget is triggered * @@ -318,15 +318,15 @@ namespace MWMechanics rangeAttack = weapRange; rangeFollow = 300; } - + ESM::Position pos = actor.getRefData().getPosition(); - Ogre::Vector3 vActorPos(pos.pos); + Ogre::Vector3 vActorPos(pos.pos); Ogre::Vector3 vTargetPos(mTarget.getRefData().getPosition().pos); Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos; bool isStuck = false; float speed = 0.0f; - if(mMovement.mPosition[1] && (Ogre::Vector3(mLastPos.pos) - vActorPos).length() < (speed = actorCls.getSpeed(actor)) / 10.0f) + if(mMovement.mPosition[1] && (Ogre::Vector3(mLastPos.pos) - vActorPos).length() < (speed = actorCls.getSpeed(actor)) / 10.0f) isStuck = true; mLastPos = pos; @@ -397,7 +397,7 @@ namespace MWMechanics if(mReadyToAttack) isStuck = false; // check if shortcut is available - if(!isStuck + if(!isStuck && (!mForceNoShortcut || (Ogre::Vector3(mShortcutFailPos.pos) - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST) && inLOS) @@ -454,7 +454,7 @@ namespace MWMechanics { if(!mPathFinder.getPath().empty()) mMovement.mRotation[2] = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); - else + else mMovement.mRotation[2] = getZAngleToDir(vDirToTarget, distToTarget); } } @@ -497,12 +497,12 @@ namespace MWMechanics // coded at 250ms or 1/4 second // // TODO: Add a parameter to vary DURATION_SAME_SPOT? + MWWorld::CellStore *cell = actor.getCell(); if((distToTarget > rangeAttack || mFollowTarget) && mObstacleCheck.check(actor, tReaction)) // check if evasive action needed { // first check if we're walking into a door mDoorCheckDuration += 1.0f; // add time taken for obstacle check - MWWorld::CellStore *cell = actor.getCell(); if(mDoorCheckDuration >= DOOR_CHECK_INTERVAL && !cell->getCell()->isExterior()) { mDoorCheckDuration = 0; @@ -542,28 +542,26 @@ namespace MWMechanics } } - MWWorld::LiveCellRef& ref = *mDoorIter; - float minSqr = 1.6 * 1.6 * MIN_DIST_TO_DOOR_SQUARED; // for legibility - // TODO: add reaction to checking open doors - if(mBackOffDoor && - vActorPos.squaredDistance(Ogre::Vector3(ref.mRef.mPos.pos)) < minSqr) + if(!cell->getCell()->isExterior() && !mDoors.mList.empty()) { - mMovement.mPosition[1] = -0.2; // back off, but slowly + MWWorld::LiveCellRef& ref = *mDoorIter; + float minSqr = 1.6 * 1.6 * MIN_DIST_TO_DOOR_SQUARED; // for legibility + // TODO: add reaction to checking open doors + if(mBackOffDoor && + vActorPos.squaredDistance(Ogre::Vector3(ref.mRef.mPos.pos)) < minSqr) + { + mMovement.mPosition[1] = -0.2; // back off, but slowly + } + else if(mBackOffDoor && + mDoorIter != mDoors.mList.end() && + ref.mData.getLocalRotation().rot[2] >= 1) + { + mDoorIter = mDoors.mList.end(); + mBackOffDoor = false; + //std::cout<<"open door id \""<= 1) - { - mDoorIter = mDoors.mList.end(); - mBackOffDoor = false; - //std::cout<<"open door id \""< Date: Fri, 9 May 2014 17:19:44 +0200 Subject: [PATCH 091/121] adjusted cmake file for opencs user settings file rename --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd437ed61..0c5c156db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -427,7 +427,7 @@ IF(NOT WIN32 AND NOT APPLE) INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") IF(BUILD_OPENCS) - INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${SYSCONFDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "opencs") + INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${SYSCONFDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "opencs") ENDIF(BUILD_OPENCS) # Install resources @@ -456,7 +456,7 @@ if(WIN32) ENDIF(BUILD_MWINIIMPORTER) IF(BUILD_OPENCS) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/opencs.exe" DESTINATION ".") - INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION ".") + INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION ".") ENDIF(BUILD_OPENCS) INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") @@ -663,7 +663,7 @@ if (APPLE) install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) - install(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) + install(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) set(CPACK_GENERATOR "DragNDrop") set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) From 731bc9c27563a73cc8fc4712d87efb908ae42d44 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 9 May 2014 18:45:49 +0200 Subject: [PATCH 092/121] Fix broken isClass check and renamed variable for clarity --- .../openmw/mwmechanics/mechanicsmanagerimp.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 5381af8da..eb51ddfc5 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -825,13 +825,13 @@ namespace MWMechanics commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } - bool MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) + bool MechanicsManager::commitCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, int arg) { // NOTE: int arg can be from itemTaken() so DON'T modify it, since it is // passed to reportCrime later on in this function. // Only player can commit crime - if (ptr.getRefData().getHandle() != "player") + if (player.getRefData().getHandle() != "player") return false; const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); @@ -856,7 +856,7 @@ namespace MWMechanics // Find all the actors within the alarm radius std::vector neighbors; - mActors.getObjectsInRange(Ogre::Vector3(ptr.getRefData().getPosition().pos), + mActors.getObjectsInRange(Ogre::Vector3(player.getRefData().getPosition().pos), esmStore.get().find("fAlarmRadius")->getInt(), neighbors); int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId(); @@ -864,10 +864,10 @@ namespace MWMechanics // Find actors who witnessed the crime for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { - if (*it == ptr) continue; // not the player + if (*it == player) continue; // not the player // Was the crime seen? - if (MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) + if (MWBase::Environment::get().getWorld()->getLOS(player, *it) && awarenessCheck(player, *it) ) { // TODO: Add more messages if (type == OT_Theft) @@ -881,8 +881,8 @@ namespace MWMechanics // This applies to both NPCs and creatures // ... except if this is a guard: then the player is given a chance to pay a fine / go to jail instead - if (type == OT_Assault && !ptr.getClass().isClass(ptr, "guard")) - MWBase::Environment::get().getMechanicsManager()->startCombat(victim, ptr); + if (type == OT_Assault && !it->getClass().isClass(*it, "guard")) + MWBase::Environment::get().getMechanicsManager()->startCombat(victim, player); } // Crime reporting only applies to NPCs @@ -897,7 +897,7 @@ namespace MWMechanics // Tell everyone, including yourself for (std::vector::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1) { - if ( *it1 == ptr + if ( *it1 == player || !it1->getClass().isNpc()) continue; // not the player and is an NPC // Will other witnesses paticipate in crime @@ -914,7 +914,7 @@ namespace MWMechanics } } if (reported) - reportCrime(ptr, victim, type, arg); + reportCrime(player, victim, type, arg); return reported; } From 872d9be1b4ca78e0324d37015c3dee04aec54e6e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 9 May 2014 19:19:21 +0200 Subject: [PATCH 093/121] Fix potential issue with dialogue globals Make sure they are updated throughout the conversation --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index caaf7c91f..8c425caa0 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -144,7 +144,6 @@ namespace MWDialogue //setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI updateTopics(); - updateGlobals(); //greeting const MWWorld::Store &dialogs = @@ -392,6 +391,8 @@ namespace MWDialogue win->setKeywords(keywordList); mChoice = choice; + + updateGlobals(); } void DialogueManager::keywordSelected (const std::string& keyword) From e7a004824c841ccce19acb1748c50543beadce2f Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 9 May 2014 23:58:24 +0200 Subject: [PATCH 094/121] Fix a search that should have been find --- apps/openmw/mwworld/livecellref.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/livecellref.cpp b/apps/openmw/mwworld/livecellref.cpp index 0fbb26c84..f312c2159 100644 --- a/apps/openmw/mwworld/livecellref.cpp +++ b/apps/openmw/mwworld/livecellref.cpp @@ -22,7 +22,7 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) std::string scriptId = mClass->getScript (ptr); mData.setLocals (*MWBase::Environment::get().getWorld()->getStore(). - get().search (scriptId)); + get().find (scriptId)); mData.getLocals().read (state.mLocals, scriptId); } @@ -44,4 +44,4 @@ void MWWorld::LiveCellRefBase::saveImp (ESM::ObjectState& state) const bool MWWorld::LiveCellRefBase::checkStateImp (const ESM::ObjectState& state) { return true; -} \ No newline at end of file +} From 136813a882cbf8fabcf12d2c28c8f7a97126f5f6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 00:00:36 +0200 Subject: [PATCH 095/121] Bug #1319: Fix references not coming from a content file incorrectly overwriting each other --- apps/openmw/mwworld/cellstore.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index e5f0c4b88..1c39d2c07 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -92,14 +92,17 @@ namespace if (!record) return; - for (typename MWWorld::CellRefList::List::iterator iter (collection.mList.begin()); - iter!=collection.mList.end(); ++iter) - if (iter->mRef.mRefNum==state.mRef.mRefNum) - { - // overwrite existing reference - iter->load (state); - return; - } + if (state.mRef.mRefNum.mContentFile != -1) + { + for (typename MWWorld::CellRefList::List::iterator iter (collection.mList.begin()); + iter!=collection.mList.end(); ++iter) + if (iter->mRef.mRefNum==state.mRef.mRefNum) + { + // overwrite existing reference + iter->load (state); + return; + } + } // new reference MWWorld::LiveCellRef ref (record); From 1444cd9051cc37e789f5eb816adb310b33a4291d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 00:37:36 +0200 Subject: [PATCH 096/121] Fix AiCombat exception when actor has a lockpick/probe equipped. Don't make NPCs autoEquip lockpicks/probes, since they can't use them. --- apps/openmw/mwmechanics/aicombat.cpp | 6 +++++- apps/openmw/mwworld/inventorystore.cpp | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index fdaec28b4..08d087069 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -250,6 +250,9 @@ namespace MWMechanics if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) actorCls.getCreatureStats(actor).setDrawState(MWMechanics::DrawState_Weapon); + // TODO: Check equipped weapon and equip a different one if we can't attack with it + // (e.g. no ammunition, or wrong type of ammunition equipped, etc. autoEquip is not very smart in this regard)) + //Get weapon speed and range MWWorld::ContainerStoreIterator weaponSlot = MWMechanics::getActiveWeapon(actorCls.getCreatureStats(actor), actorCls.getInventoryStore(actor), &weaptype); @@ -260,8 +263,9 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->getStore().get(); weapRange = gmst.find("fHandToHandReach")->getFloat(); } - else + else if (weaptype != WeapType_PickProbe && weaptype != WeapType_Spell) { + // All other WeapTypes are actually weapons, so get is safe. weapon = weaponSlot->get()->mBase; weapRange = weapon->mData.mReach; weapSpeed = weapon->mData.mSpeed; diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 9610171b2..b18bda5e3 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -192,12 +192,17 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { Ptr test = *iter; - // Don't autoEquip lights + // Don't autoEquip lights. Handled in Actors::updateEquippedLight based on environment light. if (test.getTypeName() == typeid(ESM::Light).name()) { continue; } + // Don't auto-equip probes or lockpicks. NPCs can't use them (yet). And AiCombat would attempt to "attack" with them. + // NOTE: In the future AiCombat should handle equipping appropriate weapons + if (test.getTypeName() == typeid(ESM::Lockpick).name() || test.getTypeName() == typeid(ESM::Probe).name()) + continue; + // Only autoEquip if we are the original owner of the item. // This stops merchants from auto equipping anything you sell to them. // ...unless this is a companion, he should always equip items given to him. From d86585b153d1c48ffee82c5ad5425be86e7960a6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 01:06:08 +0200 Subject: [PATCH 097/121] Fix clearing of local map markers destroyWidget changes the child count, so the for loop is flawed. --- apps/openmw/mwgui/mapwindow.cpp | 30 +++++++++++++++--------------- apps/openmw/mwgui/mapwindow.hpp | 11 ++++++++--- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 284e5c4e2..6a2228c33 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -86,6 +86,11 @@ namespace MWGui { mFogOfWar = !mFogOfWar; applyFogOfWar(); + + // clear all previous door markers + for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) + MyGUI::Gui::getInstance().destroyWidget(*it); + mDoorMarkerWidgets.clear(); } void LocalMapBase::applyFogOfWar() @@ -172,14 +177,10 @@ namespace MWGui mInterior = interior; mChanged = false; - // clear all previous markers - for (unsigned int i=0; i< mLocalMap->getChildCount(); ++i) - { - if (mLocalMap->getChildAt(i)->getName ().substr (0, 4) == "Door") - { - MyGUI::Gui::getInstance ().destroyWidget (mLocalMap->getChildAt(i)); - } - } + // clear all previous door markers + for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) + MyGUI::Gui::getInstance().destroyWidget(*it); + mDoorMarkerWidgets.clear(); // Update the map textures for (int mx=0; mx<3; ++mx) @@ -243,6 +244,8 @@ namespace MWGui // Used by tooltips to not show the tooltip if marker is hidden by fog of war markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserData(markerPos); + + mDoorMarkerWidgets.push_back(markerWidget); } updateMarkers(); @@ -344,13 +347,9 @@ namespace MWGui void LocalMapBase::updateMarkers() { // clear all previous markers - for (unsigned int i=0; i< mLocalMap->getChildCount(); ++i) - { - if (mLocalMap->getChildAt(i)->getName ().substr (0, 6) == "Marker") - { - MyGUI::Gui::getInstance ().destroyWidget (mLocalMap->getChildAt(i)); - } - } + for (std::vector::iterator it = mMarkerWidgets.begin(); it != mMarkerWidgets.end(); ++it) + MyGUI::Gui::getInstance().destroyWidget(*it); + mMarkerWidgets.clear(); addDetectionMarkers(MWBase::World::Detect_Creature); addDetectionMarkers(MWBase::World::Detect_Key); @@ -373,6 +372,7 @@ namespace MWGui markerWidget->setImageTexture("textures\\menu_map_smark.dds"); markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserData(markerPos); + mMarkerWidgets.push_back(markerWidget); } } diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 7f4f18893..a28c71ac9 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -55,12 +55,13 @@ namespace MWGui bool mChanged; bool mFogOfWar; - typedef std::pair CellId; - std::vector mMarkers; - std::vector mMapWidgets; std::vector mFogWidgets; + // Keep track of created marker widgets, just to easily remove them later. + std::vector mDoorMarkerWidgets; // Doors + std::vector mMarkerWidgets; // Other markers + void applyFogOfWar(); void onMarkerFocused(MyGUI::Widget* w1, MyGUI::Widget* w2); @@ -127,6 +128,10 @@ namespace MWGui MyGUI::IntPoint mLastDragPos; bool mGlobal; + // Markers on global map + typedef std::pair CellId; + std::vector mMarkers; + MyGUI::Button* mEventBoxGlobal; MyGUI::Button* mEventBoxLocal; From 516335847879db3c1e3db3e0005bfa69b980e625 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 01:14:12 +0200 Subject: [PATCH 098/121] Fix a crash when exiting OpenMW while the mouse cursor is over a local map marker --- apps/openmw/mwgui/mapwindow.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 6a2228c33..89517d7d1 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -41,6 +41,13 @@ namespace MWGui LocalMapBase::~LocalMapBase() { + // Clear our "lost focus" delegate for marker widgets first, otherwise it will + // fire when the widget is about to be destroyed and the mouse cursor is over it. + // At that point, other widgets may already be destroyed, so applyFogOfWar (which is called by the delegate) would crash. + for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) + (*it)->eventMouseLostFocus.clear(); + for (std::vector::iterator it = mMarkerWidgets.begin(); it != mMarkerWidgets.end(); ++it) + (*it)->eventMouseLostFocus.clear(); } void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop) From 242e19a136e44a6f913846224b9136fb92c61367 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 01:37:34 +0200 Subject: [PATCH 099/121] Fix crash when exiting OpenMW while dialogue/journal is opened and mouse cursor on a topic (Fixes #1300) --- apps/openmw/mwgui/bookpage.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/bookpage.cpp b/apps/openmw/mwgui/bookpage.cpp index 52682342f..6545b5d45 100644 --- a/apps/openmw/mwgui/bookpage.cpp +++ b/apps/openmw/mwgui/bookpage.cpp @@ -783,7 +783,8 @@ public: ActiveTextFormats::iterator i = mActiveTextFormats.find (Font); - mNode->outOfDate (i->second->mRenderItem); + if (mNode) + mNode->outOfDate (i->second->mRenderItem); } } @@ -1125,6 +1126,8 @@ public: protected: void onMouseLostFocus(Widget* _new) { + // NOTE: MyGUI also fires eventMouseLostFocus for widgets that are about to be destroyed (if they had focus). + // Child widgets may already be destroyed! So be careful. if (PageDisplay* pd = dynamic_cast (getSubWidgetText ())) { pd->onMouseLostFocus (); From 7500895519d63264b98fcede265450170b574c78 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 10:52:23 +0200 Subject: [PATCH 100/121] updated changelog --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 7f95003af..4db9425b6 100644 --- a/readme.txt +++ b/readme.txt @@ -148,6 +148,7 @@ Bug #1296: Caius doesn't leave at start of quest "Mehra Milo and the Lost Prophe Bug #1297: Saved game: map markers Bug #1302: ring_keley script causes vector::_M_range_check exception Bug #1309: Bug on "You violated the law" dialog +Bug #1319: Creatures sometimes rendered incorrectly Feature #50: Ranged Combat Feature #58: Sneaking Skill Feature #73: Crime and Punishment From aadaf7827ddfe0be49a9e4ca2afe5646b2c1c723 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 12:04:36 +0200 Subject: [PATCH 101/121] added load error log --- apps/opencs/model/doc/loader.cpp | 12 +++++++++++- apps/opencs/model/doc/state.hpp | 21 +++++++++++---------- apps/opencs/model/tools/tools.cpp | 6 +++++- apps/opencs/model/world/data.cpp | 2 +- apps/opencs/model/world/data.hpp | 4 +++- apps/opencs/model/world/universalid.cpp | 1 + apps/opencs/model/world/universalid.hpp | 5 +++-- apps/opencs/view/doc/view.cpp | 16 ++++++++++++++-- apps/opencs/view/doc/view.hpp | 2 ++ apps/opencs/view/tools/subviews.cpp | 2 ++ 10 files changed, 53 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 2ef808dd6..e2427e62d 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -3,7 +3,10 @@ #include +#include "../tools/reportmodel.hpp" + #include "document.hpp" +#include "state.hpp" CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLeft (false) {} @@ -48,13 +51,20 @@ void CSMDoc::Loader::load() { if (iter->second.mRecordsLeft) { + CSMDoc::Stage::Messages messages; for (int i=0; igetData().continueLoading()) + if (document->getData().continueLoading (messages)) { iter->second.mRecordsLeft = false; break; } + CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0); + + for (CSMDoc::Stage::Messages::const_iterator iter (messages.begin()); + iter!=messages.end(); ++iter) + document->getReport (log)->add (iter->first, iter->second); + emit nextRecord (document); return; diff --git a/apps/opencs/model/doc/state.hpp b/apps/opencs/model/doc/state.hpp index 04e6fae89..6e1a1c4f4 100644 --- a/apps/opencs/model/doc/state.hpp +++ b/apps/opencs/model/doc/state.hpp @@ -3,17 +3,18 @@ namespace CSMDoc { - enum State - { - State_Modified = 1, - State_Locked = 2, - State_Operation = 4, + enum State + { + State_Modified = 1, + State_Locked = 2, + State_Operation = 4, - State_Saving = 8, - State_Verifying = 16, - State_Compiling = 32, // not implemented yet - State_Searching = 64 // not implemented yet - }; + State_Saving = 8, + State_Verifying = 16, + State_Compiling = 32, // not implemented yet + State_Searching = 64, // not implemented yet + State_Loading = 128 // pseudo-state; can not be encountered in a loaded document + }; } #endif diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index a11297b45..2f93db48e 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -88,6 +88,9 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0) { + // index 0: load error log + mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); + mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0)); } CSMTools::Tools::~Tools() @@ -134,7 +137,8 @@ int CSMTools::Tools::getRunningOperations() const CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id) { - if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults) + if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults && + id.getType()!=CSMWorld::UniversalId::Type_LoadErrorLog) throw std::logic_error ("invalid request for report model: " + id.toString()); return mReports.at (id.getIndex()); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 885e23033..2de58675f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -505,7 +505,7 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base return mReader->getRecordCount(); } -bool CSMWorld::Data::continueLoading() +bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) { if (!mReader) throw std::logic_error ("can't continue loading, because no load has been started"); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 234069e3a..4f7c624e6 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -24,6 +24,8 @@ #include "../filter/filter.hpp" +#include "../doc/stage.hpp" + #include "idcollection.hpp" #include "universalid.hpp" #include "cell.hpp" @@ -185,7 +187,7 @@ namespace CSMWorld /// ///< \return estimated number of records - bool continueLoading(); + bool continueLoading (CSMDoc::Stage::Messages& messages); ///< \return Finished? bool hasId (const std::string& id) const; diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 94b042ec5..7471e5cec 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -101,6 +101,7 @@ namespace static const TypeData sIndexArg[] = { { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 }, + { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; } diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 24fb54399..22779b263 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -97,10 +97,11 @@ namespace CSMWorld Type_JournalInfos, Type_JournalInfo, Type_Scene, - Type_Preview + Type_Preview, + Type_LoadErrorLog }; - enum { NumberOfTypes = Type_Scene+1 }; + enum { NumberOfTypes = Type_LoadErrorLog+1 }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 95ab6ca27..e71b8435a 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -10,9 +10,12 @@ #include #include "../../model/doc/document.hpp" -#include "../world/subviews.hpp" -#include "../tools/subviews.hpp" #include "../../model/settings/usersettings.hpp" + +#include "../world/subviews.hpp" + +#include "../tools/subviews.hpp" + #include "viewmanager.hpp" #include "operations.hpp" #include "subview.hpp" @@ -47,6 +50,10 @@ void CSVDoc::View::setupFileMenu() connect (mVerify, SIGNAL (triggered()), this, SLOT (verify())); file->addAction (mVerify); + QAction *loadErrors = new QAction (tr ("Load Error Log"), this); + connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog())); + file->addAction (loadErrors); + QAction *close = new QAction (tr ("&Close"), this); connect (close, SIGNAL (triggered()), this, SLOT (close())); file->addAction(close); @@ -502,3 +509,8 @@ void CSVDoc::View::toggleShowStatusBar (bool show) subView->setStatusBar (show); } } + +void CSVDoc::View::loadErrorLog() +{ + addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_LoadErrorLog, 0)); +} diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 5e6c9abc4..686c001dc 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -179,6 +179,8 @@ namespace CSVDoc void addJournalInfosSubView(); void toggleShowStatusBar (bool show); + + void loadErrorLog(); }; } diff --git a/apps/opencs/view/tools/subviews.cpp b/apps/opencs/view/tools/subviews.cpp index 781cf602e..8b04aca50 100644 --- a/apps/opencs/view/tools/subviews.cpp +++ b/apps/opencs/view/tools/subviews.cpp @@ -9,4 +9,6 @@ void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) { manager.add (CSMWorld::UniversalId::Type_VerificationResults, new CSVDoc::SubViewFactory); + manager.add (CSMWorld::UniversalId::Type_LoadErrorLog, + new CSVDoc::SubViewFactory); } \ No newline at end of file From 95d24492de4f630037202881fa655cb44d4c971c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 13:18:40 +0200 Subject: [PATCH 102/121] display load error messages in loading window --- apps/opencs/model/doc/documentmanager.cpp | 2 ++ apps/opencs/model/doc/documentmanager.hpp | 2 ++ apps/opencs/model/doc/loader.cpp | 3 +++ apps/opencs/model/doc/loader.hpp | 3 +++ apps/opencs/view/doc/loader.cpp | 19 +++++++++++++++++++ apps/opencs/view/doc/loader.hpp | 6 ++++++ apps/opencs/view/doc/viewmanager.cpp | 4 ++++ 7 files changed, 39 insertions(+) diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index fe6aaef27..d4f8eb110 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -35,6 +35,8 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con this, SIGNAL (nextRecord (CSMDoc::Document *))); connect (this, SIGNAL (cancelLoading (CSMDoc::Document *)), &mLoader, SLOT (abortLoading (CSMDoc::Document *))); + connect (&mLoader, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)), + this, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&))); } CSMDoc::DocumentManager::~DocumentManager() diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index de4a5e94b..7b3a811fa 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -79,6 +79,8 @@ namespace CSMDoc void nextRecord (CSMDoc::Document *document); void cancelLoading (CSMDoc::Document *document); + + void loadMessage (CSMDoc::Document *document, const std::string& message); }; } diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index e2427e62d..c106c06e8 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -63,7 +63,10 @@ void CSMDoc::Loader::load() for (CSMDoc::Stage::Messages::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter) + { document->getReport (log)->add (iter->first, iter->second); + emit loadMessage (document, iter->second); + } emit nextRecord (document); diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index a6bcb6b87..c276e14ff 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -62,6 +62,9 @@ namespace CSMDoc ///< \note This signal is only given once per group of records. The group size is /// approximately the total number of records divided by the steps value of the /// previous nextStage signal. + + void loadMessage (CSMDoc::Document *document, const std::string& message); + ///< Non-critical load error or warning }; } diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 1b2ca8ad5..0a99d434a 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../../model/doc/document.hpp" @@ -58,6 +59,11 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) layout->addWidget (mError); + // other messages + mMessages = new QListWidget (this); + + layout->addWidget (mMessages); + // buttons mButtons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this); @@ -97,6 +103,11 @@ void CSVDoc::LoadingDocument::abort (const std::string& error) mButtons->setStandardButtons (QDialogButtonBox::Close); } +void CSVDoc::LoadingDocument::addMessage (const std::string& message) +{ + new QListWidgetItem (QString::fromUtf8 (message.c_str()), mMessages); +} + void CSVDoc::LoadingDocument::cancel() { if (!mAborted) @@ -168,4 +179,12 @@ void CSVDoc::Loader::nextRecord (CSMDoc::Document *document) if (iter!=mDocuments.end()) iter->second->nextRecord(); +} + +void CSVDoc::Loader::loadMessage (CSMDoc::Document *document, const std::string& message) +{ + std::map::iterator iter = mDocuments.find (document); + + if (iter!=mDocuments.end()) + iter->second->addMessage (message); } \ No newline at end of file diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index ece071755..ab2cec548 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -10,6 +10,7 @@ class QLabel; class QProgressBar; class QDialogButtonBox; +class QListWidget; namespace CSMDoc { @@ -29,6 +30,7 @@ namespace CSVDoc bool mAborted; QDialogButtonBox *mButtons; QLabel *mError; + QListWidget *mMessages; private: @@ -44,6 +46,8 @@ namespace CSVDoc void abort (const std::string& error); + void addMessage (const std::string& message); + private slots: void cancel(); @@ -85,6 +89,8 @@ namespace CSVDoc void nextStage (CSMDoc::Document *document, const std::string& name, int steps); void nextRecord (CSMDoc::Document *document); + + void loadMessage (CSMDoc::Document *document, const std::string& message); }; } diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 816eff791..02f6a5467 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -100,6 +100,10 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) &mDocumentManager, SIGNAL (nextRecord (CSMDoc::Document *)), &mLoader, SLOT (nextRecord (CSMDoc::Document *))); + connect ( + &mDocumentManager, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)), + &mLoader, SLOT (loadMessage (CSMDoc::Document *, const std::string&))); + connect ( &mLoader, SIGNAL (cancel (CSMDoc::Document *)), &mDocumentManager, SIGNAL (cancelLoading (CSMDoc::Document *))); From 79d59153c14303a14931a648722cc818731d7c40 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 13:29:28 +0200 Subject: [PATCH 103/121] improved layout of loading window --- apps/opencs/view/doc/loader.cpp | 31 +++++++++++++++++-------------- apps/opencs/view/doc/loader.hpp | 2 ++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 0a99d434a..7e4754ddf 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -18,20 +18,22 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) } CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) -: mDocument (document), mAborted (false) +: mDocument (document), mAborted (false), mMessages (0) { setWindowTitle (("Opening " + document->getSavePath().filename().string()).c_str()); - QVBoxLayout *layout = new QVBoxLayout (this); + setMinimumWidth (400); + + mLayout = new QVBoxLayout (this); // file progress mFile = new QLabel (this); - layout->addWidget (mFile); + mLayout->addWidget (mFile); mFileProgress = new QProgressBar (this); - layout->addWidget (mFileProgress); + mLayout->addWidget (mFileProgress); int size = static_cast (document->getContentFiles().size())+1; if (document->isNew()) @@ -43,11 +45,11 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) mFileProgress->setValue (0); // record progress - layout->addWidget (new QLabel ("Records", this)); + mLayout->addWidget (new QLabel ("Records", this)); mRecordProgress = new QProgressBar (this); - layout->addWidget (mRecordProgress); + mLayout->addWidget (mRecordProgress); mRecordProgress->setMinimum (0); mRecordProgress->setTextVisible (true); @@ -57,19 +59,14 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) mError = new QLabel (this); mError->setWordWrap (true); - layout->addWidget (mError); - - // other messages - mMessages = new QListWidget (this); - - layout->addWidget (mMessages); + mLayout->addWidget (mError); // buttons mButtons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this); - layout->addWidget (mButtons); + mLayout->addWidget (mButtons); - setLayout (layout); + setLayout (mLayout); move (QCursor::pos()); @@ -105,6 +102,12 @@ void CSVDoc::LoadingDocument::abort (const std::string& error) void CSVDoc::LoadingDocument::addMessage (const std::string& message) { + if (!mMessages) + { + mMessages = new QListWidget (this); + mLayout->insertWidget (4, mMessages); + } + new QListWidgetItem (QString::fromUtf8 (message.c_str()), mMessages); } diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index ab2cec548..69a8b48ba 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -11,6 +11,7 @@ class QLabel; class QProgressBar; class QDialogButtonBox; class QListWidget; +class QVBoxLayout; namespace CSMDoc { @@ -31,6 +32,7 @@ namespace CSVDoc QDialogButtonBox *mButtons; QLabel *mError; QListWidget *mMessages; + QVBoxLayout *mLayout; private: From 96ca9500ca1870ee2d6a4ebea8ea19c6dea013eb Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 13:47:22 +0200 Subject: [PATCH 104/121] generate error messages when encounting non-critical problems during load --- apps/opencs/model/world/data.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 2de58675f..3e9fe11eb 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -592,7 +592,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) } else { - /// \todo report deletion of non-existing record + messages.push_back (std::make_pair (UniversalId::Type_None, + "Trying to delete dialogue record " + id + " which does not exist")); } } else @@ -608,7 +609,9 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) { if (!mDialogue) { - /// \todo INFO record without matching DIAL record -> report to user + messages.push_back (std::make_pair (UniversalId::Type_None, + "Found info record not following a dialogue record")); + mReader->skipRecord(); break; } @@ -636,8 +639,9 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) default: - /// \todo throw an exception instead, once all records are implemented - /// or maybe report error and continue? + messages.push_back (std::make_pair (UniversalId::Type_None, + "Unsupported record type: " + n.toString())); + mReader->skipRecord(); } From 6fdbd4d3f9e54c0c545a89ddbd62f484c45d0f95 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 13:49:19 +0200 Subject: [PATCH 105/121] minor adjustment to UniversalId --- apps/opencs/model/world/universalid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 7471e5cec..140a410c0 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -18,7 +18,7 @@ namespace static const TypeData sNoArg[] = { - { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty", 0 }, + { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "-", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills", 0 }, From 804bf523bac3be304e3a83512c8a8b8fd225d40d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 17:35:11 +0200 Subject: [PATCH 106/121] removed two unused files --- apps/opencs/view/doc/opendialog.cpp | 62 ----------------------------- apps/opencs/view/doc/opendialog.hpp | 17 -------- 2 files changed, 79 deletions(-) delete mode 100644 apps/opencs/view/doc/opendialog.cpp delete mode 100644 apps/opencs/view/doc/opendialog.hpp diff --git a/apps/opencs/view/doc/opendialog.cpp b/apps/opencs/view/doc/opendialog.cpp deleted file mode 100644 index d107b198c..000000000 --- a/apps/opencs/view/doc/opendialog.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include - -#include - -#include "opendialog.hpp" - -OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent) -{ - QVBoxLayout *layout = new QVBoxLayout(this); - mFileSelector = new DataFilesList(mCfgMgr, this); - layout->addWidget(mFileSelector); - - /// \todo move config to Editor class and add command line options. - // We use the Configuration Manager to retrieve the configuration values - boost::program_options::variables_map variables; - boost::program_options::options_description desc; - - desc.add_options() - ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()) - ("data-local", boost::program_options::value()->default_value("")) - ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) - ("encoding", boost::program_options::value()->default_value("win1252")); - - boost::program_options::notify(variables); - - mCfgMgr.readConfiguration(variables, desc); - - Files::PathContainer mDataDirs, mDataLocal; - if (!variables["data"].empty()) { - mDataDirs = Files::PathContainer(variables["data"].as()); - } - - std::string local = variables["data-local"].as(); - if (!local.empty()) { - mDataLocal.push_back(Files::PathContainer::value_type(local)); - } - - mCfgMgr.processPaths(mDataDirs); - mCfgMgr.processPaths(mDataLocal); - - // Set the charset for reading the esm/esp files - QString encoding = QString::fromUtf8 (variables["encoding"].as().c_str()); - - Files::PathContainer dataDirs; - dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end()); - dataDirs.insert(dataDirs.end(), mDataLocal.begin(), mDataLocal.end()); - mFileSelector->setupDataFiles(dataDirs, encoding); - - buttonBox = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Cancel, Qt::Horizontal, this); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - layout->addWidget(buttonBox); - - setLayout(layout); - setWindowTitle(tr("Open")); -} - -void OpenDialog::getFileList(std::vector& paths) -{ - mFileSelector->selectedFiles(paths); -} diff --git a/apps/opencs/view/doc/opendialog.hpp b/apps/opencs/view/doc/opendialog.hpp deleted file mode 100644 index 6355aea44..000000000 --- a/apps/opencs/view/doc/opendialog.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include - -class DataFilesList; -class QDialogButtonBox; - -class OpenDialog : public QDialog { - Q_OBJECT -public: - OpenDialog(QWidget * parent = 0); - - void getFileList(std::vector& paths); -private: - DataFilesList * mFileSelector; - QDialogButtonBox * buttonBox; - Files::ConfigurationManager mCfgMgr; -}; \ No newline at end of file From 5b5bf6f37e4573babac9dd97adfc254869791c61 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 May 2014 17:46:10 +0200 Subject: [PATCH 107/121] removed a redundant (and unsufficiently configured) copy of ConfigurationManager --- apps/opencs/editor.cpp | 2 +- apps/opencs/model/settings/usersettings.cpp | 3 ++- apps/opencs/model/settings/usersettings.hpp | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index ad6c4be3d..57d2f4730 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -20,7 +20,7 @@ #include "model/world/data.hpp" CS::Editor::Editor (OgreInit::OgreInit& ogreInit) -: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), +: mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), mIpcServerName ("org.openmw.OpenCS") { std::pair > config = readConfig(); diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 1a9125439..04f98f0d6 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -28,7 +28,8 @@ namespace boost CSMSettings::UserSettings *CSMSettings::UserSettings::mUserSettingsInstance = 0; -CSMSettings::UserSettings::UserSettings() +CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager) +: mCfgMgr (configurationManager) { assert(!mUserSettingsInstance); mUserSettingsInstance = this; diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 830cc8c69..7e553caf6 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -30,7 +30,7 @@ namespace CSMSettings { Q_OBJECT static UserSettings *mUserSettingsInstance; - Files::ConfigurationManager mCfgMgr; + const Files::ConfigurationManager& mCfgMgr; QSettings *mSettingDefinitions; QList mSettings; @@ -40,11 +40,11 @@ namespace CSMSettings { /// Singleton implementation static UserSettings& instance(); - UserSettings(); + UserSettings (const Files::ConfigurationManager& configurationManager); ~UserSettings(); - UserSettings (UserSettings const &); //not implemented - void operator= (UserSettings const &); //not implemented + UserSettings (UserSettings const &); //not implemented + UserSettings& operator= (UserSettings const &); //not implemented /// Retrieves the settings file at all three levels (global, local and user). void loadSettings (const QString &fileName); From 9fb5cef287e2e518df7c6c58c73722c18721c528 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 15:40:00 +0200 Subject: [PATCH 108/121] Oops, committed debug code --- apps/openmw/mwgui/mapwindow.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 89517d7d1..a4cd61c84 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -93,11 +93,6 @@ namespace MWGui { mFogOfWar = !mFogOfWar; applyFogOfWar(); - - // clear all previous door markers - for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) - MyGUI::Gui::getInstance().destroyWidget(*it); - mDoorMarkerWidgets.clear(); } void LocalMapBase::applyFogOfWar() From b358cf24230e4438767aaae23fc914921a29ab25 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 18:14:35 +0200 Subject: [PATCH 109/121] Fix a potential crash when loading script locals from savegame --- apps/openmw/mwworld/livecellref.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/livecellref.cpp b/apps/openmw/mwworld/livecellref.cpp index f312c2159..4a610b45c 100644 --- a/apps/openmw/mwworld/livecellref.cpp +++ b/apps/openmw/mwworld/livecellref.cpp @@ -20,10 +20,15 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) if (state.mHasLocals) { std::string scriptId = mClass->getScript (ptr); - - mData.setLocals (*MWBase::Environment::get().getWorld()->getStore(). - get().find (scriptId)); - mData.getLocals().read (state.mLocals, scriptId); + // Make sure we still have a script. It could have been coming from a content file that is no longer active. + if (!scriptId.empty()) + { + if (const ESM::Script* script = MWBase::Environment::get().getWorld()->getStore().get().search (scriptId)) + { + mData.setLocals (*script); + mData.getLocals().read (state.mLocals, scriptId); + } + } } mClass->readAdditionalState (ptr, state); From 9095a45ba7d5280b63b89d338b9fc1911ebd72ac Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Sat, 10 May 2014 17:05:15 -0400 Subject: [PATCH 110/121] Bug 1047 Fix Dialog links can no longer be highlighted if they appear in the middle of the word. This is achieved by confirming that the character before a match is not alphabetic, so that words following hyphens can still potentially match. --- apps/openmw/mwgui/dialogue.cpp | 3 ++- apps/openmw/mwgui/keywordsearch.hpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 6c43f47b4..6ee329aa7 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -162,7 +162,8 @@ namespace MWGui { std::string::const_iterator i = text.begin (); KeywordSearchT::Match match; - while (i != text.end () && keywordSearch->search (i, text.end (), match)) + + while (i != text.end () && keywordSearch->search (i, text.end (), match, false)) { if (i != match.mBeg) addTopicLink (typesetter, 0, i - text.begin (), match.mBeg - text.begin ()); diff --git a/apps/openmw/mwgui/keywordsearch.hpp b/apps/openmw/mwgui/keywordsearch.hpp index a9fb6daab..be118597c 100644 --- a/apps/openmw/mwgui/keywordsearch.hpp +++ b/apps/openmw/mwgui/keywordsearch.hpp @@ -66,10 +66,19 @@ public: return false; } - bool search (Point beg, Point end, Match & match) + bool search (Point beg, Point end, Match & match, bool matchSubword = true) { + char prev = ' '; for (Point i = beg; i != end; ++i) { + // check if previous character marked start of new word + if (!matchSubword && isalpha(prev)) + { + prev = *i; + continue; + } + prev = *i; + // check first character typename Entry::childen_t::iterator candidate = mRoot.mChildren.find (std::tolower (*i, mLocale)); From dab4db87fff2866e215833c2e93751f5510de511 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 May 2014 23:47:00 +0200 Subject: [PATCH 111/121] Fix a bug in marker placement for interior maps --- apps/openmw/mwgui/mapwindow.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index a4cd61c84..b6b1bd89a 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -160,8 +160,9 @@ namespace MWGui markerPos.cellX = cellX; markerPos.cellY = cellY; - widgetPos = MyGUI::IntPoint(nX * 512 + (1+cellX-mCurX) * 512, - nY * 512 + (1+cellY-mCurY) * 512); + // Image space is -Y up, cells are Y up + widgetPos = MyGUI::IntPoint(nX * 512 + (1+(cellX-mCurX)) * 512, + nY * 512 + (1-(cellY-mCurY)) * 512); } markerPos.nX = nX; From eb5ef270baa4ad051ded63169bd1663e3f421388 Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Sat, 10 May 2014 17:47:21 -0400 Subject: [PATCH 112/121] Bug 1047 update - defaults and edge case Handles edge case where it was possible to highlight adjacent sub-terms without whitespace between them. Also makes ignoring words not prefixed by whitespace the assumed behaviour. --- apps/openmw/mwgui/dialogue.cpp | 2 +- apps/openmw/mwgui/journalviewmodel.cpp | 2 +- apps/openmw/mwgui/keywordsearch.hpp | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 6ee329aa7..e5b225791 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -163,7 +163,7 @@ namespace MWGui std::string::const_iterator i = text.begin (); KeywordSearchT::Match match; - while (i != text.end () && keywordSearch->search (i, text.end (), match, false)) + while (i != text.end () && keywordSearch->search (i, text.end (), match, text.begin ())) { if (i != match.mBeg) addTopicLink (typesetter, 0, i - text.begin (), match.mBeg - text.begin ()); diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index c6bd6d15d..5994c6e21 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -178,7 +178,7 @@ struct JournalViewModelImpl : JournalViewModel KeywordSearchT::Match match; - while (i != utf8text.end () && mModel->mKeywordSearch.search (i, utf8text.end (), match)) + while (i != utf8text.end () && mModel->mKeywordSearch.search (i, utf8text.end (), match, utf8text.begin())) { if (i != match.mBeg) visitor (0, i - utf8text.begin (), match.mBeg - utf8text.begin ()); diff --git a/apps/openmw/mwgui/keywordsearch.hpp b/apps/openmw/mwgui/keywordsearch.hpp index be118597c..4f4459b35 100644 --- a/apps/openmw/mwgui/keywordsearch.hpp +++ b/apps/openmw/mwgui/keywordsearch.hpp @@ -66,18 +66,18 @@ public: return false; } - bool search (Point beg, Point end, Match & match, bool matchSubword = true) + bool search (Point beg, Point end, Match & match, Point start) { - char prev = ' '; for (Point i = beg; i != end; ++i) { // check if previous character marked start of new word - if (!matchSubword && isalpha(prev)) + if (i != start) { - prev = *i; - continue; + Point prev = i; + --prev; + if(isalpha(*prev)) + continue; } - prev = *i; // check first character typename Entry::childen_t::iterator candidate = mRoot.mChildren.find (std::tolower (*i, mLocale)); From 3ad28ec5aad024f2338e23e78c644ee826258b2a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 11 May 2014 00:09:02 +0200 Subject: [PATCH 113/121] Set a proper Page size for all scrollbars. Fixes scrollbars only moving very slowly when interacting with them (as opposed to using mousewheel on the content) --- files/mygui/openmw_list.skin.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index 7972527ac..4dbc3da45 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -10,6 +10,10 @@ + + + + @@ -47,6 +51,10 @@ + + + + From 07d9845aa00a3c467c1df9d9ac114b6f45106b52 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 11 May 2014 00:10:28 +0200 Subject: [PATCH 114/121] Fix a bug in ESMStore code that checks for duplicate record insertions --- apps/openmw/mwworld/esmstore.hpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index ea6d3d006..c6c9c1ffe 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -166,16 +166,17 @@ namespace MWWorld template const T *insert(const T &x) { + std::ostringstream id; + id << "$dynamic" << mDynamicCount++; + Store &store = const_cast &>(get()); - if (store.search(x.mId) != 0) { + if (store.search(id.str()) != 0) { std::ostringstream msg; - msg << "Try to override existing record '" << x.mId << "'"; + msg << "Try to override existing record '" << id.str() << "'"; throw std::runtime_error(msg.str()); } T record = x; - std::ostringstream id; - id << "$dynamic" << mDynamicCount++; record.mId = id.str(); T *ptr = store.insert(record); @@ -189,10 +190,13 @@ namespace MWWorld template const T *insertStatic(const T &x) { + std::ostringstream id; + id << "$dynamic" << mDynamicCount++; + Store &store = const_cast &>(get()); - if (store.search(x.mId) != 0) { + if (store.search(id.str()) != 0) { std::ostringstream msg; - msg << "Try to override existing record '" << x.mId << "'"; + msg << "Try to override existing record '" << id.str() << "'"; throw std::runtime_error(msg.str()); } T record = x; @@ -225,17 +229,18 @@ namespace MWWorld template <> inline const ESM::NPC *ESMStore::insert(const ESM::NPC &npc) { + std::ostringstream id; + id << "$dynamic" << mDynamicCount++; + if (Misc::StringUtils::ciEqual(npc.mId, "player")) { return mNpcs.insert(npc); - } else if (mNpcs.search(npc.mId) != 0) { + } else if (mNpcs.search(id.str()) != 0) { std::ostringstream msg; - msg << "Try to override existing record '" << npc.mId << "'"; + msg << "Try to override existing record '" << id.str() << "'"; throw std::runtime_error(msg.str()); } ESM::NPC record = npc; - std::ostringstream id; - id << "$dynamic" << mDynamicCount++; record.mId = id.str(); ESM::NPC *ptr = mNpcs.insert(record); From 041319c43e4fcf059c7bcc28976e504c08fd3820 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 11 May 2014 00:32:22 +0200 Subject: [PATCH 115/121] Fixes #1234: Store dynamic record counter in savegame to prevent name clashes --- apps/openmw/mwstate/statemanagerimp.cpp | 1 + apps/openmw/mwworld/esmstore.cpp | 16 ++++++++++++++-- components/esm/defs.hpp | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index c718eeced..c89041710 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -314,6 +314,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl case ESM::REC_PLAY: case ESM::REC_CSTA: case ESM::REC_WTHR: + case ESM::REC_DYNA: MWBase::Environment::get().getWorld()->readRecord (reader, n.val, contentFileMap); break; diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index ebe0aa08a..a769e7f67 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -141,8 +141,8 @@ void ESMStore::setUp() int ESMStore::countSavedGameRecords() const { - return - mPotions.getDynamicSize() + return 1 // DYNA (dynamic name counter) + +mPotions.getDynamicSize() +mArmors.getDynamicSize() +mBooks.getDynamicSize() +mClasses.getDynamicSize() @@ -155,6 +155,13 @@ void ESMStore::setUp() void ESMStore::write (ESM::ESMWriter& writer, Loading::Listener& progress) const { + writer.startRecord(ESM::REC_DYNA); + writer.startSubRecord("COUN"); + writer.writeT(mDynamicCount); + writer.endRecord("COUN"); + writer.endRecord(ESM::REC_DYNA); + progress.increaseProgress(); + mPotions.write (writer, progress); mArmors.write (writer, progress); mBooks.write (writer, progress); @@ -197,6 +204,11 @@ void ESMStore::setUp() return true; + case ESM::REC_DYNA: + reader.getSubNameIs("COUN"); + reader.getHT(mDynamicCount); + return true; + default: return false; diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index b2a1637f1..5a99d0c2e 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -100,6 +100,7 @@ enum RecNameInts REC_DIAS = 0x53414944, REC_WTHR = 0x52485457, REC_KEYS = FourCC<'K','E','Y','S'>::value, + REC_DYNA = FourCC<'D','Y','N','A'>::value, // format 1 REC_FILT = 0x544C4946 From 7b46e9f914228e02c1702f785c57fdb17ea651aa Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 11 May 2014 01:05:49 +0200 Subject: [PATCH 116/121] Get rid of no longer needed widget names --- apps/openmw/mwgui/mapwindow.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index b6b1bd89a..dc22dcb22 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -65,11 +65,11 @@ namespace MWGui { MyGUI::ImageBox* map = mLocalMap->createWidget("ImageBox", MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize), - MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast(mx) + "_" + boost::lexical_cast(my)); + MyGUI::Align::Top | MyGUI::Align::Left); MyGUI::ImageBox* fog = map->createWidget("ImageBox", MyGUI::IntCoord(0, 0, widgetSize, widgetSize), - MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast(mx) + "_" + boost::lexical_cast(my) + "_fog"); + MyGUI::Align::Top | MyGUI::Align::Left); if (!mMapDragAndDrop) { @@ -237,7 +237,7 @@ namespace MWGui 8, 8); ++counter; MyGUI::Button* markerWidget = mLocalMap->createWidget("ButtonImage", - widgetCoord, MyGUI::Align::Default, "Door" + boost::lexical_cast(counter)); + widgetCoord, MyGUI::Align::Default); markerWidget->setImageResource("DoorMarker"); markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); @@ -339,7 +339,7 @@ namespace MWGui 8, 8); ++counter; MyGUI::ImageBox* markerWidget = mLocalMap->createWidget("ImageBox", - widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast(counter)); + widgetCoord, MyGUI::Align::Default); markerWidget->setImageTexture(markerTexture); markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserData(markerPos); @@ -371,7 +371,7 @@ namespace MWGui widgetPos.top - 4, 8, 8); MyGUI::ImageBox* markerWidget = mLocalMap->createWidget("ImageBox", - widgetCoord, MyGUI::Align::Default, "MarkerMarked"); + widgetCoord, MyGUI::Align::Default); markerWidget->setImageTexture("textures\\menu_map_smark.dds"); markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserData(markerPos); @@ -443,7 +443,7 @@ namespace MWGui static int _counter=0; MyGUI::Button* markerWidget = mGlobalMapOverlay->createWidget("ButtonImage", - widgetCoord, MyGUI::Align::Default, "Door" + boost::lexical_cast(_counter)); + widgetCoord, MyGUI::Align::Default); markerWidget->setImageResource("DoorMarker"); markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); From a4a9794417ff6c89197a2ebddb8b6012add7ecc4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 11 May 2014 02:07:28 +0200 Subject: [PATCH 117/121] Savegame: store fog of war (Closes #1177) --- apps/openmw/mwrender/localmap.cpp | 269 ++++++++++++++++------ apps/openmw/mwrender/localmap.hpp | 31 ++- apps/openmw/mwrender/renderingmanager.cpp | 10 +- apps/openmw/mwrender/renderingmanager.hpp | 7 +- apps/openmw/mwworld/cells.cpp | 4 + apps/openmw/mwworld/cellstore.cpp | 26 +++ apps/openmw/mwworld/cellstore.hpp | 20 ++ apps/openmw/mwworld/worldimp.cpp | 10 + components/CMakeLists.txt | 2 +- components/esm/cellstate.cpp | 7 +- components/esm/cellstate.hpp | 4 +- components/esm/fogstate.cpp | 40 ++++ components/esm/fogstate.hpp | 38 +++ 13 files changed, 381 insertions(+), 87 deletions(-) create mode 100644 components/esm/fogstate.cpp create mode 100644 components/esm/fogstate.hpp diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 0f6d782a6..41885da33 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" @@ -46,7 +48,6 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag LocalMap::~LocalMap() { - deleteBuffers(); } const Ogre::Vector2 LocalMap::rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle) @@ -55,59 +56,83 @@ const Ogre::Vector2 LocalMap::rotatePoint(const Ogre::Vector2& p, const Ogre::Ve Math::Sin(angle) * (p.x - c.x) + Math::Cos(angle) * (p.y - c.y) + c.y); } -void LocalMap::deleteBuffers() -{ - mBuffers.clear(); -} - -void LocalMap::saveTexture(const std::string& texname, const std::string& filename) -{ - TexturePtr tex = TextureManager::getSingleton().getByName(texname); - if (tex.isNull()) return; - HardwarePixelBufferSharedPtr readbuffer = tex->getBuffer(); - readbuffer->lock(HardwareBuffer::HBL_NORMAL ); - const PixelBox &readrefpb = readbuffer->getCurrentLock(); - uchar *readrefdata = static_cast(readrefpb.data); - - Image img; - img = img.loadDynamicImage (readrefdata, tex->getWidth(), - tex->getHeight(), tex->getFormat()); - img.save("./" + filename); - - readbuffer->unlock(); -} - std::string LocalMap::coordStr(const int x, const int y) { return StringConverter::toString(x) + "_" + StringConverter::toString(y); } +void LocalMap::clear() +{ + // Not actually removing the Textures here. That doesnt appear to work properly. It seems MyGUI still keeps some pointers. + mBuffers.clear(); +} + void LocalMap::saveFogOfWar(MWWorld::CellStore* cell) { if (!mInterior) { - /*saveTexture("Cell_"+coordStr(mCellX, mCellY)+"_fog", - "Cell_"+coordStr(mCellX, mCellY)+"_fog.png");*/ + std::string textureName = "Cell_"+coordStr(cell->getCell()->getGridX(), cell->getCell()->getGridY())+"_fog"; + std::auto_ptr fog (new ESM::FogState()); + fog->mFogTextures.push_back(ESM::FogTexture()); + + TexturePtr tex = TextureManager::getSingleton().getByName(textureName); + if (tex.isNull()) + return; + + Ogre::Image image; + tex->convertToImage(image); + + Ogre::DataStreamPtr encoded = image.encode("tga"); + fog->mFogTextures.back().mImageData.resize(encoded->size()); + encoded->read(&fog->mFogTextures.back().mImageData[0], encoded->size()); + + cell->setFog(fog.release()); } else { Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y); Vector2 length = max-min; - - // divide into segments const int segsX = std::ceil( length.x / sSize ); const int segsY = std::ceil( length.y / sSize ); + mInteriorName = cell->getCell()->mName; + + std::auto_ptr fog (new ESM::FogState()); + + fog->mBounds.mMinX = mBounds.getMinimum().x; + fog->mBounds.mMaxX = mBounds.getMaximum().x; + fog->mBounds.mMinY = mBounds.getMinimum().y; + fog->mBounds.mMaxY = mBounds.getMaximum().y; + fog->mNorthMarkerAngle = mAngle; + + fog->mFogTextures.reserve(segsX*segsY); + for (int x=0; xgetCell()->mName + "_" + coordStr(x,y) + "_fog"; + + TexturePtr tex = TextureManager::getSingleton().getByName(textureName); + if (tex.isNull()) + return; + + Ogre::Image image; + tex->convertToImage(image); + + fog->mFogTextures.push_back(ESM::FogTexture()); + + Ogre::DataStreamPtr encoded = image.encode("tga"); + fog->mFogTextures.back().mImageData.resize(encoded->size()); + encoded->read(&fog->mFogTextures.back().mImageData[0], encoded->size()); + + fog->mFogTextures.back().mX = x; + fog->mFogTextures.back().mY = y; } } + + cell->setFog(fog.release()); } } @@ -126,29 +151,34 @@ void LocalMap::requestMap(MWWorld::CellStore* cell, float zMin, float zMax) mCameraPosNode->setPosition(Vector3(0,0,0)); render((x+0.5)*sSize, (y+0.5)*sSize, zMin, zMax, sSize, sSize, name); + + if (mBuffers.find(name) == mBuffers.end()) + { + if (cell->getFog()) + loadFogOfWar(name, cell->getFog()->mFogTextures.back()); + else + createFogOfWar(name); + } } void LocalMap::requestMap(MWWorld::CellStore* cell, AxisAlignedBox bounds) { - // if we're in an empty cell, don't bother rendering anything + // If we're in an empty cell, bail out + // The operations in this function are only valid for finite bounds if (bounds.isNull ()) return; mInterior = true; + mBounds = bounds; - float zMin = mBounds.getMinimum().z; - float zMax = mBounds.getMaximum().z; - + // Get the cell's NorthMarker rotation. This is used to rotate the entire map. const Vector2& north = MWBase::Environment::get().getWorld()->getNorthVector(cell); - Radian angle = Ogre::Math::ATan2 (north.x, north.y); + Radian angle = Ogre::Math::ATan2 (north.x, north.y) + Ogre::Degree(2); mAngle = angle.valueRadians(); - mCellCamera->setOrientation(Quaternion::IDENTITY); - mCameraRotNode->setOrientation(Quaternion(Math::Cos(mAngle/2.f), 0, 0, -Math::Sin(mAngle/2.f))); - - // rotate the cell and merge the rotated corners to the bounding box + // Rotate the cell and merge the rotated corners to the bounding box Vector2 _center(bounds.getCenter().x, bounds.getCenter().y); Vector3 _c1 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM); Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM); @@ -168,9 +198,48 @@ void LocalMap::requestMap(MWWorld::CellStore* cell, mBounds.merge(Vector3(c3.x, c3.y, 0)); mBounds.merge(Vector3(c4.x, c4.y, 0)); - // apply a little padding - mBounds.setMinimum (mBounds.getMinimum() - Vector3(500,500,0)); - mBounds.setMaximum (mBounds.getMaximum() + Vector3(500,500,0)); + // Do NOT change padding! This will break older savegames. + // If the padding really needs to be changed, then it must be saved in the ESM::FogState and + // assume the old (500) value as default for older savegames. + const int padding = 500; + + // Apply a little padding + mBounds.setMinimum (mBounds.getMinimum() - Vector3(padding,padding,0)); + mBounds.setMaximum (mBounds.getMaximum() + Vector3(padding,padding,0)); + + float zMin = mBounds.getMinimum().z; + float zMax = mBounds.getMaximum().z; + + // If there is fog state in the CellStore (e.g. when it came from a savegame) we need to do some checks + // to see if this state is still valid. + // Both the cell bounds and the NorthMarker rotation could be changed by the content files or exchanged models. + // If they changed by too much (for bounds, < padding is considered acceptable) then parts of the interior might not + // be covered by the map anymore. + // The following code detects this, and discards the CellStore's fog state if it needs to. + if (cell->getFog()) + { + ESM::FogState* fog = cell->getFog(); + + Ogre::Vector3 newMin (fog->mBounds.mMinX, fog->mBounds.mMinY, zMin); + Ogre::Vector3 newMax (fog->mBounds.mMaxX, fog->mBounds.mMaxY, zMax); + + Ogre::Vector3 minDiff = newMin - mBounds.getMinimum(); + Ogre::Vector3 maxDiff = newMax - mBounds.getMaximum(); + + if (std::abs(minDiff.x) > 500 || std::abs(minDiff.y) > 500 + || std::abs(maxDiff.x) > 500 || std::abs(maxDiff.y) > 500 + || std::abs(mAngle - fog->mNorthMarkerAngle) > Ogre::Degree(5).valueRadians()) + { + // Nuke it + cell->setFog(NULL); + } + else + { + // Looks sane, use it + mBounds = Ogre::AxisAlignedBox(newMin, newMax); + mAngle = fog->mNorthMarkerAngle; + } + } Vector2 center(mBounds.getCenter().x, mBounds.getCenter().y); @@ -179,6 +248,9 @@ void LocalMap::requestMap(MWWorld::CellStore* cell, Vector2 length = max-min; + mCellCamera->setOrientation(Quaternion::IDENTITY); + mCameraRotNode->setOrientation(Quaternion(Math::Cos(mAngle/2.f), 0, 0, -Math::Sin(mAngle/2.f))); + mCameraPosNode->setPosition(Vector3(center.x, center.y, 0)); // divide into segments @@ -187,19 +259,96 @@ void LocalMap::requestMap(MWWorld::CellStore* cell, mInteriorName = cell->getCell()->mName; + int i=0; for (int x=0; xgetCell()->mName + "_" + coordStr(x,y)); + std::string texturePrefix = cell->getCell()->mName + "_" + coordStr(x,y); + + render(newcenter.x - center.x, newcenter.y - center.y, zMin, zMax, sSize, sSize, texturePrefix); + + if (!cell->getFog()) + createFogOfWar(texturePrefix); + else + { + ESM::FogState* fog = cell->getFog(); + + // We are using the same bounds and angle as we were using when the textures were originally made. Segments should come out the same. + assert (i < int(fog->mFogTextures.size())); + + ESM::FogTexture& esm = fog->mFogTextures[i]; + loadFogOfWar(texturePrefix, esm); + } + ++i; } } } +void LocalMap::createFogOfWar(const std::string& texturePrefix) +{ + const std::string texName = texturePrefix + "_fog"; + TexturePtr tex = createFogOfWarTexture(texName); + + // create a buffer to use for dynamic operations + std::vector buffer; + + // initialize to (0, 0, 0, 1) + buffer.resize(sFogOfWarResolution*sFogOfWarResolution, (255 << 24)); + + // upload to the texture + memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &buffer[0], sFogOfWarResolution*sFogOfWarResolution*4); + tex->getBuffer()->unlock(); + + mBuffers[texturePrefix] = buffer; +} + +Ogre::TexturePtr LocalMap::createFogOfWarTexture(const std::string &texName) +{ + TexturePtr tex = TextureManager::getSingleton().getByName(texName); + if (tex.isNull()) + { + tex = TextureManager::getSingleton().createManual( + texName, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, + sFogOfWarResolution, sFogOfWarResolution, + 0, + PF_A8R8G8B8, + TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + } + else + tex->unload(); + + return tex; +} + +void LocalMap::loadFogOfWar (const std::string& texturePrefix, ESM::FogTexture& esm) +{ + std::vector& data = esm.mImageData; + Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&data[0], data.size())); + Ogre::Image image; + image.load(stream, "tga"); + + assert (image.getWidth() == sFogOfWarResolution && image.getHeight() == sFogOfWarResolution); + + std::string texName = texturePrefix + "_fog"; + + Ogre::TexturePtr tex = createFogOfWarTexture(texName); + + tex->loadImage(image); + + // create a buffer to use for dynamic operations + std::vector buffer; + buffer.resize(sFogOfWarResolution*sFogOfWarResolution); + memcpy(&buffer[0], image.getData(), image.getSize()); + + mBuffers[texturePrefix] = buffer; +} + void LocalMap::render(const float x, const float y, const float zlow, const float zhigh, const float xw, const float yw, const std::string& texture) @@ -249,31 +398,6 @@ void LocalMap::render(const float x, const float y, vp->setMaterialScheme("local_map"); rtt->update(); - - // create "fog of war" texture - TexturePtr tex2 = TextureManager::getSingleton().createManual( - texture + "_fog", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - TEX_TYPE_2D, - xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize, - 0, - PF_A8R8G8B8, - TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); - - // create a buffer to use for dynamic operations - std::vector buffer; - buffer.resize(sFogOfWarResolution*sFogOfWarResolution); - - // initialize to (0, 0, 0, 1) - for (int p=0; pgetBuffer()->lock(HardwareBuffer::HBL_DISCARD), &buffer[0], sFogOfWarResolution*sFogOfWarResolution*4); - tex2->getBuffer()->unlock(); - - mBuffers[texture] = buffer; } mRenderingManager->enableLights(true); @@ -304,6 +428,9 @@ bool LocalMap::isPositionExplored (float nX, float nY, int x, int y, bool interi if (mBuffers.find(texName) == mBuffers.end()) return false; + nX = std::max(0.f, std::min(1.f, nX)); + nY = std::max(0.f, std::min(1.f, nY)); + int texU = (sFogOfWarResolution-1) * nX; int texV = (sFogOfWarResolution-1) * nY; @@ -414,6 +541,8 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni } // copy to the texture + // NOTE: Could be optimized later. We actually only need to update the region that changed. + // Not a big deal at the moment, the FoW is only 32x32 anyway. memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &aBuffer[0], sFogOfWarResolution*sFogOfWarResolution*4); tex->getBuffer()->unlock(); } diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 638469d2d..1d480872e 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -11,6 +11,11 @@ namespace MWWorld class CellStore; } +namespace ESM +{ + class FogTexture; +} + namespace MWRender { class RenderingManager; @@ -24,6 +29,11 @@ namespace MWRender LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering); ~LocalMap(); + /** + * Clear all savegame-specific data (i.e. fog of war textures) + */ + void clear(); + /** * Request the local map for an exterior cell. * @remarks It will either be loaded from a disk cache, @@ -54,10 +64,8 @@ namespace MWRender void updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation); /** - * Save the fog of war for the current cell to disk. - * @remarks This should be called before loading a - * new cell, as well as when the game is quit. - * @param current cell + * Save the fog of war for this cell to its CellStore. + * @remarks This should be called when unloading a cell, and for all active cells prior to saving the game. */ void saveFogOfWar(MWWorld::CellStore* cell); @@ -104,17 +112,20 @@ namespace MWRender const float xw, const float yw, const std::string& texture); - void saveTexture(const std::string& texname, const std::string& filename); + // Creates a fog of war texture and initializes it to full black + void createFogOfWar(const std::string& texturePrefix); + + // Loads a fog of war texture from its ESM struct + void loadFogOfWar(const std::string& texturePrefix, ESM::FogTexture& esm); // FogTexture not const because MemoryDataStream doesn't accept it + + Ogre::TexturePtr createFogOfWarTexture(const std::string& name); std::string coordStr(const int x, const int y); - // a buffer for the "fog of war" texture of the current cell. - // interior cells could be divided into multiple textures, - // so we store in a map. + // A buffer for the "fog of war" textures of the current cell. + // Both interior and exterior maps are possibly divided into multiple textures. std::map > mBuffers; - void deleteBuffers(); - bool mInterior; int mCellX, mCellY; Ogre::AxisAlignedBox mBounds; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 19d26a176..948f85b5e 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -216,13 +216,14 @@ OEngine::Render::Fader* RenderingManager::getFader() return mRendering.getFader(); } - MWRender::Camera* RenderingManager::getCamera() const +MWRender::Camera* RenderingManager::getCamera() const { return mCamera; } void RenderingManager::removeCell (MWWorld::CellStore *store) { + mLocalMap->saveFogOfWar(store); mObjects->removeCell(store); mActors->removeCell(store); mDebugging->cellRemoved(store); @@ -671,7 +672,7 @@ void RenderingManager::requestMap(MWWorld::CellStore* cell) mLocalMap->requestMap(cell, mObjects->getDimensions(cell)); } -void RenderingManager::preCellChange(MWWorld::CellStore* cell) +void RenderingManager::writeFog(MWWorld::CellStore* cell) { mLocalMap->saveFogOfWar(cell); } @@ -1057,4 +1058,9 @@ void RenderingManager::spawnEffect(const std::string &model, const std::string & mEffectManager->addEffect(model, texture, worldPosition, scale); } +void RenderingManager::clear() +{ + mLocalMap->clear(); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 423a7078a..eb6827292 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -107,12 +107,15 @@ public: void cellAdded (MWWorld::CellStore *store); void waterAdded(MWWorld::CellStore *store); + /// Clear all savegame-specific data (i.e. fog of war textures) + void clear(); + void enableTerrain(bool enable); void removeWater(); - void preCellChange (MWWorld::CellStore* store); - ///< this event is fired immediately before changing cell + /// Write current fog of war for this cell to the CellStore + void writeFog (MWWorld::CellStore* store); void addObject (const MWWorld::Ptr& ptr); void removeObject (const MWWorld::Ptr& ptr); diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 7f2a87eec..3b758f866 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -78,6 +78,7 @@ void MWWorld::Cells::writeCell (ESM::ESMWriter& writer, CellStore& cell) const writer.startRecord (ESM::REC_CSTA); cellState.mId.save (writer); cellState.save (writer); + cell.writeFog(writer); cell.writeReferences (writer); writer.endRecord (ESM::REC_CSTA); } @@ -319,6 +320,9 @@ bool MWWorld::Cells::readRecord (ESM::ESMReader& reader, int32_t type, state.load (reader); cellStore->loadState (state); + if (state.mHasFogOfWar) + cellStore->readFog(reader); + if (cellStore->getState()!=CellStore::State_Loaded) cellStore->load (mStore, mReader); diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 1c39d2c07..39f6538bb 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -533,6 +534,21 @@ namespace MWWorld state.mWaterLevel = mWaterLevel; state.mWaterLevel = mWaterLevel; + state.mHasFogOfWar = (mFogState.get() ? 1 : 0); + } + + void CellStore::writeFog(ESM::ESMWriter &writer) const + { + if (mFogState.get()) + { + mFogState->save(writer, mCell->mData.mFlags & ESM::Cell::Interior); + } + } + + void CellStore::readFog(ESM::ESMReader &reader) + { + mFogState.reset(new ESM::FogState()); + mFogState->load(reader); } void CellStore::writeReferences (ESM::ESMWriter& writer) const @@ -697,4 +713,14 @@ namespace MWWorld { return mPathgridGraph.aStarSearch(start, end); } + + void CellStore::setFog(ESM::FogState *fog) + { + mFogState.reset(fog); + } + + ESM::FogState* CellStore::getFog() const + { + return mFogState.get(); + } } diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 88b49ed1c..cc3036647 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -3,22 +3,28 @@ #include #include +#include #include "livecellref.hpp" #include "esmstore.hpp" #include "cellreflist.hpp" +#include + #include "../mwmechanics/pathgrid.hpp" // TODO: maybe belongs in mwworld namespace ESM { struct CellState; + struct FogState; } namespace MWWorld { class Ptr; + + /// \brief Mutable state of a cell class CellStore { @@ -31,6 +37,11 @@ namespace MWWorld private: + // Even though fog actually belongs to the player and not cells, + // it makes sense to store it here since we need it once for each cell. + // Note this is NULL until the cell is explored to save some memory + boost::shared_ptr mFogState; + const ESM::Cell *mCell; State mState; bool mHasState; @@ -84,6 +95,11 @@ namespace MWWorld void setWaterLevel (float level); + void setFog (ESM::FogState* fog); + ///< \note Takes ownership of the pointer + + ESM::FogState* getFog () const; + int count() const; ///< Return total number of references, including deleted ones. @@ -134,6 +150,10 @@ namespace MWWorld void saveState (ESM::CellState& state) const; + void writeFog (ESM::ESMWriter& writer) const; + + void readFog (ESM::ESMReader& reader); + void writeReferences (ESM::ESMWriter& writer) const; void readReferences (ESM::ESMReader& reader, const std::map& contentFileMap); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index de9c8f04a..ba36d4a86 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -231,6 +231,8 @@ namespace MWWorld void World::clear() { + mRendering->clear(); + mLocalScripts.clear(); mPlayer->clear(); @@ -277,6 +279,14 @@ namespace MWWorld void World::write (ESM::ESMWriter& writer, Loading::Listener& progress) const { + // Active cells could have a dirty fog of war, sync it to the CellStore first + for (Scene::CellStoreCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); + iter!=mWorldScene->getActiveCells().end(); ++iter) + { + CellStore* cellstore = *iter; + mRendering->writeFog(cellstore); + } + mCells.write (writer, progress); mStore.write (writer, progress); mGlobalVariables.write (writer, progress); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 1c60dfb83..3dd5df295 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -45,7 +45,7 @@ add_component_dir (esm loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate - npcstats creaturestats weatherstate quickkeys + npcstats creaturestats weatherstate quickkeys fogstate ) add_component_dir (misc diff --git a/components/esm/cellstate.cpp b/components/esm/cellstate.cpp index 1f7e8197e..541a359c6 100644 --- a/components/esm/cellstate.cpp +++ b/components/esm/cellstate.cpp @@ -8,10 +8,15 @@ void ESM::CellState::load (ESMReader &esm) { mWaterLevel = 0; esm.getHNOT (mWaterLevel, "WLVL"); + + mHasFogOfWar = false; + esm.getHNOT (mHasFogOfWar, "HFOW"); } void ESM::CellState::save (ESMWriter &esm) const { if (!mId.mPaged) esm.writeHNT ("WLVL", mWaterLevel); -} \ No newline at end of file + + esm.writeHNT("HFOW", mHasFogOfWar); +} diff --git a/components/esm/cellstate.hpp b/components/esm/cellstate.hpp index cd0db3067..88918a3ab 100644 --- a/components/esm/cellstate.hpp +++ b/components/esm/cellstate.hpp @@ -17,9 +17,11 @@ namespace ESM float mWaterLevel; + int mHasFogOfWar; // Do we have fog of war state (0 or 1)? (see fogstate.hpp) + void load (ESMReader &esm); void save (ESMWriter &esm) const; }; } -#endif \ No newline at end of file +#endif diff --git a/components/esm/fogstate.cpp b/components/esm/fogstate.cpp new file mode 100644 index 000000000..18235066d --- /dev/null +++ b/components/esm/fogstate.cpp @@ -0,0 +1,40 @@ +#include "fogstate.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" + +void ESM::FogState::load (ESMReader &esm) +{ + esm.getHNOT(mBounds, "BOUN"); + esm.getHNOT(mNorthMarkerAngle, "ANGL"); + while (esm.isNextSub("FTEX")) + { + esm.getSubHeader(); + FogTexture tex; + + esm.getT(tex.mX); + esm.getT(tex.mY); + + size_t imageSize = esm.getSubSize()-sizeof(int)*2; + tex.mImageData.resize(imageSize); + esm.getExact(&tex.mImageData[0], imageSize); + mFogTextures.push_back(tex); + } +} + +void ESM::FogState::save (ESMWriter &esm, bool interiorCell) const +{ + if (interiorCell) + { + esm.writeHNT("BOUN", mBounds); + esm.writeHNT("ANGL", mNorthMarkerAngle); + } + for (std::vector::const_iterator it = mFogTextures.begin(); it != mFogTextures.end(); ++it) + { + esm.startSubRecord("FTEX"); + esm.writeT(it->mX); + esm.writeT(it->mY); + esm.write(&it->mImageData[0], it->mImageData.size()); + esm.endRecord("FTEX"); + } +} diff --git a/components/esm/fogstate.hpp b/components/esm/fogstate.hpp new file mode 100644 index 000000000..4a5619e51 --- /dev/null +++ b/components/esm/fogstate.hpp @@ -0,0 +1,38 @@ +#ifndef OPENMW_ESM_FOGSTATE_H +#define OPENMW_ESM_FOGSTATE_H + +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + struct FogTexture + { + int mX, mY; // Only used for interior cells + std::vector mImageData; + }; + + // format 0, saved games only + // Fog of war state + struct FogState + { + // Only used for interior cells + float mNorthMarkerAngle; + struct Bounds + { + float mMinX; + float mMinY; + float mMaxX; + float mMaxY; + } mBounds; + + std::vector mFogTextures; + + void load (ESMReader &esm); + void save (ESMWriter &esm, bool interiorCell) const; + }; +} + +#endif From c98bea2a8807f86bfd0d802c1de54b58ff62e912 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 11 May 2014 02:27:43 +0200 Subject: [PATCH 118/121] Moved local map update to LocalMap::updatePlayer to fix a brief desync on cell transitions due to sFogOfWarSkip --- apps/openmw/mwbase/windowmanager.hpp | 4 ++-- apps/openmw/mwgui/windowmanagerimp.cpp | 8 +++----- apps/openmw/mwgui/windowmanagerimp.hpp | 4 ++-- apps/openmw/mwrender/localmap.cpp | 5 +---- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 9e5230af6..39cfc47ed 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -200,8 +200,8 @@ namespace MWBase virtual bool getFullHelp() const = 0; - virtual void setInteriorMapTexture(const int x, const int y) = 0; - ///< set the index of the map texture that should be used (for interiors) + virtual void setActiveMap(int x, int y, bool interior) = 0; + ///< set the indices of the map texture that should be used /// sets the visibility of the drowning bar virtual void setDrowningBarVisibility(bool visible) = 0; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 6a15c8e33..e3baf84fb 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -766,8 +766,6 @@ namespace MWGui mMap->setCellPrefix("Cell"); mHud->setCellPrefix("Cell"); - mMap->setActiveCell (cell->getCell()->getGridX(), cell->getCell()->getGridY()); - mHud->setActiveCell (cell->getCell()->getGridX(), cell->getCell()->getGridY()); } else { @@ -783,10 +781,10 @@ namespace MWGui } } - void WindowManager::setInteriorMapTexture(const int x, const int y) + void WindowManager::setActiveMap(int x, int y, bool interior) { - mMap->setActiveCell(x,y, true); - mHud->setActiveCell(x,y, true); + mMap->setActiveCell(x,y, interior); + mHud->setActiveCell(x,y, interior); } void WindowManager::setPlayerPos(const float x, const float y) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index e31013b45..7617a4463 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -192,8 +192,8 @@ namespace MWGui virtual void toggleFullHelp(); ///< show extra info in item tooltips (owner, script) virtual bool getFullHelp() const; - virtual void setInteriorMapTexture(const int x, const int y); - ///< set the index of the map texture that should be used (for interiors) + virtual void setActiveMap(int x, int y, bool interior); + ///< set the indices of the map texture that should be used /// sets the visibility of the drowning bar virtual void setDrowningBarVisibility(bool visible); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 41885da33..e1694d892 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -466,10 +466,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni mCellX = x; mCellY = y; } - else - { - MWBase::Environment::get().getWindowManager()->setInteriorMapTexture(x,y); - } + MWBase::Environment::get().getWindowManager()->setActiveMap(x,y,mInterior); // convert from world coordinates to texture UV coordinates std::string texBaseName; From c39a0368cf4150afbe64295aadcd9ae3c2a5f041 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 11 May 2014 02:38:39 +0200 Subject: [PATCH 119/121] Bug #618: Make local map textures static in an attempt to fix the disappearing maps with D3D. Also removed problematic DISCARDABLE flag for fog of war textures. --- apps/openmw/mwrender/localmap.cpp | 43 +++++++++++++++++++------------ apps/openmw/mwrender/localmap.hpp | 5 +++- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index e1694d892..56b2326ec 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -44,6 +44,24 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag mLight->setDirection (Ogre::Vector3(0.3, 0.3, -0.7)); mLight->setVisible (false); mLight->setDiffuseColour (ColourValue(0.7,0.7,0.7)); + + mRenderTexture = TextureManager::getSingleton().createManual( + "localmap/rtt", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, + sMapResolution, sMapResolution, + 0, + PF_R8G8B8, + TU_RENDERTARGET); + + mRenderTarget = mRenderTexture->getBuffer()->getRenderTarget(); + mRenderTarget->setAutoUpdated(false); + Viewport* vp = mRenderTarget->addViewport(mCellCamera); + vp->setOverlaysEnabled(false); + vp->setShadowsEnabled(false); + vp->setBackgroundColour(ColourValue(0, 0, 0)); + vp->setVisibilityMask(RV_Map); + vp->setMaterialScheme("local_map"); } LocalMap::~LocalMap() @@ -318,7 +336,7 @@ Ogre::TexturePtr LocalMap::createFogOfWarTexture(const std::string &texName) sFogOfWarResolution, sFogOfWarResolution, 0, PF_A8R8G8B8, - TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + TU_DYNAMIC_WRITE_ONLY); } else tex->unload(); @@ -378,26 +396,17 @@ void LocalMap::render(const float x, const float y, if (tex.isNull()) { // render - tex = TextureManager::getSingleton().createManual( + mRenderTarget->update(); + + // create a new texture and blit to it + Ogre::TexturePtr tex = TextureManager::getSingleton().createManual( texture, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - xw*sMapResolution/sSize, yw*sMapResolution/sSize, + sMapResolution, sMapResolution, 0, - PF_R8G8B8, - TU_RENDERTARGET); - - RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); - - rtt->setAutoUpdated(false); - Viewport* vp = rtt->addViewport(mCellCamera); - vp->setOverlaysEnabled(false); - vp->setShadowsEnabled(false); - vp->setBackgroundColour(ColourValue(0, 0, 0)); - vp->setVisibilityMask(RV_Map); - vp->setMaterialScheme("local_map"); - - rtt->update(); + PF_R8G8B8); + tex->getBuffer()->blit(mRenderTexture->getBuffer()); } mRenderingManager->enableLights(true); diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 1d480872e..941171527 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -84,7 +84,6 @@ namespace MWRender OEngine::Render::OgreRenderer* mRendering; MWRender::RenderingManager* mRenderingManager; - // 1024*1024 pixels for a cell static const int sMapResolution = 512; // the dynamic texture is a bottleneck, so don't set this too high @@ -126,6 +125,10 @@ namespace MWRender // Both interior and exterior maps are possibly divided into multiple textures. std::map > mBuffers; + // The render texture we will use to create the map images + Ogre::TexturePtr mRenderTexture; + Ogre::RenderTarget* mRenderTarget; + bool mInterior; int mCellX, mCellY; Ogre::AxisAlignedBox mBounds; From 050fe9ebe1190c0ca9ac0c9b4cc8fa519b100a92 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 12 May 2014 08:58:55 +0200 Subject: [PATCH 120/121] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 499c55eeb..6f0561490 100644 --- a/credits.txt +++ b/credits.txt @@ -33,6 +33,7 @@ Edmondo Tommasina (edmondo) Eduard Cot (trombonecot) Eli2 Emanuel Guével (potatoesmaster) +Fil Krynicki (filkry) gugus/gus Jacob Essex (Yacoby) Jannik Heller (scrawl) From 8279d307c4b53a13acf339594bd3703300ee17b6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 12 May 2014 10:32:57 +0200 Subject: [PATCH 121/121] text encoding configuration (was using hardcoded settings before) --- apps/opencs/editor.cpp | 3 +++ apps/opencs/model/doc/document.cpp | 8 +++++--- apps/opencs/model/doc/document.hpp | 5 ++++- apps/opencs/model/doc/documentmanager.cpp | 9 +++++++-- apps/opencs/model/doc/documentmanager.hpp | 5 +++++ apps/opencs/model/doc/saving.cpp | 5 +++-- apps/opencs/model/doc/saving.hpp | 5 ++++- apps/opencs/model/doc/savingstate.cpp | 8 +++----- apps/opencs/model/doc/savingstate.hpp | 5 ++++- apps/opencs/model/world/data.cpp | 6 ++---- apps/opencs/model/world/data.hpp | 4 +++- 11 files changed, 43 insertions(+), 20 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 57d2f4730..b00373587 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -90,6 +90,9 @@ std::pair > CS::Editor::readConfi mCfgMgr.readConfiguration(variables, desc); + mDocumentManager.setEncoding ( + ToUTF8::calculateEncoding (variables["encoding"].as())); + mDocumentManager.setResourceDir (mResources = variables["resources"].as()); mFsStrict = variables["fs-strict"].as(); diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 06c4a0988..f452008ac 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2204,11 +2204,13 @@ void CSMDoc::Document::createBase() CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, - const boost::filesystem::path& savePath, const boost::filesystem::path& resDir) -: mSavePath (savePath), mContentFiles (files), mNew (new_), mTools (mData), mResDir(resDir), + const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, + ToUTF8::FromType encoding) +: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding), mTools (mData), + mResDir(resDir), mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), - mSaving (*this, mProjectPath) + mSaving (*this, mProjectPath, encoding) { if (mContentFiles.empty()) throw std::runtime_error ("Empty content file sequence"); diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 000f6761a..a6f8aaae2 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -9,6 +9,8 @@ #include #include +#include + #include "../world/data.hpp" #include "../tools/tools.hpp" @@ -70,7 +72,8 @@ namespace CSMDoc Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, - const boost::filesystem::path& savePath, const boost::filesystem::path& resDir); + const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, + ToUTF8::FromType encoding); ~Document(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index d4f8eb110..096864b77 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -13,7 +13,7 @@ #include "document.hpp" CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration) -: mConfiguration (configuration) +: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252) { boost::filesystem::path projectPath = configuration.getUserDataPath() / "projects"; @@ -52,7 +52,7 @@ CSMDoc::DocumentManager::~DocumentManager() void CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - Document *document = new Document (mConfiguration, files, new_, savePath, mResDir); + Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding); mDocuments.push_back (document); @@ -80,6 +80,11 @@ void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& par mResDir = boost::filesystem::system_complete(parResDir); } +void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding) +{ + mEncoding = encoding; +} + void CSMDoc::DocumentManager::documentLoaded (Document *document) { emit documentAdded (document); diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 7b3a811fa..9b675826a 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -9,6 +9,8 @@ #include #include +#include + #include "loader.hpp" namespace Files @@ -28,6 +30,7 @@ namespace CSMDoc const Files::ConfigurationManager& mConfiguration; QThread mLoaderThread; Loader mLoader; + ToUTF8::FromType mEncoding; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); @@ -45,6 +48,8 @@ namespace CSMDoc void setResourceDir (const boost::filesystem::path& parResDir); + void setEncoding (ToUTF8::FromType encoding); + private: boost::filesystem::path mResDir; diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 73278ba97..27d21635e 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -8,8 +8,9 @@ #include "savingstages.hpp" #include "document.hpp" -CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& projectPath) -: Operation (State_Saving, true, true), mDocument (document), mState (*this, projectPath) +CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& projectPath, + ToUTF8::FromType encoding) +: Operation (State_Saving, true, true), mDocument (document), mState (*this, projectPath, encoding) { // save project file appendStage (new OpenSaveStage (mDocument, mState, true)); diff --git a/apps/opencs/model/doc/saving.hpp b/apps/opencs/model/doc/saving.hpp index cd1bbef98..44239b21b 100644 --- a/apps/opencs/model/doc/saving.hpp +++ b/apps/opencs/model/doc/saving.hpp @@ -3,6 +3,8 @@ #include +#include + #include "operation.hpp" #include "savingstate.hpp" @@ -19,7 +21,8 @@ namespace CSMDoc public: - Saving (Document& document, const boost::filesystem::path& projectPath); + Saving (Document& document, const boost::filesystem::path& projectPath, + ToUTF8::FromType encoding); }; } diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp index 4a1abb888..874214822 100644 --- a/apps/opencs/model/doc/savingstate.cpp +++ b/apps/opencs/model/doc/savingstate.cpp @@ -4,11 +4,9 @@ #include "operation.hpp" #include "document.hpp" -CSMDoc::SavingState::SavingState (Operation& operation, const boost::filesystem::path& projectPath) -: mOperation (operation), - /// \todo set encoding properly, once config implementation has been fixed. - mEncoder (ToUTF8::calculateEncoding ("win1252")), - mProjectPath (projectPath), mProjectFile (false) +CSMDoc::SavingState::SavingState (Operation& operation, const boost::filesystem::path& projectPath, + ToUTF8::FromType encoding) +: mOperation (operation), mEncoder (encoding), mProjectPath (projectPath), mProjectFile (false) { mWriter.setEncoder (&mEncoder); } diff --git a/apps/opencs/model/doc/savingstate.hpp b/apps/opencs/model/doc/savingstate.hpp index 8cf7883e5..6b4565584 100644 --- a/apps/opencs/model/doc/savingstate.hpp +++ b/apps/opencs/model/doc/savingstate.hpp @@ -7,6 +7,8 @@ #include +#include + namespace CSMDoc { class Operation; @@ -25,7 +27,8 @@ namespace CSMDoc public: - SavingState (Operation& operation, const boost::filesystem::path& projectPath); + SavingState (Operation& operation, const boost::filesystem::path& projectPath, + ToUTF8::FromType encoding); bool hasError() const; diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 3e9fe11eb..ff33b4665 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -55,10 +55,8 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec return number; } -CSMWorld::Data::Data() -/// \todo set encoding properly, once config implementation has been fixed. -: mEncoder (ToUTF8::calculateEncoding ("win1252")), - mRefs (mCells), mReader (0), mDialogue (0) +CSMWorld::Data::Data (ToUTF8::FromType encoding) +: mEncoder (encoding), mRefs (mCells), mReader (0), mDialogue (0) { mGlobals.addColumn (new StringIdColumn); mGlobals.addColumn (new RecordStateColumn); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 4f7c624e6..ab247b6a3 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -22,6 +22,8 @@ #include #include +#include + #include "../filter/filter.hpp" #include "../doc/stage.hpp" @@ -91,7 +93,7 @@ namespace CSMWorld public: - Data(); + Data (ToUTF8::FromType encoding); virtual ~Data();