From ce421b230b1938398a9559fdcc89c28c01a4a615 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 29 May 2015 14:07:41 +1000 Subject: [PATCH 01/33] Move scrollbar to newly opened subview. Should resolve Bug #2576. --- apps/opencs/view/doc/view.cpp | 21 +++++++++++++++------ apps/opencs/view/doc/view.hpp | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 5e3df27399..c100e84e61 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -519,6 +519,10 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin } } + if (mScroll) + QObject::connect(mScroll->horizontalScrollBar(), + SIGNAL(rangeChanged(int,int)), this, SLOT(moveScrollBarToEnd(int,int))); + // User setting for limiting the number of sub views per top level view. // Automatically open a new top level view if this number is exceeded // @@ -590,12 +594,6 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minWidth); move(0, y()); } - - // Make the new subview visible, setFocus() or raise() don't seem to work - // On Ubuntu the scrollbar does not go right to the end, even if using - // mScroll->horizontalScrollBar()->setValue(mScroll->horizontalScrollBar()->maximum()); - if (mSubViewWindow.width() > rect.width()) - mScroll->horizontalScrollBar()->setValue(mSubViewWindow.width()); } mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view); @@ -618,6 +616,17 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin view->useHint (hint); } +void CSVDoc::View::moveScrollBarToEnd(int min, int max) +{ + if (mScroll) + { + mScroll->horizontalScrollBar()->setValue(max); + + QObject::disconnect(mScroll->horizontalScrollBar(), + SIGNAL(rangeChanged(int,int)), this, SLOT(moveScrollBarToEnd(int,int))); + } +} + void CSVDoc::View::newView() { mViewManager.addView (mDocument); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 1d44cb7f5a..814dabc6b5 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -233,6 +233,8 @@ namespace CSVDoc void stop(); void closeRequest (SubView *subView); + + void moveScrollBarToEnd(int min, int max); }; } From 8e8da724f5dd7bddc5dccee3c081664335cb60c1 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 10 Jun 2015 08:23:38 +1000 Subject: [PATCH 02/33] Remove unnecessary comment entry in the config file. --- components/config/gamesettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index 2b3a8ba4bf..9af6c97143 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -291,9 +291,9 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) stream << key << "=" << value << "\n"; } + // new entries if (!userSettingsCopy.empty()) { - stream << "# new entries" << "\n"; QMap::const_iterator it = userSettingsCopy.begin(); for (; it != userSettingsCopy.end(); ++it) { From 6d7e6cd30c3e6a8b20a59f657e90ac91506eccab Mon Sep 17 00:00:00 2001 From: dteviot Date: Thu, 11 Jun 2015 18:28:31 +1200 Subject: [PATCH 03/33] AiTravel logic merged into AiPackage. --- apps/openmw/mwmechanics/aipackage.cpp | 9 ++++- apps/openmw/mwmechanics/aipackage.hpp | 4 ++ apps/openmw/mwmechanics/aitravel.cpp | 55 ++++++--------------------- apps/openmw/mwmechanics/aitravel.hpp | 3 ++ 4 files changed, 25 insertions(+), 46 deletions(-) diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 52a975320d..802a7723ea 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -30,9 +30,9 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po ESM::Position pos = actor.getRefData().getPosition(); //position of the actor /// Stops the actor when it gets too close to a unloaded cell + const ESM::Cell *cell = actor.getCell()->getCell(); { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - const ESM::Cell *cell = actor.getCell()->getCell(); Movement &movement = actor.getClass().getMovementSettings(actor); //Ensure pursuer doesn't leave loaded cells @@ -67,7 +67,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po //*********************** if(mTimer > 0.25) { - if(distance(mPrevDest, dest) > 10) { //Only rebuild path if it's moved + if (doesPathNeedRecalc(dest, cell)) { //Only rebuild path if it's moved mPathFinder.buildPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved mPrevDest = dest; } @@ -123,3 +123,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po return false; } + +bool MWMechanics::AiPackage::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell) +{ + return distance(mPrevDest, dest) > 10; +} \ No newline at end of file diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 179ae440bb..0370072a41 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -4,6 +4,8 @@ #include "pathfinding.hpp" #include +#include "../mwworld/cellstore.hpp" + #include "obstacle.hpp" #include "aistate.hpp" @@ -71,6 +73,8 @@ namespace MWMechanics /** \return If the actor has arrived at his destination **/ bool pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Point dest, float duration); + virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell); + // TODO: all this does not belong here, move into temporary storage PathFinder mPathFinder; ObstacleCheck mObstacleCheck; diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 2824e2c6ce..4f4d4c79ff 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -51,64 +51,31 @@ namespace MWMechanics bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration) { - MWBase::World *world = MWBase::Environment::get().getWorld(); ESM::Position pos = actor.getRefData().getPosition(); - Movement &movement = actor.getClass().getMovementSettings(actor); - const ESM::Cell *cell = actor.getCell()->getCell(); actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); - actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); - MWWorld::Ptr player = world->getPlayerPtr(); - if(cell->mData.mX != player.getCell()->getCell()->mData.mX) - { - int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX); - //check if actor is near the border of an inactive cell. If so, stop walking. - if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) > - sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) - { - movement.mPosition[1] = 0; - return false; - } - } - if(cell->mData.mY != player.getCell()->getCell()->mData.mY) - { - int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY); - //check if actor is near the border of an inactive cell. If so, stop walking. - if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) > - sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) - { - movement.mPosition[1] = 0; - return false; - } - } - if (!isWithinMaxRange(Ogre::Vector3(mX, mY, mZ), Ogre::Vector3(pos.pos))) return false; + if (pathTo(actor, ESM::Pathgrid::Point(static_cast(mX), static_cast(mY), static_cast(mZ)), duration)) + { + actor.getClass().getMovementSettings(actor).mPosition[1] = 0; + return true; + } + return false; + } + + bool AiTravel::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell) + { bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY; - if(!mPathFinder.isPathConstructed() || cellChange) + if (!mPathFinder.isPathConstructed() || cellChange) { mCellX = cell->mData.mX; mCellY = cell->mData.mY; - - ESM::Pathgrid::Point dest(static_cast(mX), static_cast(mY), static_cast(mZ)); - - ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos)); - - mPathFinder.buildPath(start, dest, actor.getCell(), true); - } - - if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1])) - { - movement.mPosition[1] = 0; return true; } - - zTurn(actor, Ogre::Degree(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]))); - movement.mPosition[1] = 1; - return false; } diff --git a/apps/openmw/mwmechanics/aitravel.hpp b/apps/openmw/mwmechanics/aitravel.hpp index c2732e3aa4..a5a4577e60 100644 --- a/apps/openmw/mwmechanics/aitravel.hpp +++ b/apps/openmw/mwmechanics/aitravel.hpp @@ -34,6 +34,9 @@ namespace MWMechanics virtual int getTypeId() const; + protected: + virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell); + private: float mX; float mY; From cb8ca2f03a751373b81e15f75b05b691bb2dee58 Mon Sep 17 00:00:00 2001 From: dteviot Date: Thu, 11 Jun 2015 18:31:35 +1200 Subject: [PATCH 04/33] Moved logic for building a Sync'ed path from AiCombat to PathFinding. Is now used by AiFollow, which should fix "running in circles" bug caused when recalc a path and closest way point is the one NPC has just passed. --- apps/openmw/mwmechanics/aicombat.cpp | 54 ++++++++++--------------- apps/openmw/mwmechanics/aicombat.hpp | 3 ++ apps/openmw/mwmechanics/aipackage.cpp | 2 +- apps/openmw/mwmechanics/pathfinding.cpp | 38 +++++++++++------ apps/openmw/mwmechanics/pathfinding.hpp | 12 +++--- 5 files changed, 56 insertions(+), 53 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 649f259d9a..8f43c6280d 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -677,44 +677,32 @@ namespace MWMechanics return false; } + bool AiCombat::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell) + { + if (!mPathFinder.getPath().empty()) + { + Ogre::Vector3 currPathTarget(PathFinder::MakeOgreVector3(mPathFinder.getPath().back())); + Ogre::Vector3 newPathTarget = PathFinder::MakeOgreVector3(dest); + float dist = (newPathTarget - currPathTarget).length(); + float targetPosThreshold = (cell->isExterior()) ? 300.0f : 100.0f; + return dist > targetPosThreshold; + } + else + { + // necessarily construct a new path + return true; + } + } + void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target) { - Ogre::Vector3 newPathTarget = Ogre::Vector3(target.getRefData().getPosition().pos); - - float dist; - - if(!mPathFinder.getPath().empty()) - { - ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back(); - Ogre::Vector3 currPathTarget(PathFinder::MakeOgreVector3(lastPt)); - dist = (newPathTarget - currPathTarget).length(); - } - else dist = 1e+38F; // necessarily construct a new path - - float targetPosThreshold = (actor.getCell()->getCell()->isExterior())? 300.0f : 100.0f; + ESM::Pathgrid::Point newPathTarget = PathFinder::MakePathgridPoint(target.getRefData().getPosition()); //construct new path only if target has moved away more than on [targetPosThreshold] - if(dist > targetPosThreshold) + if (doesPathNeedRecalc(newPathTarget, actor.getCell()->getCell())) { - ESM::Position pos = actor.getRefData().getPosition(); - - ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos)); - - ESM::Pathgrid::Point dest(PathFinder::MakePathgridPoint(newPathTarget)); - - if(!mPathFinder.isPathConstructed()) - mPathFinder.buildPath(start, dest, actor.getCell(), false); - else - { - PathFinder newPathFinder; - newPathFinder.buildPath(start, dest, actor.getCell(), false); - - if(!mPathFinder.getPath().empty()) - { - newPathFinder.syncStart(mPathFinder.getPath()); - mPathFinder = newPathFinder; - } - } + ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(actor.getRefData().getPosition())); + mPathFinder.buildSyncedPath(start, newPathTarget, actor.getCell(), false); } } diff --git a/apps/openmw/mwmechanics/aicombat.hpp b/apps/openmw/mwmechanics/aicombat.hpp index 307df3872c..8248975b58 100644 --- a/apps/openmw/mwmechanics/aicombat.hpp +++ b/apps/openmw/mwmechanics/aicombat.hpp @@ -53,6 +53,9 @@ namespace MWMechanics virtual void writeState(ESM::AiSequence::AiSequence &sequence) const; + protected: + virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell); + private: int mTargetActorId; diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 802a7723ea..216bf7b098 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -68,7 +68,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po if(mTimer > 0.25) { if (doesPathNeedRecalc(dest, cell)) { //Only rebuild path if it's moved - mPathFinder.buildPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved + mPathFinder.buildSyncedPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved mPrevDest = dest; } diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 5795f818af..980de1badd 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -301,23 +301,35 @@ namespace MWMechanics return false; } - // used by AiCombat, see header for the rationale - bool PathFinder::syncStart(const std::list &path) + // see header for the rationale + void PathFinder::buildSyncedPath(const ESM::Pathgrid::Point &startPoint, + const ESM::Pathgrid::Point &endPoint, + const MWWorld::CellStore* cell, + bool allowShortcuts) { if (mPath.size() < 2) - return false; //nothing to pop - - std::list::const_iterator oldStart = path.begin(); - std::list::iterator iter = ++mPath.begin(); - - if( (*iter).mX == oldStart->mX - && (*iter).mY == oldStart->mY - && (*iter).mZ == oldStart->mZ) { - mPath.pop_front(); - return true; + // if path has one point, then it's the destination. + // don't need to worry about bad path for this case + buildPath(startPoint, endPoint, cell, allowShortcuts); + } + else + { + const ESM::Pathgrid::Point oldStart(*getPath().begin()); + buildPath(startPoint, endPoint, cell, allowShortcuts); + if (mPath.size() >= 2) + { + // if 2nd waypoint of new path == 1st waypoint of old, + // delete 1st waypoint of new path. + std::list::iterator iter = ++mPath.begin(); + if (iter->mX == oldStart.mX + && iter->mY == oldStart.mY + && iter->mZ == oldStart.mZ) + { + mPath.pop_front(); + } + } } - return false; } } diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index f48de6624c..0f52a6e19d 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -63,13 +63,13 @@ namespace MWMechanics /** Synchronize new path with old one to avoid visiting 1 waypoint 2 times @note - If the first point is chosen as the nearest one - the situation can occur when the 1st point of the new path is undesirable - (i.e. the 2nd point of new path == the 1st point of old path). - @param path - old path - @return true if such point was found and deleted + BuildPath() takes closest PathGrid point to NPC as first point of path. + This is undesireable if NPC has just passed a Pathgrid point, as this + makes the 2nd point of the new path == the 1st point of old path. + Which results in NPC "running in a circle" back to the just passed waypoint. */ - bool syncStart(const std::list &path); + void buildSyncedPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, + const MWWorld::CellStore* cell, bool allowShortcuts = true); void addPointToPath(ESM::Pathgrid::Point &point) { From 6051c47eef9f88f65412b9f82f3fee7a895866f3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 11 Jun 2015 22:36:19 +0200 Subject: [PATCH 05/33] Fix for incorrect QString -> path conversion --- apps/opencs/editor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 84849cbbba..efd7cf4ec7 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -307,12 +307,12 @@ bool CS::Editor::makeIPCServer() mServer->close(); fullPath.remove(QRegExp("dummy$")); fullPath += mIpcServerName; - if(boost::filesystem::exists(fullPath.toStdString().c_str())) + if(boost::filesystem::exists(fullPath.toUtf8().constData())) { // TODO: compare pid of the current process with that in the file std::cout << "Detected unclean shutdown." << std::endl; // delete the stale file - if(remove(fullPath.toStdString().c_str())) + if(remove(fullPath.toUtf8().constData())) std::cerr << "ERROR removing stale connection file" << std::endl; } } From d03880fbf04a001978c23c7acba0f11156512505 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 11 Jun 2015 23:25:26 +0200 Subject: [PATCH 06/33] Compile fix for old boost versions --- apps/opencs/model/doc/document.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 18a4f48787..b833b527ff 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2272,7 +2272,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, if (boost::filesystem::exists (customFiltersPath)) { - destination << std::ifstream(customFiltersPath.c_str(), std::ios::binary).rdbuf(); + destination << std::ifstream(customFiltersPath.string().c_str(), std::ios::binary).rdbuf(); } else { From fc5176dc3882fe183809bb5060c519641aa2867d Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 11 Jun 2015 23:26:32 +0200 Subject: [PATCH 07/33] Refactor cmake scripts, reducing the amount of find_package(Qt4) --- CMakeLists.txt | 2 ++ apps/launcher/CMakeLists.txt | 4 ++-- apps/opencs/CMakeLists.txt | 5 +++-- apps/wizard/CMakeLists.txt | 4 ++-- components/CMakeLists.txt | 12 +++--------- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec69c5560e..0a75976d4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,6 +151,8 @@ endif() # Dependencies +find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork) + # Fix for not visible pthreads functions for linker with glibc 2.15 if (UNIX AND NOT APPLE) find_package (Threads) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 0de79f8f6b..8be7a20b65 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -57,7 +57,6 @@ set(LAUNCHER_UI source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER}) -find_package(Qt4 REQUIRED) set(QT_USE_QTGUI 1) # Set some platform specific settings @@ -92,7 +91,8 @@ target_link_libraries(openmw-launcher ${OGRE_LIBRARIES} ${OGRE_STATIC_PLUGINS} ${SDL2_LIBRARY_ONLY} - ${QT_LIBRARIES} + ${QT_QTGUI_LIBRARY} + ${QT_QTCORE_LIBRARY} components ) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 37d13223a7..044e8c4eeb 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -160,7 +160,6 @@ endif(WIN32) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED) include(${QT_USE_FILE}) qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI}) @@ -208,7 +207,9 @@ target_link_libraries(openmw-cs ${SHINY_LIBRARIES} ${Boost_LIBRARIES} ${BULLET_LIBRARIES} - ${QT_LIBRARIES} + ${QT_QTGUI_LIBRARY} + ${QT_QTCORE_LIBRARY} + ${QT_QTNETWORK_LIBRARY} components ) diff --git a/apps/wizard/CMakeLists.txt b/apps/wizard/CMakeLists.txt index b8cc3fda4d..55f326a0c1 100644 --- a/apps/wizard/CMakeLists.txt +++ b/apps/wizard/CMakeLists.txt @@ -81,7 +81,6 @@ endif (OPENMW_USE_UNSHIELD) source_group(wizard FILES ${WIZARD} ${WIZARD_HEADER}) -find_package(Qt4 REQUIRED) set(QT_USE_QTGUI 1) # Set some platform specific settings @@ -113,7 +112,8 @@ add_executable(openmw-wizard target_link_libraries(openmw-wizard ${Boost_LIBRARIES} - ${QT_LIBRARIES} + ${QT_QTGUI_LIBRARY} + ${QT_QTCORE_LIBRARY} components ) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 01de1c28e1..951a80509d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -126,11 +126,6 @@ add_component_dir (version set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui ) -find_package(Qt4 COMPONENTS QtCore QtGui) -if(MINGW) -find_package(Bullet REQUIRED COMPONENTS Collision) -endif() - if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (contentselector model/modelitem model/esmfile @@ -167,16 +162,15 @@ target_link_libraries(components ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${OENGINE_LIBRARY} + ${QT_QTCORE_LIBRARY} + ${QT_QTGUI_LIBRARY} + ${BULLET_LIBRARIES} ) if (GIT_CHECKOUT) add_dependencies (components git-version) endif (GIT_CHECKOUT) -if(MINGW) -target_link_libraries(components ${QT_LIBRARIES} ${BULLET_LIBRARIES}) -endif() - if (WIN32) target_link_libraries(components shlwapi) endif() From cf95d3fc356597eb5abb38e08bb4ebd091649f2f Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 11 Jun 2015 23:49:27 +0200 Subject: [PATCH 08/33] Refactor cmake scripts, reducing the amount of find_package(Boost) --- CMakeLists.txt | 2 +- apps/bsatool/CMakeLists.txt | 3 ++- apps/esmtool/CMakeLists.txt | 2 +- apps/essimporter/CMakeLists.txt | 3 ++- apps/launcher/CMakeLists.txt | 1 - apps/mwiniimporter/CMakeLists.txt | 3 ++- apps/opencs/CMakeLists.txt | 19 ++++++++++--------- apps/openmw/CMakeLists.txt | 17 +++++------------ apps/wizard/CMakeLists.txt | 1 - components/CMakeLists.txt | 6 +++++- extern/ogre-ffmpeg-videoplayer/CMakeLists.txt | 5 +---- 11 files changed, 29 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a75976d4c..4b447a3e8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,7 @@ if (HAVE_UNORDERED_MAP) endif () -set(BOOST_COMPONENTS system filesystem program_options) +set(BOOST_COMPONENTS system filesystem program_options thread wave) if(WIN32) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale) endif(WIN32) diff --git a/apps/bsatool/CMakeLists.txt b/apps/bsatool/CMakeLists.txt index 3f1988a709..27baff8157 100644 --- a/apps/bsatool/CMakeLists.txt +++ b/apps/bsatool/CMakeLists.txt @@ -9,7 +9,8 @@ add_executable(bsatool ) target_link_libraries(bsatool - ${Boost_LIBRARIES} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} components ) diff --git a/apps/esmtool/CMakeLists.txt b/apps/esmtool/CMakeLists.txt index 1d00262151..1d5e662d83 100644 --- a/apps/esmtool/CMakeLists.txt +++ b/apps/esmtool/CMakeLists.txt @@ -13,7 +13,7 @@ add_executable(esmtool ) target_link_libraries(esmtool - ${Boost_LIBRARIES} + ${Boost_PROGRAM_OPTIONS_LIBRARY} components ) diff --git a/apps/essimporter/CMakeLists.txt b/apps/essimporter/CMakeLists.txt index 72ef364ee6..84e31dad9e 100644 --- a/apps/essimporter/CMakeLists.txt +++ b/apps/essimporter/CMakeLists.txt @@ -33,7 +33,8 @@ add_executable(openmw-essimporter ) target_link_libraries(openmw-essimporter - ${Boost_LIBRARIES} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} components ) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 8be7a20b65..e392b8efc4 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -87,7 +87,6 @@ add_executable(openmw-launcher ) target_link_libraries(openmw-launcher - ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${OGRE_STATIC_PLUGINS} ${SDL2_LIBRARY_ONLY} diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index 753c86fef6..e522df6a18 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -14,7 +14,8 @@ add_executable(openmw-iniimporter ) target_link_libraries(openmw-iniimporter - ${Boost_LIBRARIES} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} components ) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 044e8c4eeb..c011f46950 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -153,13 +153,6 @@ if(WIN32) set(QT_USE_QTMAIN TRUE) endif(WIN32) -set(BOOST_COMPONENTS system filesystem program_options thread wave) -if(WIN32) - set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale) -endif(WIN32) - -find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) - include(${QT_USE_FILE}) qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI}) @@ -205,14 +198,22 @@ target_link_libraries(openmw-cs ${OGRE_Overlay_LIBRARIES} ${OGRE_STATIC_PLUGINS} ${SHINY_LIBRARIES} - ${Boost_LIBRARIES} - ${BULLET_LIBRARIES} + ${Boost_SYSTEM_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_WAVE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTNETWORK_LIBRARY} + ${BULLET_LIBRARIES} components ) +if (WIN32) + target_link_libraries(openmw-cs ${Boost_LOCALE_LIBRARY}) +endif() + + if(APPLE) INSTALL(TARGETS openmw-cs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE) endif() diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a183d172dc..c7c701d20e 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -91,17 +91,6 @@ add_openmw_dir (mwbase ) # Main executable -if (ANDROID) - set(BOOST_COMPONENTS system filesystem program_options thread wave atomic) -else () - set(BOOST_COMPONENTS system filesystem program_options thread wave) -endif () - -if(WIN32) - set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale) -endif(WIN32) - -find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) if (NOT ANDROID) add_executable(openmw @@ -126,10 +115,14 @@ target_link_libraries(openmw ${OGRE_LIBRARIES} ${OGRE_STATIC_PLUGINS} ${SHINY_LIBRARIES} - ${Boost_LIBRARIES} ${OPENAL_LIBRARY} ${SOUND_INPUT_LIBRARY} ${BULLET_LIBRARIES} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_WAVE_LIBRARY} ${MYGUI_LIBRARIES} ${SDL2_LIBRARY} ${MYGUI_PLATFORM_LIBRARIES} diff --git a/apps/wizard/CMakeLists.txt b/apps/wizard/CMakeLists.txt index 55f326a0c1..6506541ee9 100644 --- a/apps/wizard/CMakeLists.txt +++ b/apps/wizard/CMakeLists.txt @@ -111,7 +111,6 @@ add_executable(openmw-wizard ) target_link_libraries(openmw-wizard - ${Boost_LIBRARIES} ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY} components diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 951a80509d..a6ca2e86d2 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -159,7 +159,11 @@ include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) target_link_libraries(components - ${Boost_LIBRARIES} + ${Boost_SYSTEM_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_WAVE_LIBRARY} ${OGRE_LIBRARIES} ${OENGINE_LIBRARY} ${QT_QTCORE_LIBRARY} diff --git a/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt b/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt index 299a57799b..4e8f55eb88 100644 --- a/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt +++ b/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt @@ -32,11 +32,8 @@ endif() include_directories(${FFMPEG_INCLUDE_DIRS}) # Find Boost -set(BOOST_COMPONENTS thread) -find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -include_directories(${Boost_INCLUDE_DIRS}) add_library(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} STATIC ${OGRE_FFMPEG_VIDEOPLAYER_SOURCE_FILES}) -target_link_libraries(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} ${VIDEO_FFMPEG_LIBRARIES} ${Boost_LIBRARIES}) +target_link_libraries(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} ${VIDEO_FFMPEG_LIBRARIES} ${Boost_THREAD_LIBRARY}) link_directories(${CMAKE_CURRENT_BINARY_DIR}) From 45fcea929ace0facf156cf85457153e5ddfb66a3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Jun 2015 01:45:48 +0200 Subject: [PATCH 09/33] Refactor cmake scripts, reducing the amount of find_package(FFmpeg) --- CMakeLists.txt | 15 ++++++++----- extern/ogre-ffmpeg-videoplayer/CMakeLists.txt | 22 +------------------ 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b447a3e8e..b9282faeec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,25 +98,30 @@ endif() cmake_minimum_required(VERSION 2.6) # Sound setup -set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE) unset(FFMPEG_LIBRARIES CACHE) -find_package(FFmpeg) + +find_package(FFmpeg REQUIRED) + +set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARY}) + +message(STATUS ${FFMPEG_LIBRARIES}) if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND ) message(FATAL_ERROR "FFmpeg component required, but not found!") endif() set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS}) -set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES}) if( SWRESAMPLE_FOUND ) add_definitions(-DHAVE_LIBSWRESAMPLE) - set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES}) + set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES}) else() if( AVRESAMPLE_FOUND ) - set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES}) + set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES}) else() message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).") endif() endif() +set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES}) + # TinyXML option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF) if(USE_SYSTEM_TINYXML) diff --git a/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt b/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt index 4e8f55eb88..cda3d39e83 100644 --- a/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt +++ b/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt @@ -11,29 +11,9 @@ set(OGRE_FFMPEG_VIDEOPLAYER_SOURCE_FILES audiofactory.hpp ) -# Find FFMPEG -set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE) -unset(FFMPEG_LIBRARIES CACHE) -find_package(FFmpeg) -if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND ) - message(FATAL_ERROR "FFmpeg component required, but not found!") -endif() -set(VIDEO_FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES}) -if( SWRESAMPLE_FOUND ) - add_definitions(-DHAVE_LIBSWRESAMPLE) - set(VIDEO_FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES}) -else() - if( AVRESAMPLE_FOUND ) - set(VIDEO_FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES}) - else() - message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).") - endif() -endif() -include_directories(${FFMPEG_INCLUDE_DIRS}) - # Find Boost add_library(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} STATIC ${OGRE_FFMPEG_VIDEOPLAYER_SOURCE_FILES}) -target_link_libraries(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} ${VIDEO_FFMPEG_LIBRARIES} ${Boost_THREAD_LIBRARY}) +target_link_libraries(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} ${FFMPEG_LIBRARIES} ${Boost_THREAD_LIBRARY}) link_directories(${CMAKE_CURRENT_BINARY_DIR}) From c04f6cf16766d37fb65d5081290d820e4ddab4d3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Jun 2015 01:58:13 +0200 Subject: [PATCH 10/33] Remove unused code --- components/contentselector/model/contentmodel.cpp | 11 ----------- components/contentselector/model/contentmodel.hpp | 1 - 2 files changed, 12 deletions(-) diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 62f6d90141..d000290e6f 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -30,17 +30,6 @@ ContentSelectorModel::ContentModel::~ContentModel() void ContentSelectorModel::ContentModel::setEncoding(const QString &encoding) { mEncoding = encoding; - if (encoding == QLatin1String("win1252")) - mCodec = QTextCodec::codecForName("windows-1252"); - - else if (encoding == QLatin1String("win1251")) - mCodec = QTextCodec::codecForName("windows-1251"); - - else if (encoding == QLatin1String("win1250")) - mCodec = QTextCodec::codecForName("windows-1250"); - - else - return; // This should never happen; } int ContentSelectorModel::ContentModel::columnCount(const QModelIndex &parent) const diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index 6585558520..ab965ad69c 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -81,7 +81,6 @@ namespace ContentSelectorModel ContentFileList mFiles; QHash mCheckStates; QSet mPluginsWithLoadOrderError; - QTextCodec *mCodec; QString mEncoding; QIcon mWarningIcon; From 4b5c2398a10e57d74c73d888e386118b6227ccdc Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Jun 2015 02:00:06 +0200 Subject: [PATCH 11/33] Remove QTextCodec::setCodecForCStrings Not needed, we're using QString::fromUtf8/toUtf8 to handle encodings correctly. --- apps/launcher/main.cpp | 3 --- apps/wizard/main.cpp | 3 --- 2 files changed, 6 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index ba06861107..32fe8c93a7 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -54,9 +54,6 @@ int main(int argc, char *argv[]) QDir::setCurrent(dir.absolutePath()); - // Support non-latin characters - QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); - Launcher::MainDialog mainWin; Launcher::FirstRunDialogResult result = mainWin.showFirstRunDialog(); diff --git a/apps/wizard/main.cpp b/apps/wizard/main.cpp index e6a94118af..c861a4ac89 100644 --- a/apps/wizard/main.cpp +++ b/apps/wizard/main.cpp @@ -38,9 +38,6 @@ int main(int argc, char *argv[]) QDir::setCurrent(dir.absolutePath()); - // Support non-latin characters - QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); - Wizard::MainWizard wizard; wizard.show(); From e13a9388961039b0d8fe3b1e76e295e1c5054041 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Jun 2015 15:10:12 +0200 Subject: [PATCH 12/33] Add support to build with Qt5 (Task #2665) Known issue: the render view doesn't work in Qt5. With the switch to OSG around the corner, this isn't worth fixing. --- CMakeLists.txt | 14 +++++- apps/launcher/CMakeLists.txt | 23 ++++++--- apps/opencs/CMakeLists.txt | 27 +++++++--- apps/opencs/model/world/idtableproxymodel.cpp | 3 +- apps/opencs/view/doc/view.cpp | 2 +- apps/opencs/view/doc/viewmanager.cpp | 6 +-- .../view/render/unpagedworldspacewidget.cpp | 2 +- apps/opencs/view/render/worldspacewidget.cpp | 7 ++- apps/opencs/view/settings/dialog.cpp | 9 +--- apps/opencs/view/settings/dialog.hpp | 5 -- apps/opencs/view/tools/reporttable.cpp | 6 +++ apps/opencs/view/widget/scenetoolrun.cpp | 5 ++ apps/opencs/view/world/dragrecordtable.cpp | 1 + apps/opencs/view/world/dragrecordtable.hpp | 2 +- apps/opencs/view/world/nestedtable.cpp | 4 ++ apps/opencs/view/world/nestedtable.hpp | 2 +- apps/opencs/view/world/table.cpp | 4 ++ apps/opencs/view/world/table.hpp | 2 +- apps/opencs/view/world/tablesubview.cpp | 1 + apps/wizard/CMakeLists.txt | 25 +++++++--- apps/wizard/unshield/unshieldworker.cpp | 1 - apps/wizard/unshield/unshieldworker.hpp | 1 - components/CMakeLists.txt | 49 +++++++++++-------- 23 files changed, 131 insertions(+), 70 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9282faeec..5f3a0fcc1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,6 @@ find_package(FFmpeg REQUIRED) set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARY}) -message(STATUS ${FFMPEG_LIBRARIES}) if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND ) message(FATAL_ERROR "FFmpeg component required, but not found!") endif() @@ -156,7 +155,18 @@ endif() # Dependencies -find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork) +set(DESIRED_QT_VERSION 4 CACHE STRING "The QT version OpenMW should use (4 or 5)") +message(STATUS "Using Qt${DESIRED_QT_VERSION}") + +if (DESIRED_QT_VERSION MATCHES 4) + find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork) +else() + find_package(Qt5Widgets REQUIRED) + find_package(Qt5Core REQUIRED) + find_package(Qt5Network REQUIRED) + # Instruct CMake to run moc automatically when needed. + #set(CMAKE_AUTOMOC ON) +endif() # Fix for not visible pthreads functions for linker with glibc 2.15 if (UNIX AND NOT APPLE) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index e392b8efc4..66cc157d3b 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -65,12 +65,17 @@ if(WIN32) set(QT_USE_QTMAIN TRUE) endif(WIN32) -QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc) -QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC}) -QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) +if (DESIRED_QT_VERSION MATCHES 4) + include(${QT_USE_FILE}) + QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc) + QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC}) + QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) +else() + QT5_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc) + QT5_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC}) + QT5_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) +endif() - -include(${QT_USE_FILE}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) if(NOT WIN32) include_directories(${LIBUNSHIELD_INCLUDE_DIR}) @@ -90,14 +95,18 @@ target_link_libraries(openmw-launcher ${OGRE_LIBRARIES} ${OGRE_STATIC_PLUGINS} ${SDL2_LIBRARY_ONLY} - ${QT_QTGUI_LIBRARY} - ${QT_QTCORE_LIBRARY} components ) +if (DESIRED_QT_VERSION MATCHES 4) + target_link_libraries(openmw-launcher ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY}) +else() + qt5_use_modules(openmw-launcher Widgets Core) +endif() if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) target_link_libraries(openmw-launcher gcov) endif() + diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index c011f46950..402bd335ab 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -153,11 +153,16 @@ if(WIN32) set(QT_USE_QTMAIN TRUE) endif(WIN32) -include(${QT_USE_FILE}) - -qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI}) -qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT}) -qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES}) +if (DESIRED_QT_VERSION MATCHES 4) + include(${QT_USE_FILE}) + qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI}) + qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT}) + qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES}) +else() + qt5_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI}) + qt5_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT}) + qt5_add_resources(OPENCS_RES_SRC ${OPENCS_RES}) +endif() # for compiled .ui files include_directories(${CMAKE_CURRENT_BINARY_DIR}) @@ -202,13 +207,19 @@ target_link_libraries(openmw-cs ${Boost_FILESYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_WAVE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTCORE_LIBRARY} - ${QT_QTNETWORK_LIBRARY} ${BULLET_LIBRARIES} components ) +if (DESIRED_QT_VERSION MATCHES 4) + target_link_libraries(openmw-cs + ${QT_QTGUI_LIBRARY} + ${QT_QTCORE_LIBRARY} + ${QT_QTNETWORK_LIBRARY}) +else() + qt5_use_modules(openmw-cs Widgets Core Network) +endif() + if (WIN32) target_link_libraries(openmw-cs ${Boost_LOCALE_LIBRARY}) endif() diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index d8932d2057..5166447138 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -52,9 +52,10 @@ QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, i void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr& filter) { + beginResetModel(); mFilter = filter; updateColumnMap(); - reset(); + endResetModel(); } bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 2485caa883..64b066eb1e 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index b2f681df17..7c79302d74 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include "../../model/doc/documentmanager.hpp" #include "../../model/doc/document.hpp" @@ -24,10 +26,6 @@ #include "view.hpp" -#include -#include -#include - void CSVDoc::ViewManager::updateIndices() { std::map > documents; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 462b62b7a8..383382938d 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -6,7 +6,7 @@ #include #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 e888148186..ba0ec84460 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -7,7 +7,12 @@ #include #include -#include +#include +#include +#include +#include +#include +#include #include "../../model/world/universalid.hpp" #include "../../model/world/idtable.hpp" diff --git a/apps/opencs/view/settings/dialog.cpp b/apps/opencs/view/settings/dialog.cpp index e8832e2bcc..38eb7bbc7f 100644 --- a/apps/opencs/view/settings/dialog.cpp +++ b/apps/opencs/view/settings/dialog.cpp @@ -8,19 +8,12 @@ #include #include #include +#include #include "../../model/settings/usersettings.hpp" #include "page.hpp" -#include - -#include -#include -#include - -#include -#include CSVSettings::Dialog::Dialog(QMainWindow *parent) : SettingWindow (parent), mStackedWidget (0), mDebugMode (false) diff --git a/apps/opencs/view/settings/dialog.hpp b/apps/opencs/view/settings/dialog.hpp index cb85bddb98..e3a3f575ac 100644 --- a/apps/opencs/view/settings/dialog.hpp +++ b/apps/opencs/view/settings/dialog.hpp @@ -3,7 +3,6 @@ #include "settingwindow.hpp" #include "resizeablestackedwidget.hpp" -#include class QStackedWidget; class QListWidget; @@ -26,10 +25,6 @@ namespace CSVSettings { explicit Dialog (QMainWindow *parent = 0); - ///Enables setting debug mode. When the dialog opens, a page is created - ///which displays the SettingModel's contents in a Tree view. - void enableDebugMode (bool state, QStandardItemModel *model = 0); - protected: /// Settings are written on close diff --git a/apps/opencs/view/tools/reporttable.cpp b/apps/opencs/view/tools/reporttable.cpp index 7cfe8e4f05..c1c8a35dd3 100644 --- a/apps/opencs/view/tools/reporttable.cpp +++ b/apps/opencs/view/tools/reporttable.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "../../model/tools/reportmodel.hpp" @@ -121,7 +123,11 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id, bool richTextDescription, QWidget *parent) : CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id)) { +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive); +#else horizontalHeader()->setResizeMode (QHeaderView::Interactive); +#endif horizontalHeader()->setStretchLastSection (true); verticalHeader()->hide(); setSortingEnabled (true); diff --git a/apps/opencs/view/widget/scenetoolrun.cpp b/apps/opencs/view/widget/scenetoolrun.cpp index 8de334efeb..4c9eb676e8 100644 --- a/apps/opencs/view/widget/scenetoolrun.cpp +++ b/apps/opencs/view/widget/scenetoolrun.cpp @@ -65,8 +65,13 @@ CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& tool mTable->setShowGrid (false); mTable->verticalHeader()->hide(); mTable->horizontalHeader()->hide(); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch); + mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents); +#else mTable->horizontalHeader()->setResizeMode (0, QHeaderView::Stretch); mTable->horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents); +#endif mTable->setSelectionMode (QAbstractItemView::NoSelection); layout->addWidget (mTable); diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp index 7032fee6d2..2a1ae1f401 100644 --- a/apps/opencs/view/world/dragrecordtable.cpp +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -1,4 +1,5 @@ #include +#include #include "../../model/world/tablemimedata.hpp" #include "dragrecordtable.hpp" diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp index 4996c03acd..48f9e25280 100644 --- a/apps/opencs/view/world/dragrecordtable.hpp +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -2,7 +2,7 @@ #define CSV_WORLD_DRAGRECORDTABLE_H #include -#include +#include class QWidget; class QAction; diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index 5c8762020f..112873cb9a 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -23,7 +23,11 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, setSelectionBehavior (QAbstractItemView::SelectRows); setSelectionMode (QAbstractItemView::ExtendedSelection); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive); +#else horizontalHeader()->setResizeMode (QHeaderView::Interactive); +#endif verticalHeader()->hide(); int columns = model->columnCount(QModelIndex()); diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index b8e91844c2..5db977942a 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -2,7 +2,7 @@ #define CSV_WORLD_NESTEDTABLE_H #include -#include +#include class QUndoStack; class QAction; diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index bb3dfa4d32..b4efbd3c8f 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -282,7 +282,11 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, mDispatcher = new CSMWorld::CommandDispatcher (document, id, this); setModel (mProxyModel); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive); +#else horizontalHeader()->setResizeMode (QHeaderView::Interactive); +#endif verticalHeader()->hide(); setSortingEnabled (sorting); setSelectionBehavior (QAbstractItemView::SelectRows); diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index becb21f65d..67bf3fe857 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include "../../model/filter/node.hpp" #include "../../model/world/columnbase.hpp" diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index af0b644475..faff4c429b 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "../../model/doc/document.hpp" #include "../../model/world/tablemimedata.hpp" diff --git a/apps/wizard/CMakeLists.txt b/apps/wizard/CMakeLists.txt index 6506541ee9..5cd874863b 100644 --- a/apps/wizard/CMakeLists.txt +++ b/apps/wizard/CMakeLists.txt @@ -89,12 +89,17 @@ if(WIN32) set(QT_USE_QTMAIN TRUE) endif(WIN32) -QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/wizard/wizard.qrc) -QT4_WRAP_CPP(MOC_SRCS ${WIZARD_HEADER_MOC}) -QT4_WRAP_UI(UI_HDRS ${WIZARD_UI}) +if (DESIRED_QT_VERSION MATCHES 4) + include(${QT_USE_FILE}) + QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/wizard/wizard.qrc) + QT4_WRAP_CPP(MOC_SRCS ${WIZARD_HEADER_MOC}) + QT4_WRAP_UI(UI_HDRS ${WIZARD_UI}) +else() + QT5_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/wizard/wizard.qrc) + QT5_WRAP_CPP(MOC_SRCS ${WIZARD_HEADER_MOC}) + QT5_WRAP_UI(UI_HDRS ${WIZARD_UI}) +endif() - -include(${QT_USE_FILE}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) if (OPENMW_USE_UNSHIELD) @@ -111,11 +116,17 @@ add_executable(openmw-wizard ) target_link_libraries(openmw-wizard - ${QT_QTGUI_LIBRARY} - ${QT_QTCORE_LIBRARY} components ) +if (DESIRED_QT_VERSION MATCHES 4) + target_link_libraries(openmw-wizard + ${QT_QTGUI_LIBRARY} + ${QT_QTCORE_LIBRARY}) +else() + qt5_use_modules(openmw-wizard Widgets Core) +endif() + if (OPENMW_USE_UNSHIELD) target_link_libraries(openmw-wizard ${LIBUNSHIELD_LIBRARY}) endif() diff --git a/apps/wizard/unshield/unshieldworker.cpp b/apps/wizard/unshield/unshieldworker.cpp index 11e090ed18..9daea2b71a 100644 --- a/apps/wizard/unshield/unshieldworker.cpp +++ b/apps/wizard/unshield/unshieldworker.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/apps/wizard/unshield/unshieldworker.hpp b/apps/wizard/unshield/unshieldworker.hpp index 5ea7b04aee..c1d3cfff1f 100644 --- a/apps/wizard/unshield/unshieldworker.hpp +++ b/apps/wizard/unshield/unshieldworker.hpp @@ -24,7 +24,6 @@ namespace Wizard class UnshieldWorker : public QObject { Q_OBJECT - Q_ENUMS(Wizard::Component) public: UnshieldWorker(QObject *parent = 0); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index a6ca2e86d2..cbb63bf073 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -126,27 +126,30 @@ add_component_dir (version set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui ) -if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) - add_component_qt_dir (contentselector - model/modelitem model/esmfile - model/naturalsort model/contentmodel - model/loadordererror - view/combobox view/contentselector - ) - add_component_qt_dir (config - gamesettings - launchersettings - settingsbase - ) - - add_component_qt_dir (process - processinvoker +add_component_qt_dir (contentselector + model/modelitem model/esmfile + model/naturalsort model/contentmodel + model/loadordererror + view/combobox view/contentselector + ) +add_component_qt_dir (config + gamesettings + launchersettings + settingsbase ) - include(${QT_USE_FILE}) +add_component_qt_dir (process + processinvoker +) + +if (DESIRED_QT_VERSION MATCHES 4) + include(${QT_USE_FILE}) QT4_WRAP_UI(ESM_UI_HDR ${ESM_UI}) - QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) -endif(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) + QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) +else() + QT5_WRAP_UI(ESM_UI_HDR ${ESM_UI}) + QT5_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) +endif() if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" AND NOT APPLE) @@ -166,11 +169,17 @@ target_link_libraries(components ${Boost_WAVE_LIBRARY} ${OGRE_LIBRARIES} ${OENGINE_LIBRARY} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} ${BULLET_LIBRARIES} ) +if (DESIRED_QT_VERSION MATCHES 4) + target_link_libraries(components + ${QT_QTCORE_LIBRARY} + ${QT_QTGUI_LIBRARY}) +else() + qt5_use_modules(components Widgets Core) +endif() + if (GIT_CHECKOUT) add_dependencies (components git-version) endif (GIT_CHECKOUT) From 89c2a7e26b402e27224d414dc4cf33e2653288a7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Jun 2015 15:22:19 +0200 Subject: [PATCH 13/33] Fix for possibly missing library on windows --- apps/mwiniimporter/CMakeLists.txt | 5 +++++ components/CMakeLists.txt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index e522df6a18..4024c0b42a 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -19,6 +19,11 @@ target_link_libraries(openmw-iniimporter components ) +if (WIN32) + target_link_libraries(openmw-iniimporter + ${Boost_LOCALE_LIBRARY}) +endif() + if (MINGW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") endif() diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index cbb63bf073..1b33b10f6d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -172,6 +172,11 @@ target_link_libraries(components ${BULLET_LIBRARIES} ) +if (WIN32) + target_link_libraries(components + ${Boost_LOCALE_LIBRARY}) +endif() + if (DESIRED_QT_VERSION MATCHES 4) target_link_libraries(components ${QT_QTCORE_LIBRARY} From 650e37dba1cf8feb922eda3b16c93048ddc8297b Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Fri, 12 Jun 2015 22:31:12 +0300 Subject: [PATCH 14/33] RegionMap uses proper colors --- apps/opencs/model/world/regionmap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/regionmap.cpp b/apps/opencs/model/world/regionmap.cpp index f63426c04a..42bde9c81a 100644 --- a/apps/opencs/model/world/regionmap.cpp +++ b/apps/opencs/model/world/regionmap.cpp @@ -334,9 +334,9 @@ QVariant CSMWorld::RegionMap::data (const QModelIndex& index, int role) const mColours.find (Misc::StringUtils::lowerCase (cell->second.mRegion)); if (iter!=mColours.end()) - return QBrush ( - QColor (iter->second>>24, (iter->second>>16) & 255, (iter->second>>8) & 255, - iter->second & 255)); + return QBrush (QColor (iter->second & 0xff, + (iter->second >> 8) & 0xff, + (iter->second >> 16) & 0xff)); if (cell->second.mRegion.empty()) return QBrush (Qt::Dense6Pattern); // no region From b81454d226c2ea919b2a48eb6482f7b5553bd5a0 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 13 Jun 2015 14:37:47 +1000 Subject: [PATCH 15/33] Fix using wrong bit flag for NPC stats auto-calculation. Also set the corresponding mNpdtType which is used when determining which data structure to save. Should resolve Bug #2668. --- apps/esmtool/labels.cpp | 24 +++++++++---------- .../opencs/model/tools/referenceablecheck.cpp | 2 +- apps/opencs/model/world/refidadapterimp.cpp | 4 ++++ components/esm/loadnpc.hpp | 12 +++++----- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index 88e188df01..883a9e7280 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -119,7 +119,7 @@ std::string clothingTypeLabel(int idx) } std::string armorTypeLabel(int idx) -{ +{ if (idx >= 0 && idx <= 10) { static const char *armorTypeLabels[] = { @@ -645,7 +645,7 @@ std::string ruleFunction(int idx) else return "Invalid"; } - + // The "unused flag bits" should probably be defined alongside the // defined bits in the ESM component. The names of the flag bits are // very inconsistent. @@ -653,7 +653,7 @@ std::string ruleFunction(int idx) std::string bodyPartFlags(int flags) { std::string properties = ""; - if (flags == 0) properties += "[None] "; + if (flags == 0) properties += "[None] "; if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable "; int unused = (0xFFFFFFFF ^ @@ -667,7 +667,7 @@ std::string bodyPartFlags(int flags) std::string cellFlags(int flags) { std::string properties = ""; - if (flags == 0) properties += "[None] "; + if (flags == 0) properties += "[None] "; if (flags & ESM::Cell::HasWater) properties += "HasWater "; if (flags & ESM::Cell::Interior) properties += "Interior "; if (flags & ESM::Cell::NoSleep) properties += "NoSleep "; @@ -830,12 +830,12 @@ std::string npcFlags(int flags) std::string properties = ""; if (flags == 0) properties += "[None] "; // Mythicmods and the ESM component differ. Mythicmods says - // 0x8=None and 0x10=AutoCalc, while our code defines 0x8 as - // AutoCalc. The former seems to be correct. All Bethesda - // records have bit 0x8 set. A suspiciously large portion of - // females have autocalc turned off. - if (flags & ESM::NPC::Autocalc) properties += "Unknown "; - if (flags & 0x00000010) properties += "Autocalc "; + // 0x8=None and 0x10=AutoCalc, while our code previously defined + // 0x8 as AutoCalc. The former seems to be correct. All Bethesda + // records have bit 0x8 set. Previously, suspiciously large portion + // of females had autocalc turned off. + if (flags & 0x00000008) properties += "Unknown "; + if (flags & ESM::NPC::Autocalc) properties += "Autocalc "; if (flags & ESM::NPC::Female) properties += "Female "; if (flags & ESM::NPC::Respawn) properties += "Respawn "; if (flags & ESM::NPC::Essential) properties += "Essential "; @@ -847,8 +847,8 @@ std::string npcFlags(int flags) // however the only unknown bit occurs on ALL records, and // relatively few NPCs have this bit set. int unused = (0xFFFFFFFF ^ - (ESM::NPC::Autocalc| - 0x00000010| + (0x00000008| + ESM::NPC::Autocalc| ESM::NPC::Female| ESM::NPC::Respawn| ESM::NPC::Essential| diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 548fcd36f6..6b323547f0 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -648,7 +648,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated { - if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag + if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0010 = autocalculated flag { messages.push_back (std::make_pair (id, npc.mId + " mNpdtType or flags mismatch!")); //should not happend? return; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index d31a9ceaae..cb71319c87 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -546,6 +546,10 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d record.get().mFlags |= iter->second; else record.get().mFlags &= ~iter->second; + + if (iter->second == ESM::NPC::Autocalc) + record.get().mNpdtType = (value.toInt() != 0) ? ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS + : ESM::NPC::NPC_DEFAULT; } else ActorRefIdAdapter::setData (column, data, index, value); diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index b535b91b01..281020c981 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -52,12 +52,12 @@ struct NPC enum Flags { - Female = 0x0001, - Essential = 0x0002, - Respawn = 0x0004, - Autocalc = 0x0008, - Skeleton = 0x0400, // Skeleton blood effect (white) - Metal = 0x0800 // Metal blood effect (golden?) + Female = 0x0001, + Essential = 0x0002, + Respawn = 0x0004, + Autocalc = 0x0010, + Skeleton = 0x0400, // Skeleton blood effect (white) + Metal = 0x0800 // Metal blood effect (golden?) }; enum NpcType From 5b6984d8d844c812c16776298be6eab05a2e0615 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 13 Jun 2015 22:24:22 +1000 Subject: [PATCH 16/33] Set modified flag in setData() operations, without which the changes weren't being saved. Should resolve Bug #2656. --- apps/opencs/model/world/refidadapterimp.cpp | 169 +++++++++++++++----- 1 file changed, 128 insertions(+), 41 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index cb71319c87..4c369ef24f 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -37,10 +37,18 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); + ESM::Potion potion = record.get(); + if (column==mAutoCalc) - record.get().mData.mAutoCalc = value.toInt(); + potion.mData.mAutoCalc = value.toInt(); else + { InventoryRefIdAdapter::setData (column, data, index, value); + + return; + } + + record.setModified(potion); } @@ -71,12 +79,19 @@ void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdD Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); + ESM::Apparatus apparatus = record.get(); + if (column==mType) - record.get().mData.mType = value.toInt(); + apparatus.mData.mType = value.toInt(); else if (column==mQuality) - record.get().mData.mQuality = value.toFloat(); + apparatus.mData.mQuality = value.toFloat(); else + { InventoryRefIdAdapter::setData (column, data, index, value); + + return; + } + record.setModified(apparatus); } @@ -114,14 +129,22 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); + ESM::Armor armor = record.get(); + if (column==mType) - record.get().mData.mType = value.toInt(); + armor.mData.mType = value.toInt(); else if (column==mHealth) - record.get().mData.mHealth = value.toInt(); + armor.mData.mHealth = value.toInt(); else if (column==mArmor) - record.get().mData.mArmor = value.toInt(); + armor.mData.mArmor = value.toInt(); else + { EnchantableRefIdAdapter::setData (column, data, index, value); + + return; + } + + record.setModified(armor); } CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns, @@ -151,12 +174,20 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); + ESM::Book book = record.get(); + if (column==mScroll) - record.get().mData.mIsScroll = value.toInt(); + book.mData.mIsScroll = value.toInt(); else if (column==mSkill) - record.get().mData.mSkillID = value.toInt(); + book.mData.mSkillID = value.toInt(); else + { EnchantableRefIdAdapter::setData (column, data, index, value); + + return; + } + + record.setModified(book); } CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns, @@ -186,10 +217,18 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); + ESM::Clothing clothing = record.get(); + if (column==mType) - record.get().mData.mType = value.toInt(); + clothing.mData.mType = value.toInt(); else + { EnchantableRefIdAdapter::setData (column, data, index, value); + + return; + } + + record.setModified(clothing); } CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, @@ -226,24 +265,32 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + ESM::Container container = record.get(); + if (column==mWeight) - record.get().mWeight = value.toFloat(); + container.mWeight = value.toFloat(); else if (column==mOrganic) { if (value.toInt()) - record.get().mFlags |= ESM::Container::Organic; + container.mFlags |= ESM::Container::Organic; else - record.get().mFlags &= ~ESM::Container::Organic; + container.mFlags &= ~ESM::Container::Organic; } else if (column==mRespawn) { if (value.toInt()) - record.get().mFlags |= ESM::Container::Respawn; + container.mFlags |= ESM::Container::Respawn; else - record.get().mFlags &= ~ESM::Container::Respawn; + container.mFlags &= ~ESM::Container::Respawn; } else + { NameRefIdAdapter::setData (column, data, index, value); + + return; + } + + record.setModified(container); } CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) @@ -303,20 +350,22 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + ESM::Creature creature = record.get(); + if (column==mColumns.mType) - record.get().mData.mType = value.toInt(); + creature.mData.mType = value.toInt(); else if (column==mColumns.mSoul) - record.get().mData.mSoul = value.toInt(); + creature.mData.mSoul = value.toInt(); else if (column==mColumns.mScale) - record.get().mScale = value.toFloat(); + creature.mScale = value.toFloat(); else if (column==mColumns.mOriginal) - record.get().mOriginal = value.toString().toUtf8().constData(); + creature.mOriginal = value.toString().toUtf8().constData(); else if (column==mColumns.mCombat) - record.get().mData.mCombat = value.toInt(); + creature.mData.mCombat = value.toInt(); else if (column==mColumns.mMagic) - record.get().mData.mMagic = value.toInt(); + creature.mData.mMagic = value.toInt(); else if (column==mColumns.mStealth) - record.get().mData.mStealth = value.toInt(); + creature.mData.mStealth = value.toInt(); else { std::map::const_iterator iter = @@ -325,13 +374,19 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa if (iter!=mColumns.mFlags.end()) { if (value.toInt()!=0) - record.get().mFlags |= iter->second; + creature.mFlags |= iter->second; else - record.get().mFlags &= ~iter->second; + creature.mFlags &= ~iter->second; } else + { ActorRefIdAdapter::setData (column, data, index, value); + + return; + } } + + record.setModified(creature); } CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns, @@ -361,12 +416,20 @@ void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); + ESM::Door door = record.get(); + if (column==mOpenSound) - record.get().mOpenSound = value.toString().toUtf8().constData(); + door.mOpenSound = value.toString().toUtf8().constData(); else if (column==mCloseSound) - record.get().mCloseSound = value.toString().toUtf8().constData(); + door.mCloseSound = value.toString().toUtf8().constData(); else + { NameRefIdAdapter::setData (column, data, index, value); + + return; + } + + record.setModified(door); } CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns) @@ -409,14 +472,16 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); + ESM::Light light = record.get(); + if (column==mColumns.mTime) - record.get().mData.mTime = value.toInt(); + light.mData.mTime = value.toInt(); else if (column==mColumns.mRadius) - record.get().mData.mRadius = value.toInt(); + light.mData.mRadius = value.toInt(); else if (column==mColumns.mColor) - record.get().mData.mColor = value.toInt(); + light.mData.mColor = value.toInt(); else if (column==mColumns.mSound) - record.get().mSound = value.toString().toUtf8().constData(); + light.mSound = value.toString().toUtf8().constData(); else { std::map::const_iterator iter = @@ -425,13 +490,19 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& if (iter!=mColumns.mFlags.end()) { if (value.toInt()!=0) - record.get().mData.mFlags |= iter->second; + light.mData.mFlags |= iter->second; else - record.get().mData.mFlags &= ~iter->second; + light.mData.mFlags &= ~iter->second; } else + { InventoryRefIdAdapter::setData (column, data, index, value); + + return; + } } + + record.setModified (light); } CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key) @@ -456,10 +527,18 @@ void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); + ESM::Miscellaneous misc = record.get(); + if (column==mKey) - record.get().mData.mIsKey = value.toInt(); + misc.mData.mIsKey = value.toInt(); else + { InventoryRefIdAdapter::setData (column, data, index, value); + + return; + } + + record.setModified(misc); } CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) @@ -525,16 +604,18 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + ESM::NPC npc = record.get(); + if (column==mColumns.mRace) - record.get().mRace = value.toString().toUtf8().constData(); + npc.mRace = value.toString().toUtf8().constData(); else if (column==mColumns.mClass) - record.get().mClass = value.toString().toUtf8().constData(); + npc.mClass = value.toString().toUtf8().constData(); else if (column==mColumns.mFaction) - record.get().mFaction = value.toString().toUtf8().constData(); + npc.mFaction = value.toString().toUtf8().constData(); else if (column==mColumns.mHair) - record.get().mHair = value.toString().toUtf8().constData(); + npc.mHair = value.toString().toUtf8().constData(); else if (column==mColumns.mHead) - record.get().mHead = value.toString().toUtf8().constData(); + npc.mHead = value.toString().toUtf8().constData(); else { std::map::const_iterator iter = @@ -543,17 +624,23 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d if (iter!=mColumns.mFlags.end()) { if (value.toInt()!=0) - record.get().mFlags |= iter->second; + npc.mFlags |= iter->second; else - record.get().mFlags &= ~iter->second; + npc.mFlags &= ~iter->second; if (iter->second == ESM::NPC::Autocalc) - record.get().mNpdtType = (value.toInt() != 0) ? ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS - : ESM::NPC::NPC_DEFAULT; + npc.mNpdtType = (value.toInt() != 0) ? ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS + : ESM::NPC::NPC_DEFAULT; } else + { ActorRefIdAdapter::setData (column, data, index, value); + + return; + } } + + record.setModified (npc); } CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter () From 2c15ad5e0cae0a5b211ba59aed38a5810cc643e1 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sat, 13 Jun 2015 19:08:31 +0300 Subject: [PATCH 17/33] Add SoundGens verifier --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/tools/soundgencheck.cpp | 49 +++++++++++++++++++++++ apps/opencs/model/tools/soundgencheck.hpp | 30 ++++++++++++++ apps/opencs/model/tools/tools.cpp | 5 +++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/tools/soundgencheck.cpp create mode 100644 apps/opencs/model/tools/soundgencheck.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 402bd335ab..6a9318319c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -41,7 +41,7 @@ opencs_units (model/tools opencs_units_noqt (model/tools mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck - startscriptcheck search searchoperation searchstage pathgridcheck + startscriptcheck search searchoperation searchstage pathgridcheck soundgencheck ) diff --git a/apps/opencs/model/tools/soundgencheck.cpp b/apps/opencs/model/tools/soundgencheck.cpp new file mode 100644 index 0000000000..68e5edefd3 --- /dev/null +++ b/apps/opencs/model/tools/soundgencheck.cpp @@ -0,0 +1,49 @@ +#include "soundgencheck.hpp" + +#include + +#include "../world/refiddata.hpp" +#include "../world/universalid.hpp" + +CSMTools::SoundGenCheckStage::SoundGenCheckStage(const CSMWorld::IdCollection &soundGens, + const CSMWorld::IdCollection &sounds, + const CSMWorld::RefIdCollection &referenceables) + : mSoundGens(soundGens), + mSounds(sounds), + mReferenceables(referenceables) +{} + +int CSMTools::SoundGenCheckStage::setup() +{ + return mSoundGens.getSize(); +} + +void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages) +{ + const CSMWorld::Record &record = mSoundGens.getRecord(stage); + if (record.isDeleted()) + { + return; + } + + const ESM::SoundGenerator soundGen = record.get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_SoundGen, soundGen.mId); + + if (soundGen.mCreature != "") + { + CSMWorld::RefIdData::LocalIndex creatureIndex = mReferenceables.getDataSet().searchId(soundGen.mCreature); + if (creatureIndex.first == -1) + { + messages.push_back(std::make_pair(id, "No such creature '" + soundGen.mCreature + "'")); + } + else if (creatureIndex.second != CSMWorld::UniversalId::Type_Creature) + { + messages.push_back(std::make_pair(id, "'" + soundGen.mCreature + "' is not a creature")); + } + } + + if (mSounds.searchId(soundGen.mSound) == -1) + { + messages.push_back(std::make_pair(id, "No such sound '" + soundGen.mSound + "'")); + } +} diff --git a/apps/opencs/model/tools/soundgencheck.hpp b/apps/opencs/model/tools/soundgencheck.hpp new file mode 100644 index 0000000000..91b08f979e --- /dev/null +++ b/apps/opencs/model/tools/soundgencheck.hpp @@ -0,0 +1,30 @@ +#ifndef CSM_TOOLS_SOUNDGENCHECK_HPP +#define CSM_TOOLS_SOUNDGENCHECK_HPP + +#include "../world/data.hpp" + +#include "../doc/stage.hpp" + +namespace CSMTools +{ + /// \brief VerifyStage: make sure that sound gen records are internally consistent + class SoundGenCheckStage : public CSMDoc::Stage + { + const CSMWorld::IdCollection &mSoundGens; + const CSMWorld::IdCollection &mSounds; + const CSMWorld::RefIdCollection &mReferenceables; + + public: + SoundGenCheckStage(const CSMWorld::IdCollection &soundGens, + const CSMWorld::IdCollection &sounds, + const CSMWorld::RefIdCollection &referenceables); + + virtual int setup(); + ///< \return number of steps + + virtual void perform(int stage, CSMDoc::Messages &messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; +} + +#endif diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 8d93a94332..7d70abae56 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -27,6 +27,7 @@ #include "startscriptcheck.hpp" #include "searchoperation.hpp" #include "pathgridcheck.hpp" +#include "soundgencheck.hpp" CSMDoc::OperationHolder *CSMTools::Tools::get (int type) { @@ -99,6 +100,10 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mVerifierOperation->appendStage (new PathgridCheckStage (mData.getPathgrids())); + mVerifierOperation->appendStage (new SoundGenCheckStage (mData.getSoundGens(), + mData.getSounds(), + mData.getReferenceables())); + mVerifier.setOperation (mVerifierOperation); } From 281088c93b5325b8726c4ca990ffed3d67819e70 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sat, 13 Jun 2015 19:47:39 +0300 Subject: [PATCH 18/33] Add check for an empty sound field to SoundGens verifier --- apps/opencs/model/tools/soundgencheck.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/soundgencheck.cpp b/apps/opencs/model/tools/soundgencheck.cpp index 68e5edefd3..bdf89f19d2 100644 --- a/apps/opencs/model/tools/soundgencheck.cpp +++ b/apps/opencs/model/tools/soundgencheck.cpp @@ -29,7 +29,7 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages const ESM::SoundGenerator soundGen = record.get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_SoundGen, soundGen.mId); - if (soundGen.mCreature != "") + if (!soundGen.mCreature.empty()) { CSMWorld::RefIdData::LocalIndex creatureIndex = mReferenceables.getDataSet().searchId(soundGen.mCreature); if (creatureIndex.first == -1) @@ -42,7 +42,11 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages } } - if (mSounds.searchId(soundGen.mSound) == -1) + if (soundGen.mSound.empty()) + { + messages.push_back(std::make_pair(id, "Sound is not specified")); + } + else if (mSounds.searchId(soundGen.mSound) == -1) { messages.push_back(std::make_pair(id, "No such sound '" + soundGen.mSound + "'")); } From b7cd62e4dee69a6496b8b8f609f83d115a46ac62 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 13 Jun 2015 23:49:27 +0200 Subject: [PATCH 19/33] Revert "Remove user preference setting option." This reverts commit d3b7cf44d391ba9624f28070e68784352e6f514d. --- apps/launcher/maindialog.cpp | 22 +++++++++++++++++++--- apps/launcher/settingspage.cpp | 8 ++++++++ files/ui/settingspage.ui | 10 ++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 2f7a9db332..27d37dbf03 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -490,7 +490,16 @@ bool Launcher::MainDialog::writeSettings() // Game settings QFile file(userPath + QString("openmw.cfg")); - if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { + QIODevice::OpenMode mode(0); + bool keepComments = mLauncherSettings.value(QString("Settings/keep-comments"), QString("true")) + == QLatin1String("true"); + + if (keepComments) + mode = QIODevice::ReadWrite | QIODevice::Text; + else + mode = QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate; + + if (!file.open(mode)) { // File cannot be opened or created QMessageBox msgBox; msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); @@ -503,8 +512,16 @@ bool Launcher::MainDialog::writeSettings() return false; } + QTextStream stream(&file); + + if (keepComments) + mGameSettings.writeFileWithComments(file); + else + { + stream.setCodec(QTextCodec::codecForName("UTF-8")); + mGameSettings.writeFile(stream); + } - mGameSettings.writeFileWithComments(file); file.close(); // Graphics settings @@ -523,7 +540,6 @@ bool Launcher::MainDialog::writeSettings() return false; } - QTextStream stream(&file); stream.setDevice(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index 843b513914..bc8ffe6180 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -260,6 +260,10 @@ void Launcher::SettingsPage::saveSettings() } else { mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1252")); } + + QString keepComments(saveCommentsCheckBox->isChecked() ? "true" : "false"); + + mLauncherSettings.setValue(QLatin1String("Settings/keep-comments"), keepComments); } bool Launcher::SettingsPage::loadSettings() @@ -271,5 +275,9 @@ bool Launcher::SettingsPage::loadSettings() if (index != -1) languageComboBox->setCurrentIndex(index); + QString keepComments(mLauncherSettings.value(QLatin1String("Settings/keep-comments"))); + + saveCommentsCheckBox->setChecked(keepComments == "true"); + return true; } diff --git a/files/ui/settingspage.ui b/files/ui/settingspage.ui index 7f5e4a7de8..f38ba764c3 100644 --- a/files/ui/settingspage.ui +++ b/files/ui/settingspage.ui @@ -40,6 +40,16 @@ + + + + Keep comments in openmw.cfg + + + false + + + From 3bfe167bc09353fd28c7f729b5d9174819bd4b8a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 13 Jun 2015 23:49:29 +0200 Subject: [PATCH 20/33] Revert "Fix loop where there was a potential for double entry." This reverts commit a439f49c4db32a340826ae9b77c940ca59e79e5f. --- components/config/gamesettings.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index 9af6c97143..c17a5c4f73 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -265,10 +265,7 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) // Below is based on readFile() code, if that changes corresponding change may be // required (for example duplicates may be inserted if the rules don't match) if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#"))) - { stream << *iter << "\n"; - continue; - } if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2) continue; From c54a225467c6e7753dac8bafe6da26b04a8646d5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 13 Jun 2015 23:49:29 +0200 Subject: [PATCH 21/33] Revert "Allow space characters in front of comments." This reverts commit 4902c6679210dee8b5158d05d99b072c2f06a494. --- components/config/gamesettings.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index c17a5c4f73..c0a3b82d1c 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -180,7 +180,7 @@ bool Config::GameSettings::writeFile(QTextStream &stream) // // - If a line in file exists with matching key and first part of value (before ',', // '\n', etc) also matches, then replace the line with that of mUserSettings. -// - else remove line (TODO: maybe replace the line with '#' in front instead?) +// - else remove line (maybe replace the line with '#' in front instead?) // // - If there is no corresponding line in file, add at the end // @@ -224,10 +224,10 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) } QString keyVal; - for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) + for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) { // skip empty or comment lines - if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#"))) + if ((*iter).isEmpty() || (*iter).startsWith("#")) continue; // look for a key in the line @@ -257,14 +257,12 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) // write the new config file QString key; QString value; - for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) + for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) { if ((*iter).isNull()) continue; - // Below is based on readFile() code, if that changes corresponding change may be - // required (for example duplicates may be inserted if the rules don't match) - if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#"))) + if ((*iter).isEmpty() || (*iter).startsWith("#")) stream << *iter << "\n"; if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2) From de98d991b40fdb54d808521a0ba4c39c44491467 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 13 Jun 2015 23:50:04 +0200 Subject: [PATCH 22/33] Revert "Allow comments (lines starting with # character) and blank lines in openmw.cfg. Should resolve Feature #2535." Breaks the saving of content= entry order. This reverts commit 15fe5d88e2b3c7d172a28bd453b3e0d5f89295aa. Conflicts: components/config/gamesettings.cpp --- apps/launcher/maindialog.cpp | 21 +---- apps/launcher/settingspage.cpp | 8 -- components/config/gamesettings.cpp | 128 ----------------------------- components/config/gamesettings.hpp | 2 - files/ui/settingspage.ui | 10 --- 5 files changed, 3 insertions(+), 166 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 27d37dbf03..fd36993bfb 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -490,16 +490,7 @@ bool Launcher::MainDialog::writeSettings() // Game settings QFile file(userPath + QString("openmw.cfg")); - QIODevice::OpenMode mode(0); - bool keepComments = mLauncherSettings.value(QString("Settings/keep-comments"), QString("true")) - == QLatin1String("true"); - - if (keepComments) - mode = QIODevice::ReadWrite | QIODevice::Text; - else - mode = QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate; - - if (!file.open(mode)) { + if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) { // File cannot be opened or created QMessageBox msgBox; msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); @@ -513,15 +504,9 @@ bool Launcher::MainDialog::writeSettings() } QTextStream stream(&file); + stream.setCodec(QTextCodec::codecForName("UTF-8")); - if (keepComments) - mGameSettings.writeFileWithComments(file); - else - { - stream.setCodec(QTextCodec::codecForName("UTF-8")); - mGameSettings.writeFile(stream); - } - + mGameSettings.writeFile(stream); file.close(); // Graphics settings diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index bc8ffe6180..843b513914 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -260,10 +260,6 @@ void Launcher::SettingsPage::saveSettings() } else { mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1252")); } - - QString keepComments(saveCommentsCheckBox->isChecked() ? "true" : "false"); - - mLauncherSettings.setValue(QLatin1String("Settings/keep-comments"), keepComments); } bool Launcher::SettingsPage::loadSettings() @@ -275,9 +271,5 @@ bool Launcher::SettingsPage::loadSettings() if (index != -1) languageComboBox->setCurrentIndex(index); - QString keepComments(mLauncherSettings.value(QLatin1String("Settings/keep-comments"))); - - saveCommentsCheckBox->setChecked(keepComments == "true"); - return true; } diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index c0a3b82d1c..0481235c78 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -1,7 +1,6 @@ #include "gamesettings.hpp" #include "launchersettings.hpp" -#include #include #include #include @@ -174,133 +173,6 @@ bool Config::GameSettings::writeFile(QTextStream &stream) return true; } -// Policy: -// -// - Always ignore a line beginning with '#' or empty lines -// -// - If a line in file exists with matching key and first part of value (before ',', -// '\n', etc) also matches, then replace the line with that of mUserSettings. -// - else remove line (maybe replace the line with '#' in front instead?) -// -// - If there is no corresponding line in file, add at the end -// -bool Config::GameSettings::writeFileWithComments(QFile &file) -{ - QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); - - // slurp - std::vector fileCopy; - QString line = stream.readLine(); - while (!line.isNull()) - { - fileCopy.push_back(line); - line = stream.readLine(); - } - stream.seek(0); - - // empty file, no comments to keep - if (fileCopy.empty()) - return writeFile(stream); - - // Temp copy of settings to save, but with the keys appended with the first part of the value - // - // ATTENTION! - // - // A hack to avoid looping through each line, makes use of the fact that fallbacks values - // are comma separated. - QMap userSettingsCopy; - QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$"); - QString settingLine; - QMap::const_iterator settingsIter = mUserSettings.begin(); - for (; settingsIter != mUserSettings.end(); ++settingsIter) - { - settingLine = settingsIter.key()+"="+settingsIter.value(); - if (settingRegex.indexIn(settingLine) != -1) - { - userSettingsCopy[settingRegex.cap(1)+"="+settingRegex.cap(2)] = - (settingRegex.captureCount() < 3) ? "" : settingRegex.cap(3); - } - } - - QString keyVal; - for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) - { - // skip empty or comment lines - if ((*iter).isEmpty() || (*iter).startsWith("#")) - continue; - - // look for a key in the line - if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2) - { - // no key or first part of value found in line, replace with a null string which - // will be remved later - *iter = QString(); - continue; - } - - // look for a matching key in user settings - keyVal = settingRegex.cap(1)+"="+settingRegex.cap(2); - QMap::iterator it = userSettingsCopy.find(keyVal); - if (it == userSettingsCopy.end()) - { - // no such key+valStart, replace with a null string which will be remved later - *iter = QString(); - } - else - { - *iter = QString(it.key()+it.value()); - userSettingsCopy.erase(it); - } - } - - // write the new config file - QString key; - QString value; - for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) - { - if ((*iter).isNull()) - continue; - - if ((*iter).isEmpty() || (*iter).startsWith("#")) - stream << *iter << "\n"; - - if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2) - continue; - - // Quote paths with spaces - key = settingRegex.cap(1); - value = settingRegex.cap(2)+settingRegex.cap(3); - if (key == QLatin1String("data") - || key == QLatin1String("data-local") - || key == QLatin1String("resources")) - { - if (value.contains(QChar(' '))) - { - value.remove(QChar('\"')); // Remove quotes - - stream << key << "=\"" << value << "\"\n"; - continue; - } - } - stream << key << "=" << value << "\n"; - } - - // new entries - if (!userSettingsCopy.empty()) - { - QMap::const_iterator it = userSettingsCopy.begin(); - for (; it != userSettingsCopy.end(); ++it) - { - stream << it.key() << it.value() << "\n"; - } - } - - file.resize(file.pos()); - - return true; -} - bool Config::GameSettings::hasMaster() { bool result = false; diff --git a/components/config/gamesettings.hpp b/components/config/gamesettings.hpp index 35614113f4..cc5033f351 100644 --- a/components/config/gamesettings.hpp +++ b/components/config/gamesettings.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -67,7 +66,6 @@ namespace Config bool readUserFile(QTextStream &stream); bool writeFile(QTextStream &stream); - bool writeFileWithComments(QFile &file); void setContentList(const QStringList& fileNames); QStringList getContentList() const; diff --git a/files/ui/settingspage.ui b/files/ui/settingspage.ui index f38ba764c3..7f5e4a7de8 100644 --- a/files/ui/settingspage.ui +++ b/files/ui/settingspage.ui @@ -40,16 +40,6 @@ - - - - Keep comments in openmw.cfg - - - false - - - From 28caeadef4b61b9fe6fbf2fdd53c69a38a07d282 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 14 Jun 2015 02:31:00 +0200 Subject: [PATCH 23/33] Improve error message for not found records --- apps/openmw/mwworld/store.hpp | 6 +++--- components/esm/loadacti.hpp | 2 ++ components/esm/loadalch.hpp | 3 +++ components/esm/loadappa.hpp | 2 ++ components/esm/loadarmo.hpp | 2 ++ components/esm/loadbody.hpp | 2 ++ components/esm/loadbook.hpp | 2 ++ components/esm/loadbsgn.hpp | 2 ++ components/esm/loadcell.hpp | 2 ++ components/esm/loadclas.hpp | 2 ++ components/esm/loadclot.hpp | 2 ++ components/esm/loadcont.hpp | 2 ++ components/esm/loadcrea.hpp | 2 ++ components/esm/loaddial.hpp | 2 ++ components/esm/loaddoor.hpp | 2 ++ components/esm/loadench.hpp | 2 ++ components/esm/loadfact.hpp | 2 ++ components/esm/loadglob.hpp | 2 ++ components/esm/loadgmst.hpp | 2 ++ components/esm/loadinfo.hpp | 2 ++ components/esm/loadingr.hpp | 2 ++ components/esm/loadland.hpp | 2 ++ components/esm/loadlevlist.hpp | 4 ++++ components/esm/loadligh.hpp | 2 ++ components/esm/loadlock.hpp | 2 ++ components/esm/loadltex.hpp | 2 ++ components/esm/loadmgef.hpp | 2 ++ components/esm/loadmisc.hpp | 2 ++ components/esm/loadnpc.hpp | 2 ++ components/esm/loadpgrd.hpp | 2 ++ components/esm/loadprob.hpp | 2 ++ components/esm/loadrace.hpp | 2 ++ components/esm/loadregn.hpp | 2 ++ components/esm/loadrepa.hpp | 2 ++ components/esm/loadscpt.hpp | 2 ++ components/esm/loadskil.hpp | 2 ++ components/esm/loadsndg.hpp | 2 ++ components/esm/loadsoun.hpp | 2 ++ components/esm/loadspel.hpp | 2 ++ components/esm/loadsscr.hpp | 2 ++ components/esm/loadstat.hpp | 2 ++ components/esm/loadweap.hpp | 2 ++ 42 files changed, 88 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index ba8be733a0..ab09782b14 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -188,7 +188,7 @@ namespace MWWorld const T *ptr = search(id); if (ptr == 0) { std::ostringstream msg; - msg << "Object '" << id << "' not found (const)"; + msg << T::getRecordType() << " '" << id << "' not found"; throw std::runtime_error(msg.str()); } return ptr; @@ -202,7 +202,7 @@ namespace MWWorld if(ptr == 0) { std::ostringstream msg; - msg << "Object starting with '"< CellRefTracker; struct Cell { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Cell"; } enum Flags { diff --git a/components/esm/loadclas.hpp b/components/esm/loadclas.hpp index 3e489bb58a..972b48e889 100644 --- a/components/esm/loadclas.hpp +++ b/components/esm/loadclas.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct Class { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Class"; } enum AutoCalc { diff --git a/components/esm/loadclot.hpp b/components/esm/loadclot.hpp index 50896622aa..6945f224a4 100644 --- a/components/esm/loadclot.hpp +++ b/components/esm/loadclot.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct Clothing { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Clothing"; } enum Type { diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index 76c522d748..ab587f9353 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -36,6 +36,8 @@ struct InventoryList struct Container { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Container"; } enum Flags { diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 1b02aa0abc..47e5954a5f 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -22,6 +22,8 @@ class ESMWriter; struct Creature { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Creature"; } // Default is 0x48? enum Flags diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index d29948c63b..58598d3536 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -21,6 +21,8 @@ class ESMWriter; struct Dialogue { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Dialogue"; } enum Type { diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index ee2b7f7ac5..3073f4e9de 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -12,6 +12,8 @@ class ESMWriter; struct Door { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Door"; } std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound; diff --git a/components/esm/loadench.hpp b/components/esm/loadench.hpp index 3b7746812a..cfcdd4edce 100644 --- a/components/esm/loadench.hpp +++ b/components/esm/loadench.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct Enchantment { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Enchantment"; } enum Type { diff --git a/components/esm/loadfact.hpp b/components/esm/loadfact.hpp index d31670fe28..8645e23fd8 100644 --- a/components/esm/loadfact.hpp +++ b/components/esm/loadfact.hpp @@ -30,6 +30,8 @@ struct RankData struct Faction { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Faction"; } std::string mId, mName; diff --git a/components/esm/loadglob.hpp b/components/esm/loadglob.hpp index 51b2e2dc98..cc5dbbdcfc 100644 --- a/components/esm/loadglob.hpp +++ b/components/esm/loadglob.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct Global { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Global"; } std::string mId; Variant mValue; diff --git a/components/esm/loadgmst.hpp b/components/esm/loadgmst.hpp index 398b8047fd..d9d9048b61 100644 --- a/components/esm/loadgmst.hpp +++ b/components/esm/loadgmst.hpp @@ -19,6 +19,8 @@ class ESMWriter; struct GameSetting { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "GameSetting"; } std::string mId; diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index 59b1af31a2..54003b0d96 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -21,6 +21,8 @@ class ESMWriter; struct DialInfo { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "DialInfo"; } enum Gender { diff --git a/components/esm/loadingr.hpp b/components/esm/loadingr.hpp index 85f2d5e7d2..5846a97809 100644 --- a/components/esm/loadingr.hpp +++ b/components/esm/loadingr.hpp @@ -16,6 +16,8 @@ class ESMWriter; struct Ingredient { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Ingredient"; } struct IRDTstruct { diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index e510616aff..7dc5e8adb3 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct Land { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Land"; } Land(); ~Land(); diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index bcea2b234c..dc6fcda5ec 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -46,6 +46,8 @@ struct LevelledListBase struct CreatureLevList: LevelledListBase { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "CreatureLevList"; } enum Flags { @@ -64,6 +66,8 @@ struct CreatureLevList: LevelledListBase struct ItemLevList: LevelledListBase { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "ItemLevList"; } enum Flags { diff --git a/components/esm/loadligh.hpp b/components/esm/loadligh.hpp index 2c83248f8a..ed8c36665c 100644 --- a/components/esm/loadligh.hpp +++ b/components/esm/loadligh.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Light { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Light"; } enum Flags { diff --git a/components/esm/loadlock.hpp b/components/esm/loadlock.hpp index c44e2b0063..0d678cd64c 100644 --- a/components/esm/loadlock.hpp +++ b/components/esm/loadlock.hpp @@ -12,6 +12,8 @@ class ESMWriter; struct Lockpick { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Lockpick"; } struct Data { diff --git a/components/esm/loadltex.hpp b/components/esm/loadltex.hpp index 8b45f82118..50a7881054 100644 --- a/components/esm/loadltex.hpp +++ b/components/esm/loadltex.hpp @@ -28,6 +28,8 @@ class ESMWriter; struct LandTexture { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "LandTexture"; } std::string mId, mTexture; int mIndex; diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index e66322832f..32b8a85a6d 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -13,6 +13,8 @@ class ESMWriter; struct MagicEffect { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "MagicEffect"; } std::string mId; diff --git a/components/esm/loadmisc.hpp b/components/esm/loadmisc.hpp index 576bd18c0f..6e0b4e01b8 100644 --- a/components/esm/loadmisc.hpp +++ b/components/esm/loadmisc.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Miscellaneous { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Miscellaneous"; } struct MCDTstruct { diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index b535b91b01..e8867110c4 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -23,6 +23,8 @@ class ESMWriter; struct NPC { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "NPC"; } // Services enum Services diff --git a/components/esm/loadpgrd.hpp b/components/esm/loadpgrd.hpp index 256b86cdad..f33ccbedf9 100644 --- a/components/esm/loadpgrd.hpp +++ b/components/esm/loadpgrd.hpp @@ -16,6 +16,8 @@ class ESMWriter; struct Pathgrid { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Pathgrid"; } struct DATAstruct { diff --git a/components/esm/loadprob.hpp b/components/esm/loadprob.hpp index b89b2ddeb6..c737757aa3 100644 --- a/components/esm/loadprob.hpp +++ b/components/esm/loadprob.hpp @@ -12,6 +12,8 @@ class ESMWriter; struct Probe { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Probe"; } struct Data { diff --git a/components/esm/loadrace.hpp b/components/esm/loadrace.hpp index 7d5736d9b7..553d2e68b1 100644 --- a/components/esm/loadrace.hpp +++ b/components/esm/loadrace.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct Race { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Race"; } struct SkillBonus { diff --git a/components/esm/loadregn.hpp b/components/esm/loadregn.hpp index c231b6aa0d..1e241fffbe 100644 --- a/components/esm/loadregn.hpp +++ b/components/esm/loadregn.hpp @@ -19,6 +19,8 @@ class ESMWriter; struct Region { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Region"; } #pragma pack(push) #pragma pack(1) diff --git a/components/esm/loadrepa.hpp b/components/esm/loadrepa.hpp index 5b404b0e4c..e765bc93a5 100644 --- a/components/esm/loadrepa.hpp +++ b/components/esm/loadrepa.hpp @@ -12,6 +12,8 @@ class ESMWriter; struct Repair { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Repair"; } struct Data { diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index deb71de6af..56390f3841 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -20,6 +20,8 @@ class Script { public: static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Script"; } struct SCHDstruct { diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index 1b9db5bcff..e001842970 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -20,6 +20,8 @@ class ESMWriter; struct Skill { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Skill"; } std::string mId; diff --git a/components/esm/loadsndg.hpp b/components/esm/loadsndg.hpp index f89a112082..056958f0a8 100644 --- a/components/esm/loadsndg.hpp +++ b/components/esm/loadsndg.hpp @@ -16,6 +16,8 @@ class ESMWriter; struct SoundGenerator { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "SoundGenerator"; } enum Type { diff --git a/components/esm/loadsoun.hpp b/components/esm/loadsoun.hpp index 04a0984fda..ff2202ca7d 100644 --- a/components/esm/loadsoun.hpp +++ b/components/esm/loadsoun.hpp @@ -17,6 +17,8 @@ struct SOUNstruct struct Sound { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Sound"; } SOUNstruct mData; std::string mId, mSound; diff --git a/components/esm/loadspel.hpp b/components/esm/loadspel.hpp index 4bd2210ec0..491da1d179 100644 --- a/components/esm/loadspel.hpp +++ b/components/esm/loadspel.hpp @@ -14,6 +14,8 @@ class ESMWriter; struct Spell { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Spell"; } enum SpellType { diff --git a/components/esm/loadsscr.hpp b/components/esm/loadsscr.hpp index 1420d16c47..dc7ad6a42a 100644 --- a/components/esm/loadsscr.hpp +++ b/components/esm/loadsscr.hpp @@ -20,6 +20,8 @@ class ESMWriter; struct StartScript { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "StartScript"; } std::string mData; std::string mId; diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index 45b05136ad..21a9e66e88 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -23,6 +23,8 @@ class ESMWriter; struct Static { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Static"; } std::string mId, mModel; diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index 14ddb47082..f66e9f3a68 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -16,6 +16,8 @@ class ESMWriter; struct Weapon { static unsigned int sRecordId; + /// Return a string descriptor for this record type. Currently used for debugging / error logs only. + static std::string getRecordType() { return "Weapon"; } enum Type { From 0efe8f5465d652d42a7191d8a7c5223dfa711466 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 14 Jun 2015 14:42:08 +1000 Subject: [PATCH 24/33] Fix broken launcher build for windows. --- apps/launcher/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 66cc157d3b..3c7b393149 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -100,6 +100,9 @@ target_link_libraries(openmw-launcher if (DESIRED_QT_VERSION MATCHES 4) target_link_libraries(openmw-launcher ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY}) + if(WIN32) + target_link_libraries(openmw-launcher ${QT_QTMAIN_LIBRARY}) + endif(WIN32) else() qt5_use_modules(openmw-launcher Widgets Core) endif() From c22c9c271d6cfab22ac2f6c35714eeb266b2fa0c Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 14 Jun 2015 14:51:01 +1000 Subject: [PATCH 25/33] Allow comments (lines starting with # character) and blank lines in openmw.cfg. Should resolve Feature #2535. - allows moving various config entries up or down - comment lines above config entries stay as a pair --- apps/launcher/maindialog.cpp | 7 +- components/config/gamesettings.cpp | 209 +++++++++++++++++++++++++++++ components/config/gamesettings.hpp | 4 + 3 files changed, 216 insertions(+), 4 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index fd36993bfb..2f7a9db332 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -490,7 +490,7 @@ bool Launcher::MainDialog::writeSettings() // Game settings QFile file(userPath + QString("openmw.cfg")); - if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) { + if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { // File cannot be opened or created QMessageBox msgBox; msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); @@ -503,10 +503,8 @@ bool Launcher::MainDialog::writeSettings() return false; } - QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); - mGameSettings.writeFile(stream); + mGameSettings.writeFileWithComments(file); file.close(); // Graphics settings @@ -525,6 +523,7 @@ bool Launcher::MainDialog::writeSettings() return false; } + QTextStream stream(&file); stream.setDevice(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index 0481235c78..4339369cf1 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -1,6 +1,7 @@ #include "gamesettings.hpp" #include "launchersettings.hpp" +#include #include #include #include @@ -173,6 +174,214 @@ bool Config::GameSettings::writeFile(QTextStream &stream) return true; } +bool Config::GameSettings::isOrderedLine(const QString& line) const +{ + return line.contains(QRegExp("^\\s*fallback-archive\\s*=")) + || line.contains(QRegExp("^\\s*fallback\\s*=")) + || line.contains(QRegExp("^\\s*data\\s*=")) + || line.contains(QRegExp("^\\s*data-local\\s*=")) + || line.contains(QRegExp("^\\s*resources\\s*=")) + || line.contains(QRegExp("^\\s*content\\s*=")); +} + +// Policy: +// +// - Always ignore a line beginning with '#' or empty lines; added above a config +// entry. +// +// - If a line in file exists with matching key and first part of value (before ',', +// '\n', etc) also matches, then replace the line with that of mUserSettings. +// - else remove line +// +// - If there is no corresponding line in file, add at the end +// +bool Config::GameSettings::writeFileWithComments(QFile &file) +{ + QTextStream stream(&file); + stream.setCodec(QTextCodec::codecForName("UTF-8")); + + // slurp + std::vector fileCopy; + QString line = stream.readLine(); + while (!line.isNull()) + { + fileCopy.push_back(line); + line = stream.readLine(); + } + stream.seek(0); + + // empty file, no comments to keep + if (fileCopy.empty()) + return writeFile(stream); + + // start + // | + // | +----------------------------------------------------------+ + // | | | + // v v | + // skip non-"ordered" lines (remove "ordered" lines) | + // | ^ | + // | | | + // | non-"ordered" line, write saved comments | + // | ^ | + // v | | + // blank or comment line, save in temp buffer <--------+ | + // | | | | + // v +------- comment line ------+ | + // "ordered" line | + // | | + // v | + // save in a separate map of comments keyed by "ordered" line | + // | | + // +----------------------------------------------------------+ + // + // + QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$"); + std::vector comments; + std::vector::iterator commentStart = fileCopy.end(); + std::map > commentsMap; + for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) + { + if (isOrderedLine(*iter)) + { + // save in a separate map of comments keyed by "ordered" line + if (!comments.empty()) + { + if (settingRegex.indexIn(*iter) != -1) + { + commentsMap[settingRegex.cap(1)+"="+settingRegex.cap(2)] = comments; + comments.clear(); + commentStart = fileCopy.end(); + } + // else do nothing, malformed line + } + + *iter = QString(); // "ordered" lines to be removed later + } + else if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#"))) + { + // comment line, save in temp buffer + if (comments.empty()) + commentStart = iter; + comments.push_back(*iter); + *iter = QString(); // assume to be deleted later + } + else + { + int index = settingRegex.indexIn(*iter); + + // blank or non-"ordered" line, write saved comments + if (!comments.empty() && index != -1 && settingRegex.captureCount() >= 2 && + mUserSettings.find(settingRegex.cap(1)) != mUserSettings.end()) + { + for (std::vector::const_iterator it = comments.begin(); it != comments.end(); ++it) + { + *commentStart = *it; + ++commentStart; + } + comments.clear(); + commentStart = fileCopy.end(); + } + + // keep blank lines and non-"ordered" lines other than comments + + // look for a key in the line + if (index == -1 || settingRegex.captureCount() < 2) + { + // no key or first part of value found in line, replace with a null string which + // will be remved later + *iter = QString(); + comments.clear(); + commentStart = fileCopy.end(); + continue; + } + + // look for a matching key in user settings + *iter = QString(); // assume no match + QString key = settingRegex.cap(1); + QString keyVal = settingRegex.cap(1)+"="+settingRegex.cap(2); + QMap::const_iterator i = mUserSettings.find(key); + while (i != mUserSettings.end() && i.key() == key) + { + QString settingLine = i.key() + "=" + i.value(); + if (settingRegex.indexIn(settingLine) != -1) + { + if ((settingRegex.cap(1)+"="+settingRegex.cap(2)) == keyVal) + { + *iter = settingLine; + break; + } + } + ++i; + } + } + } + + // comments at top of file + for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) + { + if ((*iter).isNull()) + continue; + + // Below is based on readFile() code, if that changes corresponding change may be + // required (for example duplicates may be inserted if the rules don't match) + if (/*(*iter).isEmpty() ||*/ (*iter).contains(QRegExp("^\\s*#"))) + { + stream << *iter << "\n"; + continue; + } + } + + // Iterate in reverse order to preserve insertion order + QString settingLine; + QMapIterator it(mUserSettings); + it.toBack(); + + while (it.hasPrevious()) + { + it.previous(); + + // Quote paths with spaces + if ((it.key() == QLatin1String("data") + || it.key() == QLatin1String("data-local") + || it.key() == QLatin1String("resources")) && it.value().contains(QChar(' '))) + { + QString stripped = it.value(); + stripped.remove(QChar('\"')); // Remove quotes + + settingLine = it.key() + "=\"" + stripped + "\""; + } + else + settingLine = it.key() + "=" + it.value(); + + if (settingRegex.indexIn(settingLine) != -1) + { + std::map >::const_iterator i = + commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2)); + + if (i != commentsMap.end()) + { + std::vector cLines = i->second; + for (std::vector::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci) + stream << *ci << "\n"; + } + } + + stream << settingLine << "\n"; + } + + // flush any end comments + if (!comments.empty()) + { + for (std::vector::const_iterator ci = comments.begin(); ci != comments.end(); ++ci) + stream << *ci << "\n"; + } + + file.resize(file.pos()); + + return true; +} + bool Config::GameSettings::hasMaster() { bool result = false; diff --git a/components/config/gamesettings.hpp b/components/config/gamesettings.hpp index cc5033f351..992a3e5655 100644 --- a/components/config/gamesettings.hpp +++ b/components/config/gamesettings.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,7 @@ namespace Config bool readUserFile(QTextStream &stream); bool writeFile(QTextStream &stream); + bool writeFileWithComments(QFile &file); void setContentList(const QStringList& fileNames); QStringList getContentList() const; @@ -81,6 +83,8 @@ namespace Config QString mDataLocal; static const char sContentKey[]; + + bool isOrderedLine(const QString& line) const; }; } #endif // GAMESETTINGS_HPP From 30de47f858dc98ba2ecd8c2657ad33584585e440 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 14 Jun 2015 17:12:14 +0200 Subject: [PATCH 26/33] Reduce the number of jobs in .travis.yml Hopefully this fixes the occasional out-of-memory problems. Note travis-CI virtual machines just have 2 virtual cores according to http://docs.travis-ci.com/user/ci-environment/, so 4 jobs wouldn't improve build times anyway. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1fc85dca38..6b03be1141 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,7 @@ before_script: - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi script: - cd ./build - - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j4; fi + - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j2; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi after_script: - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi From 36aa4aa9bdeb50a3512d5f2212bb5daaa94477b2 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 15 Jun 2015 09:53:26 +1000 Subject: [PATCH 27/33] If a removed 'content=' item has comments, keep them in config file for later use. --- components/config/gamesettings.cpp | 47 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index 4339369cf1..74d92d55da 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -195,6 +195,9 @@ bool Config::GameSettings::isOrderedLine(const QString& line) const // // - If there is no corresponding line in file, add at the end // +// - Removed content items are saved as comments if the item had any comments. +// Content items prepended with '##' are considered previously removed. +// bool Config::GameSettings::writeFileWithComments(QFile &file) { QTextStream stream(&file); @@ -227,7 +230,8 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) // v | | // blank or comment line, save in temp buffer <--------+ | // | | | | - // v +------- comment line ------+ | + // | +------- comment line ------+ | + // v (special processing '##') | // "ordered" line | // | | // v | @@ -263,7 +267,20 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) // comment line, save in temp buffer if (comments.empty()) commentStart = iter; - comments.push_back(*iter); + + // special removed content processing + if ((*iter).contains(QRegExp("^##content\\s*="))) + { + if (!comments.empty()) + { + commentsMap[*iter] = comments; + comments.clear(); + commentStart = fileCopy.end(); + } + } + else + comments.push_back(*iter); + *iter = QString(); // assume to be deleted later } else @@ -359,17 +376,43 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) std::map >::const_iterator i = commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2)); + // check if previous removed content item with comments + if (i == commentsMap.end()) + i = commentsMap.find("##"+settingRegex.cap(1)+"="+settingRegex.cap(2)); + if (i != commentsMap.end()) { std::vector cLines = i->second; for (std::vector::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci) stream << *ci << "\n"; + + commentsMap.erase(i); } } stream << settingLine << "\n"; } + // flush any removed settings + if (!commentsMap.empty()) + { + std::map >::const_iterator i = commentsMap.begin(); + for (; i != commentsMap.end(); ++i) + { + if (i->first.contains(QRegExp("^\\s*content\\s*="))) + { + std::vector cLines = i->second; + for (std::vector::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci) + stream << *ci << "\n"; + + // mark the content line entry for future preocessing + stream << "##" << i->first << "\n"; + + //commentsMap.erase(i); + } + } + } + // flush any end comments if (!comments.empty()) { From 6b28955f316d8e3261d68b99c48bd6ce8a8e3f48 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 15 Jun 2015 10:26:16 +1000 Subject: [PATCH 28/33] Fix attempt to erase using a const_iterator. --- components/config/gamesettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index 74d92d55da..ca6bfd80da 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -373,7 +373,7 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) if (settingRegex.indexIn(settingLine) != -1) { - std::map >::const_iterator i = + std::map >::iterator i = commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2)); // check if previous removed content item with comments From 609e146a22f2e8b3c70cb15693b4976aba7141d5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 15 Jun 2015 14:16:14 +0200 Subject: [PATCH 29/33] Build fixes for windows --- apps/launcher/CMakeLists.txt | 3 +++ apps/opencs/CMakeLists.txt | 8 ++++++++ apps/wizard/CMakeLists.txt | 7 +++++++ extern/ogre-ffmpeg-videoplayer/CMakeLists.txt | 3 +-- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 3c7b393149..caf96054e7 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -105,6 +105,9 @@ if (DESIRED_QT_VERSION MATCHES 4) endif(WIN32) else() qt5_use_modules(openmw-launcher Widgets Core) + if (WIN32) + target_link_libraries(Qt5::WinMain) + endif() endif() if (BUILD_WITH_CODE_COVERAGE) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 6a9318319c..bf39b36c19 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -216,8 +216,16 @@ if (DESIRED_QT_VERSION MATCHES 4) ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTNETWORK_LIBRARY}) + + if (WIN32) + target_link_libraries(openmw-cs ${QT_QTMAIN_LIBRARY}) + endif() + else() qt5_use_modules(openmw-cs Widgets Core Network) + if (WIN32) + target_link_libraries(Qt5::WinMain) + endif() endif() if (WIN32) diff --git a/apps/wizard/CMakeLists.txt b/apps/wizard/CMakeLists.txt index 5cd874863b..89438640c1 100644 --- a/apps/wizard/CMakeLists.txt +++ b/apps/wizard/CMakeLists.txt @@ -123,8 +123,15 @@ if (DESIRED_QT_VERSION MATCHES 4) target_link_libraries(openmw-wizard ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY}) + + if (WIN32) + target_link_libraries(openmw-wizard ${QT_QTMAIN_LIBRARY}) + endif() else() qt5_use_modules(openmw-wizard Widgets Core) + if (WIN32) + target_link_libraries(Qt5::WinMain) + endif() endif() if (OPENMW_USE_UNSHIELD) diff --git a/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt b/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt index cda3d39e83..edd5575f46 100644 --- a/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt +++ b/extern/ogre-ffmpeg-videoplayer/CMakeLists.txt @@ -11,8 +11,7 @@ set(OGRE_FFMPEG_VIDEOPLAYER_SOURCE_FILES audiofactory.hpp ) -# Find Boost - +include_directories(${FFMPEG_INCLUDE_DIRS}) add_library(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} STATIC ${OGRE_FFMPEG_VIDEOPLAYER_SOURCE_FILES}) target_link_libraries(${OGRE_FFMPEG_VIDEOPLAYER_LIBRARY} ${FFMPEG_LIBRARIES} ${Boost_THREAD_LIBRARY}) From 98a77f68a335a7fc878e3c7dba4a509bad8e4e68 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 15 Jun 2015 20:04:36 +0200 Subject: [PATCH 30/33] Fix AiWander::fastForward using incorrect pathgrid coordinates when actor recently moved to a new cell --- apps/openmw/mwmechanics/aiwander.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 0766369747..e6fd684696 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -669,6 +669,9 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->moveObject(actor, static_cast(dest.mX), static_cast(dest.mY), static_cast(dest.mZ)); actor.getClass().adjustPosition(actor, false); + + // may have changed cell + mStoredAvailableNodes = false; } void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell) From 5347d407d805e234a4022896cf4d94e213aa2f8f Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 15 Jun 2015 20:05:12 +0200 Subject: [PATCH 31/33] Disallow AiWander fast-forward for water creatures Pathgrid nodes are usually above the water level, so appearing at a random node would have the creature break out of the water level it's supposed to be constrained to. --- apps/openmw/mwmechanics/aiwander.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index e6fd684696..1f4133c0aa 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -651,6 +651,9 @@ namespace MWMechanics if (mAllowedNodes.empty()) return; + if (actor.getClass().isPureWaterCreature(actor)) + return; + state.moveIn(new AiWanderStorage()); int index = OEngine::Misc::Rng::rollDice(mAllowedNodes.size()); From cccf6c6bdd272c28f848935023b9e9ac60401191 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 16 Jun 2015 12:48:45 +1000 Subject: [PATCH 32/33] Rebuild the list of available content files when opening the open/new dialogues. Should resolve Bug #2644. --- apps/opencs/editor.cpp | 14 ++++++++++++-- apps/opencs/editor.hpp | 2 +- apps/opencs/view/doc/filedialog.cpp | 8 ++++++-- apps/opencs/view/doc/filedialog.hpp | 1 + components/contentselector/model/contentmodel.cpp | 7 +++++++ components/contentselector/model/contentmodel.hpp | 1 + .../contentselector/view/contentselector.cpp | 5 +++++ .../contentselector/view/contentselector.hpp | 1 + components/files/configurationmanager.cpp | 6 +++++- components/files/configurationmanager.hpp | 2 +- 10 files changed, 40 insertions(+), 7 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index efd7cf4ec7..80d8b8a932 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -95,7 +95,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) } } -std::pair > CS::Editor::readConfig() +std::pair > CS::Editor::readConfig(bool quiet) { boost::program_options::variables_map variables; boost::program_options::options_description desc("Syntax: openmw-cs \nAllowed options"); @@ -115,7 +115,7 @@ std::pair > CS::Editor::readConfi boost::program_options::notify(variables); - mCfgMgr.readConfiguration(variables, desc); + mCfgMgr.readConfiguration(variables, desc, /*quiet*/true); mDocumentManager.setEncoding ( ToUTF8::calculateEncoding (variables["encoding"].as())); @@ -195,6 +195,11 @@ void CS::Editor::cancelCreateGame() void CS::Editor::createAddon() { mStartup.hide(); + + mFileDialog.clearFiles(); + std::pair > config = readConfig(/*quiet*/true); + setupDataFiles (config.first); + mFileDialog.showDialog (CSVDoc::ContentAction_New); } @@ -215,6 +220,11 @@ void CS::Editor::cancelFileDialog() void CS::Editor::loadDocument() { mStartup.hide(); + + mFileDialog.clearFiles(); + std::pair > config = readConfig(/*quiet*/true); + setupDataFiles (config.first); + mFileDialog.showDialog (CSVDoc::ContentAction_Edit); } diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index eb85743a39..cbf306df83 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -62,7 +62,7 @@ namespace CS void setupDataFiles (const Files::PathContainer& dataDirs); - std::pair > readConfig(); + std::pair > readConfig(bool quiet=false); ///< \return data paths // not implemented diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index eeec81109f..b6f4aaec31 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -33,6 +33,11 @@ void CSVDoc::FileDialog::addFiles(const QString &path) mSelector->addFiles(path); } +void CSVDoc::FileDialog::clearFiles() +{ + mSelector->clearFiles(); +} + QStringList CSVDoc::FileDialog::selectedFilePaths() { QStringList filePaths; @@ -105,7 +110,6 @@ void CSVDoc::FileDialog::buildNewFileView() connect (mFileWidget, SIGNAL (nameChanged(const QString &, bool)), this, SLOT (slotUpdateAcceptButton(const QString &, bool))); - } ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); @@ -139,7 +143,7 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(int) { QString name = ""; - if (mAction == ContentAction_New) + if (mFileWidget && mAction == ContentAction_New) name = mFileWidget->getName(); slotUpdateAcceptButton (name, true); diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 3c23a5cb5a..6488365652 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -45,6 +45,7 @@ namespace CSVDoc void showDialog (ContentAction action); void addFiles (const QString &path); + void clearFiles (); QString filename() const; QStringList selectedFilePaths(); diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index d000290e6f..769afee37b 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -473,6 +473,13 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) sortFiles(); } +void ContentSelectorModel::ContentModel::clearFiles() +{ + beginRemoveRows(QModelIndex(), 0, mFiles.count()-1); + mFiles.clear(); + endRemoveRows(); +} + QStringList ContentSelectorModel::ContentModel::gameFiles() const { QStringList gameFiles; diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index ab965ad69c..bc785a2767 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -44,6 +44,7 @@ namespace ContentSelectorModel bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); void addFiles(const QString &path); + void clearFiles(); QModelIndex indexFromItem(const EsmFile *item) const; const EsmFile *item(const QString &name) const; diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 2fae8e74b9..78aa20cd26 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -150,6 +150,11 @@ void ContentSelectorView::ContentSelector::addFiles(const QString &path) mContentModel->uncheckAll(); } +void ContentSelectorView::ContentSelector::clearFiles() +{ + mContentModel->clearFiles(); +} + QString ContentSelectorView::ContentSelector::currentFile() const { QModelIndex currentIdx = ui.addonView->currentIndex(); diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index e455807c96..4e9fcfb3c8 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -29,6 +29,7 @@ namespace ContentSelectorView QString currentFile() const; void addFiles(const QString &path); + void clearFiles(); void setProfileContent (const QStringList &fileList); void clearCheckStates(); diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index e321b58143..dc6f02b608 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -52,8 +52,11 @@ void ConfigurationManager::setupTokensMapping() } void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables, - boost::program_options::options_description& description) + boost::program_options::options_description& description, bool quiet) { + bool silent = mSilent; + mSilent = quiet; + loadConfig(mFixedPath.getUserConfigPath(), variables, description); boost::program_options::notify(variables); @@ -62,6 +65,7 @@ void ConfigurationManager::readConfiguration(boost::program_options::variables_m loadConfig(mFixedPath.getGlobalConfigPath(), variables, description); boost::program_options::notify(variables); + mSilent = silent; } void ConfigurationManager::processPaths(Files::PathContainer& dataDirs, bool create) diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 24b08c5236..5f0062c2e9 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -29,7 +29,7 @@ struct ConfigurationManager virtual ~ConfigurationManager(); void readConfiguration(boost::program_options::variables_map& variables, - boost::program_options::options_description& description); + boost::program_options::options_description& description, bool quiet=false); void processPaths(Files::PathContainer& dataDirs, bool create = false); ///< \param create Try creating the directory, if it does not exist. From 6a47ea9a676949c93dd1339f51a7b709b52ce81d Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 16 Jun 2015 13:09:44 +1000 Subject: [PATCH 33/33] fix typo --- apps/opencs/editor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 80d8b8a932..bd4f57304f 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -115,7 +115,7 @@ std::pair > CS::Editor::readConfi boost::program_options::notify(variables); - mCfgMgr.readConfiguration(variables, desc, /*quiet*/true); + mCfgMgr.readConfiguration(variables, desc, quiet); mDocumentManager.setEncoding ( ToUTF8::calculateEncoding (variables["encoding"].as()));