From 30f114873d419cefef6aec22d9ef2999e376decc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 3 Aug 2014 10:12:03 +0200 Subject: [PATCH 01/55] added debug profile record --- components/CMakeLists.txt | 2 +- components/esm/debugprofile.cpp | 50 +++++++++++++++++++++++++++++++++ components/esm/debugprofile.hpp | 33 ++++++++++++++++++++++ components/esm/defs.hpp | 3 +- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 components/esm/debugprofile.cpp create mode 100644 components/esm/debugprofile.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index efe432227..c8758ca9e 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -41,7 +41,7 @@ add_component_dir (esm loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate - npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate + npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile aisequence ) diff --git a/components/esm/debugprofile.cpp b/components/esm/debugprofile.cpp new file mode 100644 index 000000000..eb6dc2fdc --- /dev/null +++ b/components/esm/debugprofile.cpp @@ -0,0 +1,50 @@ + +#include "debugprofile.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" +#include "defs.hpp" + +unsigned int ESM::DebugProfile::sRecordId = REC_DBGP; + +void ESM::DebugProfile::load (ESMReader& esm) +{ + mDescription = esm.getHNString ("DESC"); + mScript = esm.getHNString ("SCRP"); + + int default_ = 0; + esm.getHNOT (default_, "DEFA"); + + mDefault = default_!=0; + + int bypass = 0; + esm.getHNOT (bypass, "BYNG"); + + mBypassNewGame = bypass!=0; +} + +void ESM::DebugProfile::save (ESMWriter& esm) const +{ + esm.writeHNCString ("DESC", mDescription); + esm.writeHNCString ("SCRP", mScript); + + if (mDefault) + { + int default_ = 1; + esm.writeHNT ("DEFA", default_); + } + + if (mBypassNewGame) + { + int bypass = 1; + esm.writeHNT ("BYNG", bypass); + } +} + +void ESM::DebugProfile::blank() +{ + mDescription.clear(); + mScript.clear(); + mDefault = false; + mBypassNewGame = false; +} diff --git a/components/esm/debugprofile.hpp b/components/esm/debugprofile.hpp new file mode 100644 index 000000000..1e8574299 --- /dev/null +++ b/components/esm/debugprofile.hpp @@ -0,0 +1,33 @@ +#ifndef COMPONENTS_ESM_DEBUGPROFILE_H +#define COMPONENTS_ESM_DEBUGPROFILE_H + +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + struct DebugProfile + { + static unsigned int sRecordId; + + std::string mId; + + std::string mDescription; + + std::string mScript; + + bool mDefault; + + bool mBypassNewGame; + + void load (ESMReader& esm); + void save (ESMWriter& esm) const; + + /// Set record to default state (does not touch the ID). + void blank(); + }; +} + +#endif diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index f967af274..14f2d3ebd 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -114,7 +114,8 @@ enum RecNameInts REC_DCOU = FourCC<'D','C','O','U'>::value, // format 1 - REC_FILT = 0x544C4946 + REC_FILT = 0x544C4946, + REC_DBGP = FourCC<'D','B','G','P'>::value ///< only used in project files }; } From 4d49924025c3621c6ca906a541297844ee63cddc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 4 Aug 2014 13:36:01 +0200 Subject: [PATCH 02/55] added debug profile record table --- apps/opencs/model/world/data.cpp | 53 ++++++++++++++++++++----- apps/opencs/model/world/data.hpp | 6 +++ apps/opencs/model/world/universalid.cpp | 2 + apps/opencs/model/world/universalid.hpp | 6 ++- apps/opencs/view/doc/view.cpp | 15 +++++++ apps/opencs/view/doc/view.hpp | 4 ++ apps/opencs/view/world/subviews.cpp | 4 ++ 7 files changed, 79 insertions(+), 11 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index b9f6c6cf9..a1a498868 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -258,6 +258,11 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mFilters.addColumn (new DescriptionColumn); mFilters.addColumn (new ScopeColumn); + mDebugProfiles.addColumn (new StringIdColumn); + mDebugProfiles.addColumn (new RecordStateColumn); + mDebugProfiles.addColumn (new FixedRecordTypeColumn (UniversalId::Type_DebugProfile)); + mDebugProfiles.addColumn (new DescriptionColumn); + addModel (new IdTable (&mGlobals), UniversalId::Type_Global); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst); addModel (new IdTable (&mSkills), UniversalId::Type_Skill); @@ -280,6 +285,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc UniversalId::Type_Referenceable); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); addModel (new IdTable (&mFilters), UniversalId::Type_Filter); + addModel (new IdTable (&mDebugProfiles), UniversalId::Type_DebugProfile); addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Mesh)), UniversalId::Type_Mesh); addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Icon)), @@ -513,6 +519,16 @@ CSMWorld::IdCollection& CSMWorld::Data::getBodyParts() return mBodyParts; } +const CSMWorld::IdCollection& CSMWorld::Data::getDebugProfiles() const +{ + return mDebugProfiles; +} + +CSMWorld::IdCollection& CSMWorld::Data::getDebugProfiles() +{ + return mDebugProfiles; +} + const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const { return mResourcesManager.get (UniversalId::getParentType (id.getType())); @@ -582,6 +598,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) ESM::NAME n = mReader->getRecName(); mReader->getRecHeader(); + bool unhandledRecord = false; + switch (n.val) { case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break; @@ -692,23 +710,40 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) case ESM::REC_FILT: - if (mProject) + if (!mProject) { - mFilters.load (*mReader, mBase); - mFilters.setData (mFilters.getSize()-1, - mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope), - static_cast (CSMFilter::Filter::Scope_Project)); + unhandledRecord = true; break; } - // fall through (filter record in a content file is an error with format 0) + mFilters.load (*mReader, mBase); + mFilters.setData (mFilters.getSize()-1, + mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope), + static_cast (CSMFilter::Filter::Scope_Project)); + break; + + case ESM::REC_DBGP: + + if (!mProject) + { + unhandledRecord = true; + break; + } + + mDebugProfiles.load (*mReader, mBase); + break; default: - messages.push_back (std::make_pair (UniversalId::Type_None, - "Unsupported record type: " + n.toString())); + unhandledRecord = true; + } - mReader->skipRecord(); + if (unhandledRecord) + { + messages.push_back (std::make_pair (UniversalId::Type_None, + "Unsupported record type: " + n.toString())); + + mReader->skipRecord(); } return false; diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index cbf13d8b1..ab22096b2 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -70,6 +71,7 @@ namespace CSMWorld IdCollection mJournals; IdCollection mEnchantments; IdCollection mBodyParts; + IdCollection mDebugProfiles; InfoCollection mTopicInfos; InfoCollection mJournalInfos; IdCollection mCells; @@ -190,6 +192,10 @@ namespace CSMWorld IdCollection& getBodyParts(); + const IdCollection& getDebugProfiles() const; + + IdCollection& getDebugProfiles(); + /// Throws an exception, if \a id does not match a resources list. const Resources& getResources (const UniversalId& id) const; diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 7ee767354..7d2cce0de 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -50,6 +50,7 @@ namespace { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_SoundsRes, "Sound Files", 0 }, { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Textures, "Textures", 0 }, { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Videos, "Videos", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_DebugProfiles, "Debug Profiles", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; @@ -109,6 +110,7 @@ namespace { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Video, "Video", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_DebugProfile, "Debug Profile", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 3d3f215d6..8f3437220 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -119,10 +119,12 @@ namespace CSMWorld Type_Textures, Type_Texture, Type_Videos, - Type_Video + Type_Video, + Type_DebugProfiles, + Type_DebugProfile }; - enum { NumberOfTypes = Type_BodyPart+1 }; + enum { NumberOfTypes = Type_DebugProfile+1 }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 4868f20ff..acd415034 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -232,6 +232,15 @@ void CSVDoc::View::setupAssetsMenu() assets->addAction (videos); } +void CSVDoc::View::setupDebugMenu() +{ + QMenu *debug = menuBar()->addMenu (tr ("Debug")); + + QAction *profiles = new QAction (tr ("Debug Profiles"), this); + connect (profiles, SIGNAL (triggered()), this, SLOT (addDebugProfilesSubView())); + debug->addAction (profiles); +} + void CSVDoc::View::setupUi() { setupFileMenu(); @@ -241,6 +250,7 @@ void CSVDoc::View::setupUi() setupMechanicsMenu(); setupCharacterMenu(); setupAssetsMenu(); + setupDebugMenu(); } void CSVDoc::View::updateTitle() @@ -543,6 +553,11 @@ void CSVDoc::View::addVideosSubView() addSubView (CSMWorld::UniversalId::Type_Videos); } +void CSVDoc::View::addDebugProfilesSubView() +{ + addSubView (CSMWorld::UniversalId::Type_DebugProfiles); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 19171ff42..a76429315 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -67,6 +67,8 @@ namespace CSVDoc void setupAssetsMenu(); + void setupDebugMenu(); + void setupUi(); void updateTitle(); @@ -194,6 +196,8 @@ namespace CSVDoc void addVideosSubView(); + void addDebugProfilesSubView(); + void toggleShowStatusBar (bool show); void loadErrorLog(); diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 200a26a85..9deaee329 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -95,6 +95,10 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator >); + manager.add (CSMWorld::UniversalId::Type_DebugProfiles, + new CSVDoc::SubViewFactoryWithCreator); + manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); // Dialogue subviews From 828536e99918ee05f53dad61b901d24203d9fb83 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 6 Aug 2014 09:53:10 +0200 Subject: [PATCH 03/55] generalised the concept of record scope --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/scope.cpp | 25 +++++++++++++++++++++++++ apps/opencs/model/world/scope.hpp | 23 +++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/world/scope.cpp create mode 100644 apps/opencs/model/world/scope.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 62747c9b0..3928b06d8 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -24,7 +24,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection - refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager + refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/scope.cpp b/apps/opencs/model/world/scope.cpp new file mode 100644 index 000000000..e3ebf5ebd --- /dev/null +++ b/apps/opencs/model/world/scope.cpp @@ -0,0 +1,25 @@ + +#include "scope.hpp" + +#include + +#include + +CSMWorld::Scope CSMWorld::getScopeFromId (const std::string& id) +{ + // get root namespace + std::string namespace_; + + std::string::size_type i = id.find ("::"); + + if (i!=std::string::npos) + namespace_ = Misc::StringUtils::lowerCase (id.substr (0, i)); + + if (namespace_=="project") + return Scope_Project; + + if (namespace_=="session") + return Scope_Session; + + return Scope_Content; +} \ No newline at end of file diff --git a/apps/opencs/model/world/scope.hpp b/apps/opencs/model/world/scope.hpp new file mode 100644 index 000000000..3983d91f5 --- /dev/null +++ b/apps/opencs/model/world/scope.hpp @@ -0,0 +1,23 @@ +#ifndef CSM_WOLRD_SCOPE_H +#define CSM_WOLRD_SCOPE_H + +#include + +namespace CSMWorld +{ + enum Scope + { + // record stored in content file + Scope_Content = 1, + + // record stored in project file + Scope_Project = 2, + + // record that exists only for the duration of one editing session + Scope_Session = 4 + }; + + Scope getScopeFromId (const std::string& id); +} + +#endif From 0be1e3d12f34f25d301ed923b2280bdb2b1f73bb Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 6 Aug 2014 10:03:04 +0200 Subject: [PATCH 04/55] removed WriteFilterStage class (functionality integrated into WriteCollectionStage) --- apps/opencs/model/doc/saving.cpp | 3 ++- apps/opencs/model/doc/savingstages.cpp | 17 ----------------- apps/opencs/model/doc/savingstages.hpp | 26 +++++++++----------------- 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 95631eea9..506bdc0ae 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -17,7 +17,8 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteHeaderStage (mDocument, mState, true)); - appendStage (new WriteFilterStage (mDocument, mState, CSMFilter::Filter::Scope_Project)); + appendStage (new WriteCollectionStage > ( + mDocument.getData().getFilters(), mState, CSMWorld::Scope_Project)); appendStage (new CloseSaveStage (mState)); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index d36c2fb86..17c2b4dca 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -201,23 +201,6 @@ void CSMDoc::WriteRefIdCollectionStage::perform (int stage, Messages& messages) } -CSMDoc::WriteFilterStage::WriteFilterStage (Document& document, SavingState& state, - CSMFilter::Filter::Scope scope) -: WriteCollectionStage > (document.getData().getFilters(), - state), - mDocument (document), mScope (scope) -{} - -void CSMDoc::WriteFilterStage::perform (int stage, Messages& messages) -{ - const CSMWorld::Record& record = - mDocument.getData().getFilters().getRecord (stage); - - if (record.get().mScope==mScope) - WriteCollectionStage >::perform (stage, messages); -} - - CSMDoc::CollectionReferencesStage::CollectionReferencesStage (Document& document, SavingState& state) : mDocument (document), mState (state) diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index dcb1a8650..700983dce 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -5,6 +5,7 @@ #include "../world/record.hpp" #include "../world/idcollection.hpp" +#include "../world/scope.hpp" #include "../filter/filter.hpp" @@ -67,10 +68,12 @@ namespace CSMDoc { const CollectionT& mCollection; SavingState& mState; + CSMWorld::Scope mScope; public: - WriteCollectionStage (const CollectionT& collection, SavingState& state); + WriteCollectionStage (const CollectionT& collection, SavingState& state, + CSMWorld::Scope scope = CSMWorld::Scope_Content); virtual int setup(); ///< \return number of steps @@ -81,8 +84,8 @@ namespace CSMDoc template WriteCollectionStage::WriteCollectionStage (const CollectionT& collection, - SavingState& state) - : mCollection (collection), mState (state) + SavingState& state, CSMWorld::Scope scope) + : mCollection (collection), mState (state), mScope (scope) {} template @@ -94,6 +97,9 @@ namespace CSMDoc template void WriteCollectionStage::perform (int stage, Messages& messages) { + if (CSMWorld::getScopeFromId (mCollection.getRecord (stage).get().mId)!=mScope) + return; + CSMWorld::RecordBase::State state = mCollection.getRecord (stage).mState; if (state==CSMWorld::RecordBase::State_Modified || @@ -152,20 +158,6 @@ namespace CSMDoc }; - class WriteFilterStage : public WriteCollectionStage > - { - Document& mDocument; - CSMFilter::Filter::Scope mScope; - - public: - - WriteFilterStage (Document& document, SavingState& state, CSMFilter::Filter::Scope scope); - - virtual void perform (int stage, Messages& messages); - ///< Messages resulting from this stage will be appended to \a messages. - - }; - class CollectionReferencesStage : public Stage { Document& mDocument; From 35803bc9b66ecf3e615e346cc607bac5d72474e5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 7 Aug 2014 09:32:49 +0200 Subject: [PATCH 05/55] added scope configuration to creators --- apps/opencs/view/filter/filtercreator.cpp | 4 ++-- apps/opencs/view/filter/filtercreator.hpp | 2 +- apps/opencs/view/world/creator.cpp | 11 ++++++++++- apps/opencs/view/world/creator.hpp | 20 ++++++++++++++++---- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/apps/opencs/view/filter/filtercreator.cpp b/apps/opencs/view/filter/filtercreator.cpp index 640c9fe78..5bca0434b 100644 --- a/apps/opencs/view/filter/filtercreator.cpp +++ b/apps/opencs/view/filter/filtercreator.cpp @@ -56,7 +56,7 @@ CSVFilter::FilterCreator::FilterCreator (CSMWorld::Data& data, QUndoStack& undoS /// \todo re-enable for OpenMW 1.1 // mScope->addItem ("Content"); - connect (mScope, SIGNAL (currentIndexChanged (int)), this, SLOT (setScope (int))); + connect (mScope, SIGNAL (currentIndexChanged (int)), this, SLOT (setScope2 (int))); insertAtBeginning (mScope, false); @@ -71,7 +71,7 @@ void CSVFilter::FilterCreator::reset() GenericCreator::reset(); } -void CSVFilter::FilterCreator::setScope (int index) +void CSVFilter::FilterCreator::setScope2 (int index) { update(); } diff --git a/apps/opencs/view/filter/filtercreator.hpp b/apps/opencs/view/filter/filtercreator.hpp index 437d01c8d..144b5adf4 100644 --- a/apps/opencs/view/filter/filtercreator.hpp +++ b/apps/opencs/view/filter/filtercreator.hpp @@ -36,7 +36,7 @@ namespace CSVFilter private slots: - void setScope (int index); + void setScope2 (int index); }; } diff --git a/apps/opencs/view/world/creator.cpp b/apps/opencs/view/world/creator.cpp index d753a2b47..a24c58e54 100644 --- a/apps/opencs/view/world/creator.cpp +++ b/apps/opencs/view/world/creator.cpp @@ -1,7 +1,16 @@ #include "creator.hpp" -CSVWorld::Creator:: ~Creator() {} +#include + +CSVWorld::Creator::~Creator() {} + +void CSVWorld::Creator::setScope (unsigned int scope) +{ + if (scope!=CSMWorld::Scope_Content) + throw std::logic_error ("Invalid scope in creator"); +} + CSVWorld::CreatorFactoryBase::~CreatorFactoryBase() {} diff --git a/apps/opencs/view/world/creator.hpp b/apps/opencs/view/world/creator.hpp index 88da70330..8e50e8715 100644 --- a/apps/opencs/view/world/creator.hpp +++ b/apps/opencs/view/world/creator.hpp @@ -1,9 +1,14 @@ #ifndef CSV_WORLD_CREATOR_H #define CSV_WORLD_CREATOR_H +#include + #include + #include "../../model/world/universalid.hpp" +#include "../../model/world/scope.hpp" + class QUndoStack; namespace CSMWorld @@ -32,6 +37,9 @@ namespace CSVWorld virtual void toggleWidgets(bool active = true) = 0; + /// Default implementation: Throw an exception if scope!=Scope_Content. + virtual void setScope (unsigned int scope); + signals: void done(); @@ -68,7 +76,7 @@ namespace CSVWorld /// \note The function always returns 0. }; - template + template class CreatorFactory : public CreatorFactoryBase { public: @@ -81,11 +89,15 @@ namespace CSVWorld /// records should be provided. }; - template - Creator *CreatorFactory::makeCreator (CSMWorld::Data& data, QUndoStack& undoStack, + template + Creator *CreatorFactory::makeCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) const { - return new CreatorT (data, undoStack, id); + std::auto_ptr creator (new CreatorT (data, undoStack, id)); + + creator->setScope (scope); + + return creator.release(); } } From a54efbcfa00990eccdcc78e31d7b26f1fede15cd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 10 Aug 2014 18:46:32 +0200 Subject: [PATCH 06/55] made FilterCreator redundant by generalising GenericCreator --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/filter/filtercreator.cpp | 77 -------------- apps/opencs/view/filter/filtercreator.hpp | 43 -------- apps/opencs/view/world/genericcreator.cpp | 121 ++++++++++++++++++---- apps/opencs/view/world/genericcreator.hpp | 14 ++- apps/opencs/view/world/subviews.cpp | 2 +- 6 files changed, 117 insertions(+), 142 deletions(-) delete mode 100644 apps/opencs/view/filter/filtercreator.cpp delete mode 100644 apps/opencs/view/filter/filtercreator.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 3928b06d8..a5fe77dd9 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -131,7 +131,7 @@ opencs_hdrs_noqt (model/filter ) opencs_units (view/filter - filtercreator filterbox recordfilterbox editwidget + filterbox recordfilterbox editwidget ) set (OPENCS_US diff --git a/apps/opencs/view/filter/filtercreator.cpp b/apps/opencs/view/filter/filtercreator.cpp deleted file mode 100644 index 5bca0434b..000000000 --- a/apps/opencs/view/filter/filtercreator.cpp +++ /dev/null @@ -1,77 +0,0 @@ - -#include "filtercreator.hpp" - -#include -#include - -#include "../../model/filter/filter.hpp" - -#include "../../model/world/data.hpp" -#include "../../model/world/commands.hpp" -#include "../../model/world/columns.hpp" -#include "../../model/world/idtable.hpp" - -std::string CSVFilter::FilterCreator::getNamespace() const -{ - switch (mScope->currentIndex()) - { - case CSMFilter::Filter::Scope_Project: return "project::"; - case CSMFilter::Filter::Scope_Session: return "session::"; - } - - return ""; -} - -void CSVFilter::FilterCreator::update() -{ - mNamespace->setText (QString::fromUtf8 (getNamespace().c_str())); - GenericCreator::update(); -} - -std::string CSVFilter::FilterCreator::getId() const -{ - return getNamespace() + GenericCreator::getId(); -} - -void CSVFilter::FilterCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const -{ - int index = - dynamic_cast (*getData().getTableModel (getCollectionId())). - findColumnIndex (CSMWorld::Columns::ColumnId_Scope); - - command.addValue (index, mScope->currentIndex()); -} - -CSVFilter::FilterCreator::FilterCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id) -: GenericCreator (data, undoStack, id) -{ - mNamespace = new QLabel ("::", this); - insertAtBeginning (mNamespace, false); - - mScope = new QComboBox (this); - - mScope->addItem ("Project"); - mScope->addItem ("Session"); - /// \todo re-enable for OpenMW 1.1 - // mScope->addItem ("Content"); - - connect (mScope, SIGNAL (currentIndexChanged (int)), this, SLOT (setScope2 (int))); - - insertAtBeginning (mScope, false); - - QLabel *label = new QLabel ("Scope", this); - insertAtBeginning (label, false); - - mScope->setCurrentIndex (1); -} - -void CSVFilter::FilterCreator::reset() -{ - GenericCreator::reset(); -} - -void CSVFilter::FilterCreator::setScope2 (int index) -{ - update(); -} diff --git a/apps/opencs/view/filter/filtercreator.hpp b/apps/opencs/view/filter/filtercreator.hpp deleted file mode 100644 index 144b5adf4..000000000 --- a/apps/opencs/view/filter/filtercreator.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef CSV_FILTER_FILTERCREATOR_H -#define CSV_FILTER_FILTERCREATOR_H - -class QComboBox; -class QLabel; - -#include "../world/genericcreator.hpp" - -namespace CSVFilter -{ - class FilterCreator : public CSVWorld::GenericCreator - { - Q_OBJECT - - QComboBox *mScope; - QLabel *mNamespace; - - private: - - std::string getNamespace() const; - - protected: - - void update(); - - virtual std::string getId() const; - - virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; - - public: - - FilterCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id); - - virtual void reset(); - - private slots: - - void setScope2 (int index); - }; -} - -#endif diff --git a/apps/opencs/view/world/genericcreator.cpp b/apps/opencs/view/world/genericcreator.cpp index 31c216e2c..d23fc2803 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "../../model/world/commands.hpp" #include "../../model/world/data.hpp" @@ -22,6 +24,9 @@ void CSVWorld::GenericCreator::update() mId->setToolTip (QString::fromUtf8 (mErrors.c_str())); mCreate->setEnabled (mErrors.empty() && !mLocked); + + if (mNamespace) + mNamespace->setText (QString::fromUtf8 (getNamespace().c_str())); } void CSVWorld::GenericCreator::setManualEditing (bool enabled) @@ -41,7 +46,7 @@ void CSVWorld::GenericCreator::insertBeforeButtons (QWidget *widget, bool stretc std::string CSVWorld::GenericCreator::getId() const { - return mId->text().toUtf8().constData(); + return getNamespace() + mId->text().toUtf8().constData(); } void CSVWorld::GenericCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const {} @@ -56,16 +61,37 @@ const CSMWorld::UniversalId& CSVWorld::GenericCreator::getCollectionId() const return mListId; } +std::string CSVWorld::GenericCreator::getNamespace() const +{ + CSMWorld::Scope scope = CSMWorld::Scope_Content; + + if (mScope) + { + scope = static_cast (mScope->itemData (mScope->currentIndex()).toInt()); + } + else + { + if (mScopes & CSMWorld::Scope_Project) + scope = CSMWorld::Scope_Project; + else if (mScopes & CSMWorld::Scope_Session) + scope = CSMWorld::Scope_Session; + } + + switch (scope) + { + case CSMWorld::Scope_Content: return ""; + case CSMWorld::Scope_Project: return "project::"; + case CSMWorld::Scope_Session: return "session::"; + } + + return ""; +} + CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, bool relaxedIdRules): - - mData (data), - mUndoStack (undoStack), - mListId (id), - mLocked (false), - mCloneMode(false), - mClonedType(CSMWorld::UniversalId::Type_None) - + const CSMWorld::UniversalId& id, bool relaxedIdRules) +: mData (data), mUndoStack (undoStack), mListId (id), mLocked (false), mCloneMode (false), + mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (0), + mScopeLabel (0), mNamespace (0) { mLayout = new QHBoxLayout; mLayout->setContentsMargins (0, 0, 0, 0); @@ -128,29 +154,28 @@ void CSVWorld::GenericCreator::create() { if (!mLocked) { + std::string id = getId(); + if (mCloneMode) { - std::string id = getId(); std::auto_ptr command (new CSMWorld::CloneCommand ( dynamic_cast (*mData.getTableModel(mListId)), mClonedId, id, mClonedType)); mUndoStack.push(command.release()); - emit done(); - emit requestFocus(id); - } else { - std::string id = getId(); - + } + else + { std::auto_ptr command (new CSMWorld::CreateCommand ( dynamic_cast (*mData.getTableModel (mListId)), id)); configureCreateCommand (*command); mUndoStack.push (command.release()); - - emit done(); - emit requestFocus (id); } + + emit done(); + emit requestFocus(id); } } @@ -165,3 +190,61 @@ void CSVWorld::GenericCreator::cloneMode(const std::string& originId, void CSVWorld::GenericCreator::toggleWidgets(bool active) { } + +void CSVWorld::GenericCreator::setScope (unsigned int scope) +{ + mScopes = scope; + int count = (mScopes & CSMWorld::Scope_Content) + (mScopes & CSMWorld::Scope_Project) + + (mScopes & CSMWorld::Scope_Session); + + // namespace widget + if (count>1 || (count>0 && !(mScopes & CSMWorld::Scope_Content))) + { + if (!mNamespace) + { + mNamespace = new QLabel ("::", this); + insertAtBeginning (mNamespace, false); + } + } + else + { + delete mNamespace; + mNamespace = 0; + } + + // scope selector widget + if (count>1) + { + mScope = new QComboBox (this); + insertAtBeginning (mScope, false); + + if (mScopes & CSMWorld::Scope_Content) + mScope->addItem ("Content", static_cast (CSMWorld::Scope_Content)); + + if (mScopes & CSMWorld::Scope_Project) + mScope->addItem ("Project", static_cast (CSMWorld::Scope_Project)); + + if (mScopes & CSMWorld::Scope_Session) + mScope->addItem ("Session", static_cast (CSMWorld::Scope_Session)); + + connect (mScope, SIGNAL (currentIndexChanged (int)), this, SLOT (scopeChanged (int))); + + mScopeLabel = new QLabel ("Scope", this); + insertAtBeginning (mScopeLabel, false); + + mScope->setCurrentIndex (0); + } + else + { + delete mScope; + mScope = 0; + + delete mScopeLabel; + mScopeLabel = 0; + } +} + +void CSVWorld::GenericCreator::scopeChanged (int index) +{ + update(); +} \ No newline at end of file diff --git a/apps/opencs/view/world/genericcreator.hpp b/apps/opencs/view/world/genericcreator.hpp index 714853f98..fdd743489 100644 --- a/apps/opencs/view/world/genericcreator.hpp +++ b/apps/opencs/view/world/genericcreator.hpp @@ -5,6 +5,8 @@ class QString; class QPushButton; class QLineEdit; class QHBoxLayout; +class QComboBox; +class QLabel; #include "creator.hpp" @@ -31,6 +33,10 @@ namespace CSVWorld bool mLocked; std::string mClonedId; CSMWorld::UniversalId::Type mClonedType; + unsigned int mScopes; + QComboBox *mScope; + QLabel *mScopeLabel; + QLabel *mNamespace; protected: bool mCloneMode; @@ -54,6 +60,8 @@ namespace CSVWorld const CSMWorld::UniversalId& getCollectionId() const; + std::string getNamespace() const; + public: GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, @@ -65,18 +73,22 @@ namespace CSVWorld virtual void toggleWidgets (bool active = true); - virtual void cloneMode(const std::string& originId, + virtual void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type); virtual std::string getErrors() const; ///< Return formatted error descriptions for the current state of the creator. if an empty /// string is returned, there is no error. + virtual void setScope (unsigned int scope); + private slots: void textChanged (const QString& text); void create(); + + void scopeChanged (int index); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 9deaee329..1d90a26bb 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -93,7 +93,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Filters, new CSVDoc::SubViewFactoryWithCreator >); + CreatorFactory >); manager.add (CSMWorld::UniversalId::Type_DebugProfiles, new CSVDoc::SubViewFactoryWithCreator Date: Sun, 10 Aug 2014 20:49:14 +0200 Subject: [PATCH 07/55] removed mScope field from Filter record (redundant now) --- apps/opencs/model/filter/filter.hpp | 8 ------- apps/opencs/model/world/columnimp.hpp | 30 --------------------------- apps/opencs/model/world/columns.cpp | 1 - apps/opencs/model/world/columns.hpp | 1 - apps/opencs/model/world/data.cpp | 4 ---- apps/opencs/view/world/subviews.cpp | 2 -- 6 files changed, 46 deletions(-) diff --git a/apps/opencs/model/filter/filter.hpp b/apps/opencs/model/filter/filter.hpp index 62170ca80..0c71ad333 100644 --- a/apps/opencs/model/filter/filter.hpp +++ b/apps/opencs/model/filter/filter.hpp @@ -11,14 +11,6 @@ namespace CSMFilter /// \brief Wrapper for Filter record struct Filter : public ESM::Filter { - enum Scope - { - Scope_Project = 0, // per project - Scope_Session = 1, // exists only for one editing session; not saved - Scope_Content = 2 // embedded in the edited content file - }; - - Scope mScope; }; } diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 3fad05f65..d9cd48940 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1224,36 +1224,6 @@ namespace CSMWorld } }; - template - struct ScopeColumn : public Column - { - ScopeColumn() - : Column (Columns::ColumnId_Scope, ColumnBase::Display_Integer, 0) - {} - - virtual QVariant get (const Record& record) const - { - return static_cast (record.get().mScope); - } - - virtual void set (Record& record, const QVariant& data) - { - ESXRecordT record2 = record.get(); - record2.mScope = static_cast (data.toInt()); - record.setModified (record2); - } - - virtual bool isEditable() const - { - return true; - } - - virtual bool isUserEditable() const - { - return false; - } - }; - template struct PosColumn : public Column diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 05df0b735..982b6e5ef 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -172,7 +172,6 @@ namespace CSMWorld { ColumnId_Rank, "Rank" }, { ColumnId_Gender, "Gender" }, { ColumnId_PcRank, "PC Rank" }, - { ColumnId_Scope, "Scope" }, { ColumnId_ReferenceableId, "Referenceable ID" }, { ColumnId_CombatState, "Combat" }, { ColumnId_MagicState, "Magic" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 326a02596..bcebef97d 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -165,7 +165,6 @@ namespace CSMWorld ColumnId_Rank = 152, ColumnId_Gender = 153, ColumnId_PcRank = 154, - ColumnId_Scope = 155, ColumnId_ReferenceableId = 156, ColumnId_CombatState = 157, ColumnId_MagicState = 158, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index a1a498868..f17ac6e4c 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -256,7 +256,6 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mFilters.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Filter)); mFilters.addColumn (new FilterColumn); mFilters.addColumn (new DescriptionColumn); - mFilters.addColumn (new ScopeColumn); mDebugProfiles.addColumn (new StringIdColumn); mDebugProfiles.addColumn (new RecordStateColumn); @@ -717,9 +716,6 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) } mFilters.load (*mReader, mBase); - mFilters.setData (mFilters.getSize()-1, - mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope), - static_cast (CSMFilter::Filter::Scope_Project)); break; case ESM::REC_DBGP: diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 1d90a26bb..2e962f29e 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -3,8 +3,6 @@ #include "../doc/subviewfactoryimp.hpp" -#include "../filter/filtercreator.hpp" - #include "tablesubview.hpp" #include "dialoguesubview.hpp" #include "scriptsubview.hpp" From fa9c6b19c2513b4fef821514b193b86c08cbe090 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 10 Aug 2014 21:03:45 +0200 Subject: [PATCH 08/55] removed OpenCS-specific custom Filter record struct (default ESM struct will do from now on) --- apps/opencs/CMakeLists.txt | 4 ---- apps/opencs/model/doc/saving.cpp | 2 +- apps/opencs/model/doc/savingstages.hpp | 2 -- apps/opencs/model/filter/filter.hpp | 17 ----------------- apps/opencs/model/filter/parser.cpp | 2 +- apps/opencs/model/world/data.cpp | 14 +++++++------- apps/opencs/model/world/data.hpp | 9 ++++----- 7 files changed, 13 insertions(+), 37 deletions(-) delete mode 100644 apps/opencs/model/filter/filter.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index a5fe77dd9..2574eb111 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -126,10 +126,6 @@ opencs_units_noqt (model/filter node unarynode narynode leafnode booleannode parser andnode ornode notnode textnode valuenode ) -opencs_hdrs_noqt (model/filter - filter - ) - opencs_units (view/filter filterbox recordfilterbox editwidget ) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 506bdc0ae..676946930 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -17,7 +17,7 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteHeaderStage (mDocument, mState, true)); - appendStage (new WriteCollectionStage > ( + appendStage (new WriteCollectionStage > ( mDocument.getData().getFilters(), mState, CSMWorld::Scope_Project)); appendStage (new CloseSaveStage (mState)); diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 700983dce..d766b774e 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -7,8 +7,6 @@ #include "../world/idcollection.hpp" #include "../world/scope.hpp" -#include "../filter/filter.hpp" - #include "savingstate.hpp" namespace ESM diff --git a/apps/opencs/model/filter/filter.hpp b/apps/opencs/model/filter/filter.hpp deleted file mode 100644 index 0c71ad333..000000000 --- a/apps/opencs/model/filter/filter.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CSM_FILTER_FILTER_H -#define CSM_FILTER_FILTER_H - -#include -#include - -#include - -namespace CSMFilter -{ - /// \brief Wrapper for Filter record - struct Filter : public ESM::Filter - { - }; -} - -#endif \ No newline at end of file diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index bec445cbc..51338dfc9 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -596,7 +596,7 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined) return false; } - const CSMWorld::Record& record = mData.getFilters().getRecord (index); + const CSMWorld::Record& record = mData.getFilters().getRecord (index); if (record.isDeleted()) { diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index f17ac6e4c..2f837d63b 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -251,11 +251,11 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRefs.addColumn (new KeyColumn); mRefs.addColumn (new TrapColumn); - mFilters.addColumn (new StringIdColumn); - mFilters.addColumn (new RecordStateColumn); - mFilters.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Filter)); - mFilters.addColumn (new FilterColumn); - mFilters.addColumn (new DescriptionColumn); + mFilters.addColumn (new StringIdColumn); + mFilters.addColumn (new RecordStateColumn); + mFilters.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Filter)); + mFilters.addColumn (new FilterColumn); + mFilters.addColumn (new DescriptionColumn); mDebugProfiles.addColumn (new StringIdColumn); mDebugProfiles.addColumn (new RecordStateColumn); @@ -488,12 +488,12 @@ CSMWorld::RefCollection& CSMWorld::Data::getReferences() return mRefs; } -const CSMWorld::IdCollection& CSMWorld::Data::getFilters() const +const CSMWorld::IdCollection& CSMWorld::Data::getFilters() const { return mFilters; } -CSMWorld::IdCollection& CSMWorld::Data::getFilters() +CSMWorld::IdCollection& CSMWorld::Data::getFilters() { return mFilters; } diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index ab22096b2..d0a07c677 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -24,11 +24,10 @@ #include #include #include +#include #include -#include "../filter/filter.hpp" - #include "../doc/stage.hpp" #include "idcollection.hpp" @@ -77,7 +76,7 @@ namespace CSMWorld IdCollection mCells; RefIdCollection mReferenceables; RefCollection mRefs; - IdCollection mFilters; + IdCollection mFilters; const ResourcesManager& mResourcesManager; std::vector mModels; std::map mModelIndex; @@ -180,9 +179,9 @@ namespace CSMWorld RefCollection& getReferences(); - const IdCollection& getFilters() const; + const IdCollection& getFilters() const; - IdCollection& getFilters(); + IdCollection& getFilters(); const IdCollection& getEnchantments() const; From c66dfe67b1a88c2f806dccf8531d786cbb7142b3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 14 Aug 2014 14:21:34 +0200 Subject: [PATCH 09/55] integrated namespace widget into input field (GenericCreator) --- apps/opencs/view/world/genericcreator.cpp | 51 +++++++++------- apps/opencs/view/world/genericcreator.hpp | 8 ++- apps/opencs/view/world/idvalidator.cpp | 71 ++++++++++++++++++++++- apps/opencs/view/world/idvalidator.hpp | 5 ++ 4 files changed, 111 insertions(+), 24 deletions(-) diff --git a/apps/opencs/view/world/genericcreator.cpp b/apps/opencs/view/world/genericcreator.cpp index d23fc2803..bbdf2f67b 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include "../../model/world/commands.hpp" #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" @@ -24,9 +26,6 @@ void CSVWorld::GenericCreator::update() mId->setToolTip (QString::fromUtf8 (mErrors.c_str())); mCreate->setEnabled (mErrors.empty() && !mLocked); - - if (mNamespace) - mNamespace->setText (QString::fromUtf8 (getNamespace().c_str())); } void CSVWorld::GenericCreator::setManualEditing (bool enabled) @@ -87,17 +86,40 @@ std::string CSVWorld::GenericCreator::getNamespace() const return ""; } +void CSVWorld::GenericCreator::updateNamespace() +{ + std::string namespace_ = getNamespace(); + + mValidator->setNamespace (namespace_); + + int index = mId->text().indexOf ("::"); + + if (index==-1) + { + // no namespace in old text + mId->setText (QString::fromUtf8 (namespace_.c_str()) + mId->text()); + } + else + { + std::string oldNamespace = + Misc::StringUtils::lowerCase (mId->text().left (index).toUtf8().constData()); + + if (oldNamespace=="project" || oldNamespace=="session") + mId->setText (QString::fromUtf8 (namespace_.c_str()) + mId->text().mid (index+2)); + } +} + CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, bool relaxedIdRules) : mData (data), mUndoStack (undoStack), mListId (id), mLocked (false), mCloneMode (false), mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (0), - mScopeLabel (0), mNamespace (0) + mScopeLabel (0) { mLayout = new QHBoxLayout; mLayout->setContentsMargins (0, 0, 0, 0); mId = new QLineEdit; - mId->setValidator (new IdValidator (relaxedIdRules, this)); + mId->setValidator (mValidator = new IdValidator (relaxedIdRules, this)); mLayout->addWidget (mId, 1); mCreate = new QPushButton ("Create"); @@ -125,6 +147,7 @@ void CSVWorld::GenericCreator::reset() mCloneMode = false; mId->setText (""); update(); + updateNamespace(); } std::string CSVWorld::GenericCreator::getErrors() const @@ -197,21 +220,6 @@ void CSVWorld::GenericCreator::setScope (unsigned int scope) int count = (mScopes & CSMWorld::Scope_Content) + (mScopes & CSMWorld::Scope_Project) + (mScopes & CSMWorld::Scope_Session); - // namespace widget - if (count>1 || (count>0 && !(mScopes & CSMWorld::Scope_Content))) - { - if (!mNamespace) - { - mNamespace = new QLabel ("::", this); - insertAtBeginning (mNamespace, false); - } - } - else - { - delete mNamespace; - mNamespace = 0; - } - // scope selector widget if (count>1) { @@ -242,9 +250,12 @@ void CSVWorld::GenericCreator::setScope (unsigned int scope) delete mScopeLabel; mScopeLabel = 0; } + + updateNamespace(); } void CSVWorld::GenericCreator::scopeChanged (int index) { update(); + updateNamespace(); } \ No newline at end of file diff --git a/apps/opencs/view/world/genericcreator.hpp b/apps/opencs/view/world/genericcreator.hpp index fdd743489..ea099248e 100644 --- a/apps/opencs/view/world/genericcreator.hpp +++ b/apps/opencs/view/world/genericcreator.hpp @@ -19,6 +19,8 @@ namespace CSMWorld namespace CSVWorld { + class IdValidator; + class GenericCreator : public Creator { Q_OBJECT @@ -36,7 +38,7 @@ namespace CSVWorld unsigned int mScopes; QComboBox *mScope; QLabel *mScopeLabel; - QLabel *mNamespace; + IdValidator *mValidator; protected: bool mCloneMode; @@ -62,6 +64,10 @@ namespace CSVWorld std::string getNamespace() const; + private: + + void updateNamespace(); + public: GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, diff --git a/apps/opencs/view/world/idvalidator.cpp b/apps/opencs/view/world/idvalidator.cpp index 7c210daae..5f4cd2194 100644 --- a/apps/opencs/view/world/idvalidator.cpp +++ b/apps/opencs/view/world/idvalidator.cpp @@ -1,6 +1,8 @@ #include "idvalidator.hpp" +#include + bool CSVWorld::IdValidator::isValid (const QChar& c, bool first) const { if (c.isLetter() || c=='_') @@ -26,11 +28,74 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con else { bool first = true; + bool scope = false; + bool prevScope = false; - for (QString::const_iterator iter (input.begin()); iter!=input.end(); ++iter, first = false) - if (!isValid (*iter, first)) - return QValidator::Invalid; + QString::const_iterator iter = input.begin(); + + if (!mNamespace.empty()) + { + std::string namespace_ = input.left (mNamespace.size()).toUtf8().constData(); + + if (Misc::StringUtils::lowerCase (namespace_)!=mNamespace) + return QValidator::Invalid; // incorrect namespace + + iter += namespace_.size(); + first = false; + prevScope = true; + } + else + { + int index = input.indexOf (":"); + + if (index!=-1) + { + QString namespace_ = input.left (index); + + if (namespace_=="project" || namespace_=="session") + return QValidator::Invalid; // reserved namespace + } + } + + for (; iter!=input.end(); ++iter, first = false) + { + if (*iter==':') + { + if (first) + return QValidator::Invalid; // scope operator at the beginning + + if (scope) + { + scope = false; + prevScope = true; + } + else + { + if (prevScope) + return QValidator::Invalid; // sequence of two scope operators + + scope = true; + } + } + else if (scope) + return QValidator::Invalid; // incomplete scope operator + else + { + prevScope = false; + + if (!isValid (*iter, first)) + return QValidator::Invalid; + } + } + + if (prevScope) + return QValidator::Intermediate; // ending with scope operator } return QValidator::Acceptable; +} + +void CSVWorld::IdValidator::setNamespace (const std::string& namespace_) +{ + mNamespace = Misc::StringUtils::lowerCase (namespace_); } \ No newline at end of file diff --git a/apps/opencs/view/world/idvalidator.hpp b/apps/opencs/view/world/idvalidator.hpp index 8ca162440..4b3e6cf6a 100644 --- a/apps/opencs/view/world/idvalidator.hpp +++ b/apps/opencs/view/world/idvalidator.hpp @@ -1,6 +1,8 @@ #ifndef CSV_WORLD_IDVALIDATOR_H #define CSV_WORLD_IDVALIDATOR_H +#include + #include namespace CSVWorld @@ -8,6 +10,7 @@ namespace CSVWorld class IdValidator : public QValidator { bool mRelaxed; + std::string mNamespace; private: @@ -20,6 +23,8 @@ namespace CSVWorld virtual State validate (QString& input, int& pos) const; + void setNamespace (const std::string& namespace_); + }; } From 1bf177fe7215af6cf3bf4e3fc05570c6cb2da188 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 12:01:37 +0200 Subject: [PATCH 10/55] fixed double namespace in GenericCreator --- apps/opencs/view/world/genericcreator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/genericcreator.cpp b/apps/opencs/view/world/genericcreator.cpp index bbdf2f67b..7ad5305e3 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -45,7 +45,7 @@ void CSVWorld::GenericCreator::insertBeforeButtons (QWidget *widget, bool stretc std::string CSVWorld::GenericCreator::getId() const { - return getNamespace() + mId->text().toUtf8().constData(); + return mId->text().toUtf8().constData(); } void CSVWorld::GenericCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const {} From 605f71ecc0a8173dcb1d5df34b6f1554956e9760 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 12:03:07 +0200 Subject: [PATCH 11/55] added creator to debug profile table --- apps/opencs/view/world/subviews.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 2e962f29e..6276c3da1 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -95,7 +95,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_DebugProfiles, new CSVDoc::SubViewFactoryWithCreator); + CreatorFactory >); manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); From 775e24d2c090bf14710ac0adc408c1a4bb3da79d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 12:08:29 +0200 Subject: [PATCH 12/55] save debug profiles in project files --- apps/opencs/model/doc/saving.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 676946930..d587ef3af 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -20,6 +20,9 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteCollectionStage > ( mDocument.getData().getFilters(), mState, CSMWorld::Scope_Project)); + appendStage (new WriteCollectionStage > ( + mDocument.getData().getDebugProfiles(), mState, CSMWorld::Scope_Project)); + appendStage (new CloseSaveStage (mState)); // save content file From 3486da0fb03a6489e3950681321806cc7a4b5817 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 12:27:08 +0200 Subject: [PATCH 13/55] consolidated the debug profile flags into a single and added a global flag --- components/esm/debugprofile.cpp | 27 +++------------------------ components/esm/debugprofile.hpp | 11 ++++++++--- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/components/esm/debugprofile.cpp b/components/esm/debugprofile.cpp index eb6dc2fdc..bd0fdd80b 100644 --- a/components/esm/debugprofile.cpp +++ b/components/esm/debugprofile.cpp @@ -11,40 +11,19 @@ void ESM::DebugProfile::load (ESMReader& esm) { mDescription = esm.getHNString ("DESC"); mScript = esm.getHNString ("SCRP"); - - int default_ = 0; - esm.getHNOT (default_, "DEFA"); - - mDefault = default_!=0; - - int bypass = 0; - esm.getHNOT (bypass, "BYNG"); - - mBypassNewGame = bypass!=0; + esm.getHNT (mFlags, "FLAG"); } void ESM::DebugProfile::save (ESMWriter& esm) const { esm.writeHNCString ("DESC", mDescription); esm.writeHNCString ("SCRP", mScript); - - if (mDefault) - { - int default_ = 1; - esm.writeHNT ("DEFA", default_); - } - - if (mBypassNewGame) - { - int bypass = 1; - esm.writeHNT ("BYNG", bypass); - } + esm.writeHNT ("FLAG", mFlags); } void ESM::DebugProfile::blank() { mDescription.clear(); mScript.clear(); - mDefault = false; - mBypassNewGame = false; + mFlags = 0; } diff --git a/components/esm/debugprofile.hpp b/components/esm/debugprofile.hpp index 1e8574299..dc3658f7d 100644 --- a/components/esm/debugprofile.hpp +++ b/components/esm/debugprofile.hpp @@ -12,15 +12,20 @@ namespace ESM { static unsigned int sRecordId; + enum Flags + { + Flag_Default = 1, // add to newly opened scene subviews + Flag_BypassNewGame = 2, // bypass regular game startup + Flag_Global = 4 // make available from main menu (i.e. not location specific) + }; + std::string mId; std::string mDescription; std::string mScript; - bool mDefault; - - bool mBypassNewGame; + unsigned int mFlags; void load (ESMReader& esm); void save (ESMWriter& esm) const; From 2b9395333ade426cef18a1f70fc5be6ab8c76418 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 13:11:55 +0200 Subject: [PATCH 14/55] fixed error detection and improved error reporting in IdValidator --- apps/opencs/view/world/genericcreator.cpp | 12 +++--------- apps/opencs/view/world/idvalidator.cpp | 24 ++++++++++++++++++++++- apps/opencs/view/world/idvalidator.hpp | 7 +++++++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/apps/opencs/view/world/genericcreator.cpp b/apps/opencs/view/world/genericcreator.cpp index 7ad5305e3..e905cfef6 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -154,16 +154,10 @@ std::string CSVWorld::GenericCreator::getErrors() const { std::string errors; - std::string id = getId(); - - if (id.empty()) - { - errors = "Missing ID"; - } - else if (mData.hasId (id)) - { + if (!mId->hasAcceptableInput()) + errors = mValidator->getError(); + else if (mData.hasId (getId())) errors = "ID is already in use"; - } return errors; } diff --git a/apps/opencs/view/world/idvalidator.cpp b/apps/opencs/view/world/idvalidator.cpp index 5f4cd2194..7caa20f9b 100644 --- a/apps/opencs/view/world/idvalidator.cpp +++ b/apps/opencs/view/world/idvalidator.cpp @@ -20,6 +20,8 @@ CSVWorld::IdValidator::IdValidator (bool relaxed, QObject *parent) QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) const { + mError.clear(); + if (mRelaxed) { if (input.indexOf ('"')!=-1 || input.indexOf ("::")!=-1 || input.indexOf ("#")!=-1) @@ -27,6 +29,12 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con } else { + if (input.isEmpty()) + { + mError = "Missing ID"; + return QValidator::Intermediate; + } + bool first = true; bool scope = false; bool prevScope = false; @@ -88,8 +96,17 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con } } + if (scope) + { + mError = "ID ending with incomplete scope operator"; + return QValidator::Intermediate; + } + if (prevScope) - return QValidator::Intermediate; // ending with scope operator + { + mError = "ID ending with scope operator"; + return QValidator::Intermediate; + } } return QValidator::Acceptable; @@ -98,4 +115,9 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con void CSVWorld::IdValidator::setNamespace (const std::string& namespace_) { mNamespace = Misc::StringUtils::lowerCase (namespace_); +} + +std::string CSVWorld::IdValidator::getError() const +{ + return mError; } \ No newline at end of file diff --git a/apps/opencs/view/world/idvalidator.hpp b/apps/opencs/view/world/idvalidator.hpp index 4b3e6cf6a..a9df9580a 100644 --- a/apps/opencs/view/world/idvalidator.hpp +++ b/apps/opencs/view/world/idvalidator.hpp @@ -11,6 +11,7 @@ namespace CSVWorld { bool mRelaxed; std::string mNamespace; + mutable std::string mError; private: @@ -25,6 +26,12 @@ namespace CSVWorld void setNamespace (const std::string& namespace_); + /// Return a description of the error that resulted in the last call of validate + /// returning QValidator::Intermediate. If the last call to validate returned + /// a different value (or if there was no such call yet), an empty string is + /// returned. + std::string getError() const; + }; } From fd3842d7260c1eaac906ae0b29e771728c033f39 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 13:22:20 +0200 Subject: [PATCH 15/55] added flag columns to debug profile table --- apps/opencs/model/world/columnimp.hpp | 41 +++++++++++++++++++++++++++ apps/opencs/model/world/columns.cpp | 3 ++ apps/opencs/model/world/columns.hpp | 3 ++ apps/opencs/model/world/data.cpp | 6 ++++ 4 files changed, 53 insertions(+) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index d9cd48940..e66320189 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -500,6 +500,47 @@ namespace CSMWorld } }; + template + struct FlagColumn2 : public Column + { + int mMask; + bool mInverted; + + FlagColumn2 (int columnId, int mask, bool inverted = false) + : Column (columnId, ColumnBase::Display_Boolean), mMask (mask), + mInverted (inverted) + {} + + virtual QVariant get (const Record& record) const + { + bool flag = (record.get().mFlags & mMask)!=0; + + if (mInverted) + flag = !flag; + + return flag; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + int flags = record2.mFlags & ~mMask; + + if ((data.toInt()!=0)!=mInverted) + flags |= mMask; + + record2.mFlags = flags; + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + template struct WeightHeightColumn : public Column { diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 982b6e5ef..a5a81343d 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -180,6 +180,9 @@ namespace CSMWorld { ColumnId_Vampire, "Vampire" }, { ColumnId_BodyPartType, "Bodypart Type" }, { ColumnId_MeshType, "Mesh Type" }, + { ColumnId_DefaultProfile, "Default Profile" }, + { ColumnId_BypassNewGame, "Bypass New Game" }, + { ColumnId_GlobalProfile, "Global Profile" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index bcebef97d..ae71a0bde 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -173,6 +173,9 @@ namespace CSMWorld ColumnId_Vampire = 161, ColumnId_BodyPartType = 162, ColumnId_MeshType = 163, + ColumnId_DefaultProfile = 164, + ColumnId_BypassNewGame = 165, + ColumnId_GlobalProfile = 166, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 2f837d63b..1172eef30 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -260,6 +260,12 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mDebugProfiles.addColumn (new StringIdColumn); mDebugProfiles.addColumn (new RecordStateColumn); mDebugProfiles.addColumn (new FixedRecordTypeColumn (UniversalId::Type_DebugProfile)); + mDebugProfiles.addColumn (new FlagColumn2 ( + Columns::ColumnId_DefaultProfile, ESM::DebugProfile::Flag_Default)); + mDebugProfiles.addColumn (new FlagColumn2 ( + Columns::ColumnId_BypassNewGame, ESM::DebugProfile::Flag_BypassNewGame)); + mDebugProfiles.addColumn (new FlagColumn2 ( + Columns::ColumnId_GlobalProfile, ESM::DebugProfile::Flag_Global)); mDebugProfiles.addColumn (new DescriptionColumn); addModel (new IdTable (&mGlobals), UniversalId::Type_Global); From 6f97fa472e146f8422fe083c26925baecc51b78c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 13:35:53 +0200 Subject: [PATCH 16/55] added dialgoue subview for debug profiles --- apps/opencs/view/world/subviews.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 6276c3da1..393585e9a 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -149,6 +149,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Journal, new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add (CSMWorld::UniversalId::Type_DebugProfile, + new CSVDoc::SubViewFactoryWithCreator > (false)); + //preview manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory); } \ No newline at end of file From 58916a77314e440c2d91baae0009dd64496f34e6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 13:37:37 +0200 Subject: [PATCH 17/55] fixed creator for filter dialogue subview --- apps/opencs/view/world/subviews.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 393585e9a..1ab995343 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -108,7 +108,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Global, CSMWorld::UniversalId::Type_Race, CSMWorld::UniversalId::Type_Class, - CSMWorld::UniversalId::Type_Filter, CSMWorld::UniversalId::Type_Sound, CSMWorld::UniversalId::Type_Faction, CSMWorld::UniversalId::Type_Enchantment, @@ -152,6 +151,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_DebugProfile, new CSVDoc::SubViewFactoryWithCreator > (false)); + manager.add (CSMWorld::UniversalId::Type_Filter, + new CSVDoc::SubViewFactoryWithCreator > (false)); + //preview manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory); } \ No newline at end of file From 06e1cfe61362e53db28f1692b62608f18978a3d0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Aug 2014 14:41:34 +0200 Subject: [PATCH 18/55] added missing allowed drop types for script edit (script and region) --- apps/opencs/view/world/scriptedit.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 23bc76000..b3dece73c 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -40,7 +40,9 @@ CSVWorld::ScriptEdit::ScriptEdit (QWidget* parent, const CSMDoc::Document& docum < Date: Sun, 17 Aug 2014 15:25:22 +0200 Subject: [PATCH 19/55] moved script widget configuration code from ScriptSubView to ScriptEdit --- apps/opencs/view/world/scriptedit.cpp | 5 +++++ apps/opencs/view/world/scriptsubview.cpp | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index b3dece73c..8b4c76059 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -14,6 +14,11 @@ CSVWorld::ScriptEdit::ScriptEdit (QWidget* parent, const CSMDoc::Document& docum mDocument (document), mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive) { + setAcceptRichText (false); + setLineWrapMode (QTextEdit::NoWrap); + setTabStopWidth (4); + setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead + mAllowedTypes <setAcceptRichText (false); - mEditor->setLineWrapMode (QTextEdit::NoWrap); - mEditor->setTabStopWidth (4); - mEditor->setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead - mModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts)); From d4981c3037dc0b7826896ec3f2c3257ab7d98df5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 21 Aug 2014 14:50:13 +0200 Subject: [PATCH 20/55] moved change lock from ScriptSubView to ScriptEdit --- apps/opencs/view/world/scriptedit.cpp | 19 +++++++++++++++- apps/opencs/view/world/scriptedit.hpp | 28 ++++++++++++++++++++++++ apps/opencs/view/world/scriptsubview.cpp | 24 ++++++-------------- apps/opencs/view/world/scriptsubview.hpp | 19 ++-------------- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 8b4c76059..111be9b42 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -9,10 +9,22 @@ #include "../../model/world/universalid.hpp" #include "../../model/world/tablemimedata.hpp" +CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit) +{ + ++mEdit.mChangeLocked; +} + +CSVWorld::ScriptEdit::ChangeLock::~ChangeLock() +{ + --mEdit.mChangeLocked; +} + + CSVWorld::ScriptEdit::ScriptEdit (QWidget* parent, const CSMDoc::Document& document) : QTextEdit (parent), mDocument (document), - mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive) + mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive), + mChangeLocked (0) { setAcceptRichText (false); setLineWrapMode (QTextEdit::NoWrap); @@ -50,6 +62,11 @@ CSVWorld::ScriptEdit::ScriptEdit (QWidget* parent, const CSMDoc::Document& docum < (event->mimeData()); diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index b4627c2fe..0b2ede119 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -19,9 +19,37 @@ namespace CSVWorld class ScriptEdit : public QTextEdit { Q_OBJECT + public: + + class ChangeLock + { + ScriptEdit& mEdit; + + ChangeLock (const ChangeLock&); + ChangeLock& operator= (const ChangeLock&); + + public: + + ChangeLock (ScriptEdit& edit); + ~ChangeLock(); + }; + + friend class ChangeLock; + + private: + + int mChangeLocked; + + public: + ScriptEdit (QWidget* parent, const CSMDoc::Document& document); + /// Should changes to the data be ignored (i.e. not cause updated)? + /// + /// \note This mechanism is used to avoid infinite update recursions + bool isChangeLocked() const; + private: QVector mAllowedTypes; const CSMDoc::Document& mDocument; diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 0508b4de2..52cd04413 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -15,18 +15,8 @@ #include "scripthighlighter.hpp" #include "scriptedit.hpp" -CSVWorld::ScriptSubView::ChangeLock::ChangeLock (ScriptSubView& view) : mView (view) -{ - ++mView.mChangeLocked; -} - -CSVWorld::ScriptSubView::ChangeLock::~ChangeLock() -{ - --mView.mChangeLocked; -} - CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mDocument (document), mColumn (-1), mChangeLocked (0) +: SubView (id), mDocument (document), mColumn (-1) { setWidget (mEditor = new ScriptEdit (this, mDocument)); @@ -78,10 +68,10 @@ void CSVWorld::ScriptSubView::idListChanged() void CSVWorld::ScriptSubView::textChanged() { - if (mChangeLocked) + if (mEditor->isChangeLocked()) return; - ChangeLock lock (*this); + ScriptEdit::ChangeLock lock (*mEditor); mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel, mModel->getModelIndex (getUniversalId().getId(), mColumn), mEditor->toPlainText())); @@ -89,10 +79,10 @@ void CSVWorld::ScriptSubView::textChanged() void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (mChangeLocked) + if (mEditor->isChangeLocked()) return; - ChangeLock lock (*this); + ScriptEdit::ChangeLock lock (*mEditor); QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); @@ -115,10 +105,10 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i void CSVWorld::ScriptSubView::updateHighlighting() { - if (mChangeLocked) + if (mEditor->isChangeLocked()) return; - ChangeLock lock (*this); + ScriptEdit::ChangeLock lock (*mEditor); mHighlighter->rehighlight(); } \ No newline at end of file diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 7ceab70ba..ccb8f706e 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -21,34 +21,19 @@ namespace CSMWorld namespace CSVWorld { class ScriptHighlighter; + class ScriptEdit; class ScriptSubView : public CSVDoc::SubView { Q_OBJECT - QTextEdit *mEditor; + ScriptEdit *mEditor; CSMDoc::Document& mDocument; CSMWorld::IdTable *mModel; int mColumn; - int mChangeLocked; ScriptHighlighter *mHighlighter; QTimer mUpdateTimer; - class ChangeLock - { - ScriptSubView& mView; - - ChangeLock (const ChangeLock&); - ChangeLock& operator= (const ChangeLock&); - - public: - - ChangeLock (ScriptSubView& view); - ~ChangeLock(); - }; - - friend class ChangeLock; - public: ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); From c2e3709d0fd31deb5cb2f1180466c589d3f9cf2d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 22 Aug 2014 12:49:34 +0200 Subject: [PATCH 21/55] moved syntax highlighter from ScriptSubView to ScriptEdit --- apps/opencs/view/world/scriptedit.cpp | 30 ++++++++++++++++++++++++ apps/opencs/view/world/scriptedit.hpp | 13 +++++++++- apps/opencs/view/world/scriptsubview.cpp | 28 ---------------------- apps/opencs/view/world/scriptsubview.hpp | 12 ---------- 4 files changed, 42 insertions(+), 41 deletions(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 111be9b42..d91a3898c 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -6,9 +6,13 @@ #include #include +#include "../../model/doc/document.hpp" + #include "../../model/world/universalid.hpp" #include "../../model/world/tablemimedata.hpp" +#include "scripthighlighter.hpp" + CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit) { ++mEdit.mChangeLocked; @@ -60,6 +64,14 @@ CSVWorld::ScriptEdit::ScriptEdit (QWidget* parent, const CSMDoc::Document& docum <invalidateIds(); + + if (!mUpdateTimer.isActive()) + mUpdateTimer.start (0); +} + +void CSVWorld::ScriptEdit::updateHighlighting() +{ + if (isChangeLocked()) + return; + + ChangeLock lock (*this); + + mHighlighter->rehighlight(); +} \ No newline at end of file diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index 0b2ede119..993f4c653 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -1,8 +1,9 @@ #ifndef SCRIPTEDIT_H #define SCRIPTEDIT_H -#include +#include #include +#include #include "../../model/world/universalid.hpp" @@ -16,6 +17,8 @@ namespace CSMDoc namespace CSVWorld { + class ScriptHighlighter; + class ScriptEdit : public QTextEdit { Q_OBJECT @@ -40,6 +43,8 @@ namespace CSVWorld private: int mChangeLocked; + ScriptHighlighter *mHighlighter; + QTimer mUpdateTimer; public: @@ -62,6 +67,12 @@ namespace CSVWorld void dragMoveEvent (QDragMoveEvent* event); bool stringNeedsQuote(const std::string& id) const; + + private slots: + + void idListChanged(); + + void updateHighlighting(); }; } #endif // SCRIPTEDIT_H \ No newline at end of file diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 52cd04413..57910d250 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -3,8 +3,6 @@ #include -#include - #include "../../model/doc/document.hpp" #include "../../model/world/universalid.hpp" #include "../../model/world/data.hpp" @@ -12,7 +10,6 @@ #include "../../model/world/commands.hpp" #include "../../model/world/idtable.hpp" -#include "scripthighlighter.hpp" #include "scriptedit.hpp" CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) @@ -43,14 +40,6 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int))); - - connect (&document.getData(), SIGNAL (idListChanged()), this, SLOT (idListChanged())); - - mHighlighter = new ScriptHighlighter (document.getData(), mEditor->document()); - - connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting())); - - mUpdateTimer.setSingleShot (true); } void CSVWorld::ScriptSubView::setEditLock (bool locked) @@ -58,14 +47,6 @@ void CSVWorld::ScriptSubView::setEditLock (bool locked) mEditor->setReadOnly (locked); } -void CSVWorld::ScriptSubView::idListChanged() -{ - mHighlighter->invalidateIds(); - - if (!mUpdateTimer.isActive()) - mUpdateTimer.start (0); -} - void CSVWorld::ScriptSubView::textChanged() { if (mEditor->isChangeLocked()) @@ -103,12 +84,3 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i deleteLater(); } -void CSVWorld::ScriptSubView::updateHighlighting() -{ - if (mEditor->isChangeLocked()) - return; - - ScriptEdit::ChangeLock lock (*mEditor); - - mHighlighter->rehighlight(); -} \ No newline at end of file diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index ccb8f706e..77127d9be 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -3,9 +3,6 @@ #include "../doc/subview.hpp" -#include - -class QTextEdit; class QModelIndex; namespace CSMDoc @@ -20,7 +17,6 @@ namespace CSMWorld namespace CSVWorld { - class ScriptHighlighter; class ScriptEdit; class ScriptSubView : public CSVDoc::SubView @@ -31,8 +27,6 @@ namespace CSVWorld CSMDoc::Document& mDocument; CSMWorld::IdTable *mModel; int mColumn; - ScriptHighlighter *mHighlighter; - QTimer mUpdateTimer; public: @@ -42,17 +36,11 @@ namespace CSVWorld public slots: - void idListChanged(); - void textChanged(); void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); - - private slots: - - void updateHighlighting(); }; } From be61ed0f6a29324c7d5c37499cec77730821c376 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 22 Aug 2014 13:18:47 +0200 Subject: [PATCH 22/55] minor cleanup --- apps/opencs/view/world/scriptedit.cpp | 2 +- apps/opencs/view/world/scriptedit.hpp | 2 +- apps/opencs/view/world/scriptsubview.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index d91a3898c..89c27970f 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -24,7 +24,7 @@ CSVWorld::ScriptEdit::ChangeLock::~ChangeLock() } -CSVWorld::ScriptEdit::ScriptEdit (QWidget* parent, const CSMDoc::Document& document) : +CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, QWidget* parent) : QTextEdit (parent), mDocument (document), mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive), diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index 993f4c653..5713f2426 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -48,7 +48,7 @@ namespace CSVWorld public: - ScriptEdit (QWidget* parent, const CSMDoc::Document& document); + ScriptEdit (const CSMDoc::Document& document, QWidget* parent); /// Should changes to the data be ignored (i.e. not cause updated)? /// diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 57910d250..d2cde1db2 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -15,7 +15,7 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), mDocument (document), mColumn (-1) { - setWidget (mEditor = new ScriptEdit (this, mDocument)); + setWidget (mEditor = new ScriptEdit (mDocument, this)); mModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts)); From f468c532815c14484339b632a5c9762b5221164a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 22 Aug 2014 13:38:03 +0200 Subject: [PATCH 23/55] renamed the script field in DebugProfile to improve consistency --- components/esm/debugprofile.cpp | 6 +++--- components/esm/debugprofile.hpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/esm/debugprofile.cpp b/components/esm/debugprofile.cpp index bd0fdd80b..6c05fac2a 100644 --- a/components/esm/debugprofile.cpp +++ b/components/esm/debugprofile.cpp @@ -10,20 +10,20 @@ unsigned int ESM::DebugProfile::sRecordId = REC_DBGP; void ESM::DebugProfile::load (ESMReader& esm) { mDescription = esm.getHNString ("DESC"); - mScript = esm.getHNString ("SCRP"); + mScriptText = esm.getHNString ("SCRP"); esm.getHNT (mFlags, "FLAG"); } void ESM::DebugProfile::save (ESMWriter& esm) const { esm.writeHNCString ("DESC", mDescription); - esm.writeHNCString ("SCRP", mScript); + esm.writeHNCString ("SCRP", mScriptText); esm.writeHNT ("FLAG", mFlags); } void ESM::DebugProfile::blank() { mDescription.clear(); - mScript.clear(); + mScriptText.clear(); mFlags = 0; } diff --git a/components/esm/debugprofile.hpp b/components/esm/debugprofile.hpp index dc3658f7d..b54e8ff5f 100644 --- a/components/esm/debugprofile.hpp +++ b/components/esm/debugprofile.hpp @@ -23,7 +23,7 @@ namespace ESM std::string mDescription; - std::string mScript; + std::string mScriptText; unsigned int mFlags; From 30830d0693ce7a4cd57b36a7ff41f3436f3456bb Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 23 Aug 2014 12:25:12 +0200 Subject: [PATCH 24/55] make delegates use the whole document instead of the undo stack --- apps/opencs/view/tools/reportsubview.cpp | 2 +- .../opencs/view/world/datadisplaydelegate.cpp | 13 +++++-------- .../opencs/view/world/datadisplaydelegate.hpp | 4 ++-- apps/opencs/view/world/dialoguesubview.cpp | 14 +++++++------- apps/opencs/view/world/dialoguesubview.hpp | 8 ++++---- apps/opencs/view/world/enumdelegate.cpp | 10 +++++----- apps/opencs/view/world/enumdelegate.hpp | 4 ++-- apps/opencs/view/world/idtypedelegate.cpp | 10 +++++----- apps/opencs/view/world/idtypedelegate.hpp | 4 ++-- .../view/world/recordstatusdelegate.cpp | 10 +++++----- .../view/world/recordstatusdelegate.hpp | 4 ++-- apps/opencs/view/world/table.cpp | 2 +- apps/opencs/view/world/util.cpp | 19 ++++++++++++------- apps/opencs/view/world/util.hpp | 11 +++++++---- apps/opencs/view/world/vartypedelegate.cpp | 10 +++++----- apps/opencs/view/world/vartypedelegate.hpp | 4 ++-- 16 files changed, 67 insertions(+), 62 deletions(-) diff --git a/apps/opencs/view/tools/reportsubview.cpp b/apps/opencs/view/tools/reportsubview.cpp index e84f5cf4b..5a2523789 100644 --- a/apps/opencs/view/tools/reportsubview.cpp +++ b/apps/opencs/view/tools/reportsubview.cpp @@ -21,7 +21,7 @@ CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc: mTable->setSelectionMode (QAbstractItemView::ExtendedSelection); mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate ( - document.getUndoStack(), this); + document, this); mTable->setItemDelegateForColumn (0, mIdTypeDelegate); diff --git a/apps/opencs/view/world/datadisplaydelegate.cpp b/apps/opencs/view/world/datadisplaydelegate.cpp index 31ec18d52..20cf22cdf 100644 --- a/apps/opencs/view/world/datadisplaydelegate.cpp +++ b/apps/opencs/view/world/datadisplaydelegate.cpp @@ -6,11 +6,11 @@ CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values, const IconList &icons, - QUndoStack &undoStack, + CSMDoc::Document& document, const QString &pageName, const QString &settingName, QObject *parent) - : EnumDelegate (values, undoStack, parent), mDisplayMode (Mode_TextOnly), + : EnumDelegate (values, document, parent), mDisplayMode (Mode_TextOnly), mIcons (icons), mIconSize (QSize(16, 16)), mIconLeftOffset(3), mTextLeftOffset(8), mSettingKey (pageName + '/' + settingName) { @@ -126,8 +126,6 @@ void CSVWorld::DataDisplayDelegate::updateDisplayMode (const QString &mode) CSVWorld::DataDisplayDelegate::~DataDisplayDelegate() { - mIcons.clear(); - mPixmaps.clear(); } void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, QString enumName, QString iconFilename) @@ -137,11 +135,10 @@ void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, QString enumName, } -CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate (QUndoStack& undoStack, - QObject *parent) const +CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate ( + CSMDoc::Document& document, QObject *parent) const { - - return new DataDisplayDelegate (mValues, mIcons, undoStack, "", "", parent); + return new DataDisplayDelegate (mValues, mIcons, document, "", "", parent); } diff --git a/apps/opencs/view/world/datadisplaydelegate.hpp b/apps/opencs/view/world/datadisplaydelegate.hpp index ef453c58f..a29675e74 100755 --- a/apps/opencs/view/world/datadisplaydelegate.hpp +++ b/apps/opencs/view/world/datadisplaydelegate.hpp @@ -40,7 +40,7 @@ namespace CSVWorld public: explicit DataDisplayDelegate (const ValueList & values, const IconList & icons, - QUndoStack& undoStack, + CSMDoc::Document& document, const QString &pageName, const QString &settingName, QObject *parent); @@ -82,7 +82,7 @@ namespace CSVWorld public: - virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. protected: diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index bcf108934..749aeab5f 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -167,10 +167,10 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: ==============================DialogueDelegateDispatcher========================================== */ -CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) : +CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMDoc::Document& document) : mParent(parent), mTable(table), -mUndoStack(undoStack), +mDocument (document), mNotEditableDelegate(table, parent) { } @@ -182,7 +182,7 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS if (delegateIt == mDelegates.end()) { delegate = CommandDelegateFactoryCollection::get().makeDelegate ( - display, mUndoStack, mParent); + display, mDocument, mParent); mDelegates.insert(std::make_pair(display, delegate)); } else { @@ -315,12 +315,12 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() =============================================================EditWidget===================================================== */ -CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete) : -mDispatcher(this, table, undoStack), +CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete) : +mDispatcher(this, table, document), QScrollArea(parent), mWidgetMapper(NULL), mMainWidget(NULL), -mUndoStack(undoStack), +mDocument (document), mTable(table) { remake (row); @@ -478,7 +478,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); - mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false); + mEditWidget = new EditWidget(mainWidget, mRow, mTable, document, false); connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index cbca0159c..4c260170f 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -101,14 +101,14 @@ namespace CSVWorld CSMWorld::IdTable* mTable; - QUndoStack& mUndoStack; + CSMDoc::Document& mDocument; NotEditableSubDelegate mNotEditableDelegate; std::vector mProxys; //once we move to the C++11 we should use unique_ptr public: - DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack); + DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMDoc::Document& document); ~DialogueDelegateDispatcher(); @@ -145,11 +145,11 @@ namespace CSVWorld DialogueDelegateDispatcher mDispatcher; QWidget* mMainWidget; CSMWorld::IdTable* mTable; - QUndoStack& mUndoStack; + CSMDoc::Document& mDocument; public: - EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false); + EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete = false); void remake(int row); diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 377f479bf..168e5cb0a 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -35,8 +35,8 @@ void CSVWorld::EnumDelegate::addCommands (QAbstractItemModel *model, CSVWorld::EnumDelegate::EnumDelegate (const std::vector >& values, - QUndoStack& undoStack, QObject *parent) -: CommandDelegate (undoStack, parent), mValues (values) + CSMDoc::Document& document, QObject *parent) +: CommandDelegate (document, parent), mValues (values) { } @@ -140,10 +140,10 @@ CSVWorld::EnumDelegateFactory::EnumDelegateFactory (const std::vector >& values, - QUndoStack& undoStack, QObject *parent); + CSMDoc::Document& document, QObject *parent); virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, @@ -64,7 +64,7 @@ namespace CSVWorld EnumDelegateFactory (const std::vector& names, bool allowNone = false); /// \param allowNone Use value of -1 for "none selected" (empty string) - virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. void add (int value, const QString& name); diff --git a/apps/opencs/view/world/idtypedelegate.cpp b/apps/opencs/view/world/idtypedelegate.cpp index 6b4d442f3..543c96a24 100755 --- a/apps/opencs/view/world/idtypedelegate.cpp +++ b/apps/opencs/view/world/idtypedelegate.cpp @@ -3,8 +3,8 @@ #include "../../model/world/universalid.hpp" CSVWorld::IdTypeDelegate::IdTypeDelegate - (const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent) - : DataDisplayDelegate (values, icons, undoStack, + (const ValueList &values, const IconList &icons, CSMDoc::Document& document, QObject *parent) + : DataDisplayDelegate (values, icons, document, "Display Format", "Referenceable ID Type Display", parent) {} @@ -20,8 +20,8 @@ CSVWorld::IdTypeDelegateFactory::IdTypeDelegateFactory() } } -CSVWorld::CommandDelegate *CSVWorld::IdTypeDelegateFactory::makeDelegate (QUndoStack& undoStack, - QObject *parent) const +CSVWorld::CommandDelegate *CSVWorld::IdTypeDelegateFactory::makeDelegate ( + CSMDoc::Document& document, QObject *parent) const { - return new IdTypeDelegate (mValues, mIcons, undoStack, parent); + return new IdTypeDelegate (mValues, mIcons, document, parent); } diff --git a/apps/opencs/view/world/idtypedelegate.hpp b/apps/opencs/view/world/idtypedelegate.hpp index bed81f2d5..e9a0af68c 100755 --- a/apps/opencs/view/world/idtypedelegate.hpp +++ b/apps/opencs/view/world/idtypedelegate.hpp @@ -11,7 +11,7 @@ namespace CSVWorld class IdTypeDelegate : public DataDisplayDelegate { public: - IdTypeDelegate (const ValueList &mValues, const IconList &icons, QUndoStack& undoStack, QObject *parent); + IdTypeDelegate (const ValueList &mValues, const IconList &icons, CSMDoc::Document& document, QObject *parent); }; class IdTypeDelegateFactory : public DataDisplayDelegateFactory @@ -20,7 +20,7 @@ namespace CSVWorld IdTypeDelegateFactory(); - virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index 4fe7031ce..13931b7ad 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -9,16 +9,16 @@ CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values, const IconList & icons, - QUndoStack &undoStack, QObject *parent) - : DataDisplayDelegate (values, icons, undoStack, + CSMDoc::Document& document, QObject *parent) + : DataDisplayDelegate (values, icons, document, "Display Format", "Record Status Display", parent) {} -CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate (QUndoStack& undoStack, - QObject *parent) const +CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate ( + CSMDoc::Document& document, QObject *parent) const { - return new RecordStatusDelegate (mValues, mIcons, undoStack, parent); + return new RecordStatusDelegate (mValues, mIcons, document, parent); } CSVWorld::RecordStatusDelegateFactory::RecordStatusDelegateFactory() diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index 1b42223af..fbdaed538 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -19,7 +19,7 @@ namespace CSVWorld explicit RecordStatusDelegate(const ValueList& values, const IconList& icons, - QUndoStack& undoStack, QObject *parent = 0); + CSMDoc::Document& document, QObject *parent = 0); }; class RecordStatusDelegateFactory : public DataDisplayDelegateFactory @@ -28,7 +28,7 @@ namespace CSVWorld RecordStatusDelegateFactory(); - virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 43a34e41d..57f47033d 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -179,7 +179,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate (display, - mDocument.getUndoStack(), this); + mDocument, this); mDelegates.push_back (delegate); setItemDelegateForColumn (i, delegate); diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index ca66087fa..baea27098 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -78,15 +78,15 @@ void CSVWorld::CommandDelegateFactoryCollection::add (CSMWorld::ColumnBase::Disp } CSVWorld::CommandDelegate *CSVWorld::CommandDelegateFactoryCollection::makeDelegate ( - CSMWorld::ColumnBase::Display display, QUndoStack& undoStack, QObject *parent) const + CSMWorld::ColumnBase::Display display, CSMDoc::Document& document, QObject *parent) const { std::map::const_iterator iter = mFactories.find (display); if (iter!=mFactories.end()) - return iter->second->makeDelegate (undoStack, parent); + return iter->second->makeDelegate (document, parent); - return new CommandDelegate (undoStack, parent); + return new CommandDelegate (document, parent); } const CSVWorld::CommandDelegateFactoryCollection& CSVWorld::CommandDelegateFactoryCollection::get() @@ -100,7 +100,12 @@ const CSVWorld::CommandDelegateFactoryCollection& CSVWorld::CommandDelegateFacto QUndoStack& CSVWorld::CommandDelegate::getUndoStack() const { - return mUndoStack; + return mDocument.getUndoStack(); +} + +CSMDoc::Document& CSVWorld::CommandDelegate::getDocument() const +{ + return mDocument; } void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, @@ -112,11 +117,11 @@ void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemM QVariant new_ = hack.getData(); if (model->data (index)!=new_) - mUndoStack.push (new CSMWorld::ModifyCommand (*model, index, new_)); + getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); } -CSVWorld::CommandDelegate::CommandDelegate (QUndoStack& undoStack, QObject *parent) -: QStyledItemDelegate (parent), mUndoStack (undoStack), mEditLock (false) +CSVWorld::CommandDelegate::CommandDelegate (CSMDoc::Document& document, QObject *parent) +: QStyledItemDelegate (parent), mDocument (document), mEditLock (false) {} void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index c95a24982..b4d972bf3 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -51,7 +51,8 @@ namespace CSVWorld virtual ~CommandDelegateFactory(); - virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const = 0; + virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) + const = 0; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; @@ -77,7 +78,7 @@ namespace CSVWorld /// /// This function must not be called more than once per value of \a display. - CommandDelegate *makeDelegate (CSMWorld::ColumnBase::Display display, QUndoStack& undoStack, + CommandDelegate *makeDelegate (CSMWorld::ColumnBase::Display display, CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. /// @@ -110,19 +111,21 @@ namespace CSVWorld { Q_OBJECT - QUndoStack& mUndoStack; + CSMDoc::Document& mDocument; bool mEditLock; protected: QUndoStack& getUndoStack() const; + CSMDoc::Document& getDocument() const; + virtual void setModelDataImp (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; public: - CommandDelegate (QUndoStack& undoStack, QObject *parent); + CommandDelegate (CSMDoc::Document& document, QObject *parent); virtual void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; diff --git a/apps/opencs/view/world/vartypedelegate.cpp b/apps/opencs/view/world/vartypedelegate.cpp index fc00f4491..c3c98b800 100644 --- a/apps/opencs/view/world/vartypedelegate.cpp +++ b/apps/opencs/view/world/vartypedelegate.cpp @@ -47,8 +47,8 @@ void CSVWorld::VarTypeDelegate::addCommands (QAbstractItemModel *model, const QM } CSVWorld::VarTypeDelegate::VarTypeDelegate (const std::vector >& values, - QUndoStack& undoStack, QObject *parent) -: EnumDelegate (values, undoStack, parent) + CSMDoc::Document& document, QObject *parent) +: EnumDelegate (values, document, parent) {} @@ -68,10 +68,10 @@ CSVWorld::VarTypeDelegateFactory::VarTypeDelegateFactory (ESM::VarType type0, add (type3); } -CSVWorld::CommandDelegate *CSVWorld::VarTypeDelegateFactory::makeDelegate (QUndoStack& undoStack, - QObject *parent) const +CSVWorld::CommandDelegate *CSVWorld::VarTypeDelegateFactory::makeDelegate ( + CSMDoc::Document& document, QObject *parent) const { - return new VarTypeDelegate (mValues, undoStack, parent); + return new VarTypeDelegate (mValues, document, parent); } void CSVWorld::VarTypeDelegateFactory::add (ESM::VarType type) diff --git a/apps/opencs/view/world/vartypedelegate.hpp b/apps/opencs/view/world/vartypedelegate.hpp index c8493f029..c86b936f6 100644 --- a/apps/opencs/view/world/vartypedelegate.hpp +++ b/apps/opencs/view/world/vartypedelegate.hpp @@ -17,7 +17,7 @@ namespace CSVWorld public: VarTypeDelegate (const std::vector >& values, - QUndoStack& undoStack, QObject *parent); + CSMDoc::Document& document, QObject *parent); }; class VarTypeDelegateFactory : public CommandDelegateFactory @@ -30,7 +30,7 @@ namespace CSVWorld ESM::VarType type1 = ESM::VT_Unknown, ESM::VarType type2 = ESM::VT_Unknown, ESM::VarType type3 = ESM::VT_Unknown); - virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. void add (ESM::VarType type); From 5c536d571b377c8d9e16edfbcbdafaa1415c8a8b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 24 Aug 2014 13:15:18 +0200 Subject: [PATCH 25/55] added script column to debug profile table (dialogue only) --- apps/opencs/model/world/columnbase.hpp | 3 ++- apps/opencs/model/world/columnimp.hpp | 14 ++++++++++++-- apps/opencs/model/world/data.cpp | 4 +++- apps/opencs/view/world/util.cpp | 6 ++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 1444f70f1..f216dc99f 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -99,7 +99,8 @@ namespace CSMWorld Display_SoundRes, Display_Texture, Display_Video, - Display_Colour + Display_Colour, + Display_ScriptLines // console context }; int mColumnId; diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index e66320189..6c54240dc 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -807,8 +807,18 @@ namespace CSMWorld template struct ScriptColumn : public Column { - ScriptColumn() - : Column (Columns::ColumnId_ScriptText, ColumnBase::Display_Script, 0) {} + enum Type + { + Type_File, // regular script record + Type_Lines, // console context + Type_Info // dialogue context (not implemented yet) + }; + + ScriptColumn (Type type) + : Column (Columns::ColumnId_ScriptText, + type==Type_File ? ColumnBase::Display_Script : ColumnBase::Display_ScriptLines, + type==Type_File ? 0 : ColumnBase::Flag_Dialogue) + {} virtual QVariant get (const Record& record) const { diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 1172eef30..1e32250b1 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -131,7 +131,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mScripts.addColumn (new StringIdColumn); mScripts.addColumn (new RecordStateColumn); mScripts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Script)); - mScripts.addColumn (new ScriptColumn); + mScripts.addColumn (new ScriptColumn (ScriptColumn::Type_File)); mRegions.addColumn (new StringIdColumn); mRegions.addColumn (new RecordStateColumn); @@ -267,6 +267,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mDebugProfiles.addColumn (new FlagColumn2 ( Columns::ColumnId_GlobalProfile, ESM::DebugProfile::Flag_Global)); mDebugProfiles.addColumn (new DescriptionColumn); + mDebugProfiles.addColumn (new ScriptColumn ( + ScriptColumn::Type_Lines)); addModel (new IdTable (&mGlobals), UniversalId::Type_Global); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst); diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index baea27098..8ff3b6942 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -17,6 +17,8 @@ #include "../../model/world/commands.hpp" #include "../../model/world/tablemimedata.hpp" +#include "scriptedit.hpp" + CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model) : mModel (model) {} @@ -191,6 +193,10 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO return new DropLineEdit(parent); + case CSMWorld::ColumnBase::Display_ScriptLines: + + return new ScriptEdit (mDocument, parent); + default: return QStyledItemDelegate::createEditor (parent, option, index); From ea4cd94c25e23f38feaa3ca61cefe0c8c1e17ce2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 24 Aug 2014 17:56:20 +0200 Subject: [PATCH 26/55] syntax highlighter modes --- apps/opencs/view/world/scriptedit.cpp | 8 ++++---- apps/opencs/view/world/scriptedit.hpp | 7 ++++--- apps/opencs/view/world/scripthighlighter.cpp | 16 ++++++++++++++-- apps/opencs/view/world/scripthighlighter.hpp | 10 +++++++++- apps/opencs/view/world/scriptsubview.cpp | 2 +- apps/opencs/view/world/util.cpp | 2 +- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 89c27970f..5bed4760f 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -11,7 +11,6 @@ #include "../../model/world/universalid.hpp" #include "../../model/world/tablemimedata.hpp" -#include "scripthighlighter.hpp" CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit) { @@ -24,8 +23,9 @@ CSVWorld::ScriptEdit::ChangeLock::~ChangeLock() } -CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, QWidget* parent) : - QTextEdit (parent), +CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode, + QWidget* parent) + : QTextEdit (parent), mDocument (document), mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive), mChangeLocked (0) @@ -65,7 +65,7 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, QWidget* par < mScheme; + Mode mMode; private: @@ -74,7 +82,7 @@ namespace CSVWorld public: - ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent); + ScriptHighlighter (const CSMWorld::Data& data, Mode mode, QTextDocument *parent); virtual void highlightBlock (const QString& text); diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index d2cde1db2..df3fd87be 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -15,7 +15,7 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), mDocument (document), mColumn (-1) { - setWidget (mEditor = new ScriptEdit (mDocument, this)); + setWidget (mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this)); mModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts)); diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 8ff3b6942..4e82eab63 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -195,7 +195,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO case CSMWorld::ColumnBase::Display_ScriptLines: - return new ScriptEdit (mDocument, parent); + return new ScriptEdit (mDocument, ScriptHighlighter::Mode_Console, parent); default: From 7e653cebdf6833ea3767a87ec59b2082f7e06b73 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 1 Sep 2014 10:52:10 +0200 Subject: [PATCH 27/55] implement script editor via QPlainTextEdit instead of QTextEdit --- apps/opencs/view/world/scriptedit.cpp | 12 ++++++------ apps/opencs/view/world/scriptedit.hpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 5bed4760f..c2d94ab5d 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -25,13 +25,13 @@ CSVWorld::ScriptEdit::ChangeLock::~ChangeLock() CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode, QWidget* parent) - : QTextEdit (parent), + : QPlainTextEdit (parent), mDocument (document), mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive), mChangeLocked (0) { - setAcceptRichText (false); - setLineWrapMode (QTextEdit::NoWrap); +// setAcceptRichText (false); + setLineWrapMode (QPlainTextEdit::NoWrap); setTabStopWidth (4); setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead @@ -83,7 +83,7 @@ void CSVWorld::ScriptEdit::dragEnterEvent (QDragEnterEvent* event) { const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); if (!mime) - QTextEdit::dragEnterEvent(event); + QPlainTextEdit::dragEnterEvent(event); else { setTextCursor (cursorForPosition (event->pos())); @@ -95,7 +95,7 @@ void CSVWorld::ScriptEdit::dragMoveEvent (QDragMoveEvent* event) { const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); if (!mime) - QTextEdit::dragMoveEvent(event); + QPlainTextEdit::dragMoveEvent(event); else { setTextCursor (cursorForPosition (event->pos())); @@ -108,7 +108,7 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event) const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped { - QTextEdit::dropEvent(event); + QPlainTextEdit::dropEvent(event); return; } diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index 0b91c17c7..c67385816 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -1,7 +1,7 @@ #ifndef SCRIPTEDIT_H #define SCRIPTEDIT_H -#include +#include #include #include @@ -19,7 +19,7 @@ namespace CSMDoc namespace CSVWorld { - class ScriptEdit : public QTextEdit + class ScriptEdit : public QPlainTextEdit { Q_OBJECT From bec6c4e726296db27254aa9c6df012a8725b272e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 1 Sep 2014 10:56:38 +0200 Subject: [PATCH 28/55] fixed editor creation for Display_LongString --- apps/opencs/view/world/util.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 4e82eab63..3bfc4663a 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -169,8 +169,11 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO return new QDoubleSpinBox(parent); case CSMWorld::ColumnBase::Display_LongString: - - return new QTextEdit(parent); + { + QPlainTextEdit *edit = new QPlainTextEdit(parent); + edit->setUndoRedoEnabled (false); + return edit; + } case CSMWorld::ColumnBase::Display_Boolean: From 96cd46568ba3e95d80a8004229f8e851dc83ec3c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 1 Sep 2014 11:15:59 +0200 Subject: [PATCH 29/55] some cleanup --- apps/opencs/view/world/dialoguesubview.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 749aeab5f..57069bec0 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -266,7 +266,6 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: editor = delegateIt->second->createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); - bool skip = false; if (qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); @@ -274,27 +273,22 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: proxy, SLOT(tableMimeDataDropped(const std::vector&, const CSMDoc::Document*))); connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); - skip = true; } - if(!skip && qobject_cast(editor)) + else if (qobject_cast(editor)) { connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited())); - skip = true; } - if(!skip && qobject_cast(editor)) + else if (qobject_cast(editor)) { connect(editor, SIGNAL(textChanged()), proxy, SLOT(editorDataCommited())); - skip = true; } - if(!skip && qobject_cast(editor)) + else if (qobject_cast(editor)) { connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); - skip = true; } - if(!skip && qobject_cast(editor)) + else if (qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); - skip = true; } connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); From a9df3b53fd03c750aa1244e7d8832760865aea37 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 1 Sep 2014 11:55:12 +0200 Subject: [PATCH 30/55] restored --new-game switch --- apps/openmw/engine.cpp | 6 ++++-- apps/openmw/engine.hpp | 7 ++++++- apps/openmw/main.cpp | 7 ++++++- readme.txt | 2 ++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2e5689fa8..147057cf1 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -182,6 +182,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mGrab(true) , mScriptBlacklistUse (true) , mExportFonts(false) + , mNewGame (false) { std::srand ( std::time(NULL) ); MWClass::registerClasses(); @@ -264,9 +265,10 @@ void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity) mVerboseScripts = scriptsVerbosity; } -void OMW::Engine::setSkipMenu (bool skipMenu) +void OMW::Engine::setSkipMenu (bool skipMenu, bool newGame) { mSkipMenu = skipMenu; + mNewGame = newGame; } std::string OMW::Engine::loadSettings (Settings::Manager & settings) @@ -472,7 +474,7 @@ void OMW::Engine::go() } else { - MWBase::Environment::get().getStateManager()->newGame (true); + MWBase::Environment::get().getStateManager()->newGame (!mNewGame); } // Start the main rendering loop diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 10c1f6ff2..0f5b66f2f 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -93,6 +93,7 @@ namespace OMW Translation::Storage mTranslationDataStorage; std::vector mScriptBlacklist; bool mScriptBlacklistUse; + bool mNewGame; // not implemented Engine (const Engine&); @@ -153,7 +154,11 @@ namespace OMW /// Disable or enable all sounds void setSoundUsage(bool soundUsage); - void setSkipMenu (bool skipMenu); + /// Skip main menu and go directly into the game + /// + /// \param newGame Start a new game instead off dumping the player into the game + /// (ignored if !skipMenu). + void setSkipMenu (bool skipMenu, bool newGame); void setGrabMouse(bool grab) { mGrab = grab; } diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 57b3e045e..f81df31ff 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -153,6 +153,9 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("skip-menu", bpo::value()->implicit_value(true) ->default_value(false), "skip main menu on game startup") + ("new-game", bpo::value()->implicit_value(true) + ->default_value(false), "run new game sequence (ignored if skip-menu=0)") + ("fs-strict", bpo::value()->implicit_value(true) ->default_value(false), "strict file system handling (no case folding)") @@ -256,7 +259,9 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat // startup-settings engine.setCell(variables["start"].as()); - engine.setSkipMenu (variables["skip-menu"].as()); + engine.setSkipMenu (variables["skip-menu"].as(), variables["new-game"].as()); + if (!variables["skip-menu"].as() && variables["new-game"].as()) + std::cerr << "new-game used without skip-menu -> ignoring it" << std::endl; // scripts engine.setCompileAll(variables["script-all"].as()); diff --git a/readme.txt b/readme.txt index a02cc4ebc..79ffa7a8f 100644 --- a/readme.txt +++ b/readme.txt @@ -73,6 +73,8 @@ Allowed options: correctly compiled anyway 2 - treat warnings as errors --skip-menu [=arg(=1)] (=0) skip main menu on game startup + --new-game [=arg(=1)] (=0) run new game sequence (ignored if + skip-menu=0) --fs-strict [=arg(=1)] (=0) strict file system handling (no case folding) --encoding arg (=win1252) Character encoding used in OpenMW game From 1b4ab6e1307f446a96fbb156a80ac1df0e468539 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Sep 2014 10:21:17 +0200 Subject: [PATCH 31/55] added OpenMW runner --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/doc/document.cpp | 10 +++++++++ apps/opencs/model/doc/document.hpp | 7 ++++++ apps/opencs/model/doc/runner.cpp | 35 ++++++++++++++++++++++++++++++ apps/opencs/model/doc/runner.hpp | 33 ++++++++++++++++++++++++++++ apps/opencs/view/doc/view.cpp | 20 +++++++++++++++++ apps/opencs/view/doc/view.hpp | 4 ++++ 7 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/doc/runner.cpp create mode 100644 apps/opencs/model/doc/runner.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 2574eb111..5fbd0c5dd 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -5,7 +5,7 @@ opencs_units (. editor) set (CMAKE_BUILD_TYPE DEBUG) opencs_units (model/doc - document operation saving documentmanager loader + document operation saving documentmanager loader runner ) opencs_units_noqt (model/doc diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index c608757e0..f4eb72b6b 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2367,6 +2367,16 @@ bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id) return mBlacklist.isBlacklisted (id); } +void CSMDoc::Document::startRunning (const std::string& profile, + const std::string& startupInstruction) +{ + mRunner.start(); +} + +void CSMDoc::Document::stopRunning() +{ + mRunner.stop(); +} void CSMDoc::Document::progress (int current, int max, int type) { diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index d0e94d5e0..9efee352d 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -18,6 +18,7 @@ #include "state.hpp" #include "saving.hpp" #include "blacklist.hpp" +#include "runner.hpp" class QAbstractItemModel; @@ -54,6 +55,7 @@ namespace CSMDoc Saving mSaving; boost::filesystem::path mResDir; Blacklist mBlacklist; + Runner mRunner; // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. @@ -115,6 +117,11 @@ namespace CSMDoc bool isBlacklisted (const CSMWorld::UniversalId& id) const; + void startRunning (const std::string& profile, + const std::string& startupInstruction = ""); + + void stopRunning(); + signals: void stateChanged (int state, CSMDoc::Document *document); diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp new file mode 100644 index 000000000..dd8e745b2 --- /dev/null +++ b/apps/opencs/model/doc/runner.cpp @@ -0,0 +1,35 @@ + +#include "runner.hpp" + + +CSMDoc::Runner::Runner() +{ + connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), + this, SLOT (finished (int, QProcess::ExitStatus))); +} + +void CSMDoc::Runner::start() +{ + QString path = "openmw"; +#ifdef Q_OS_WIN + path.append(QString(".exe")); +#elif defined(Q_OS_MAC) + QDir dir(QCoreApplication::applicationDirPath()); + path = dir.absoluteFilePath(name); +#else + path.prepend(QString("./")); +#endif + + mProcess.start (path); + emit runStateChanged (true); +} + +void CSMDoc::Runner::stop() +{ + mProcess.kill(); +} + +void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) +{ + emit runStateChanged (false); +} diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp new file mode 100644 index 000000000..8ab73fcf3 --- /dev/null +++ b/apps/opencs/model/doc/runner.hpp @@ -0,0 +1,33 @@ +#ifndef CSM_DOC_RUNNER_H +#define CSM_DOC_RUNNER_H + +#include +#include + +namespace CSMDoc +{ + class Runner : public QObject + { + Q_OBJECT + + QProcess mProcess; + + public: + + Runner(); + + void start(); + + void stop(); + + signals: + + void runStateChanged (bool running); + + private slots: + + void finished (int exitCode, QProcess::ExitStatus exitStatus); + }; +} + +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index acd415034..9d1bb40e8 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -239,6 +239,16 @@ void CSVDoc::View::setupDebugMenu() QAction *profiles = new QAction (tr ("Debug Profiles"), this); connect (profiles, SIGNAL (triggered()), this, SLOT (addDebugProfilesSubView())); debug->addAction (profiles); + + debug->addSeparator(); + + QAction *run = new QAction (tr ("Run OpenMW"), this); + connect (run, SIGNAL (triggered()), this, SLOT (run())); + debug->addAction (run); + + QAction *stop = new QAction (tr ("Shutdown OpenMW"), this); + connect (stop, SIGNAL (triggered()), this, SLOT (stop())); + debug->addAction (stop); } void CSVDoc::View::setupUi() @@ -603,3 +613,13 @@ void CSVDoc::View::loadErrorLog() { addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_LoadErrorLog, 0)); } + +void CSVDoc::View::run() +{ + mDocument->startRunning ("", ""); +} + +void CSVDoc::View::stop() +{ + mDocument->stopRunning(); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index a76429315..dca8f4b22 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -201,6 +201,10 @@ namespace CSVDoc void toggleShowStatusBar (bool show); void loadErrorLog(); + + void run(); + + void stop(); }; } From c88b3a15209f5906835777872f9bd9e6d9ee8a64 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Sep 2014 11:56:35 +0200 Subject: [PATCH 32/55] track state of OpenMW process and enable/disable run/stop actions accordingly --- apps/opencs/model/doc/document.cpp | 10 ++++++++++ apps/opencs/model/doc/document.hpp | 2 ++ apps/opencs/model/doc/runner.cpp | 13 ++++++++++--- apps/opencs/model/doc/runner.hpp | 7 ++++++- apps/opencs/model/doc/state.hpp | 11 ++++++----- apps/opencs/view/doc/view.cpp | 15 +++++++++------ apps/opencs/view/doc/view.hpp | 2 ++ 7 files changed, 45 insertions(+), 15 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index f4eb72b6b..87f5c584e 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2256,6 +2256,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, connect ( &mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)), this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, int))); + + connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged())); } CSMDoc::Document::~Document() @@ -2277,6 +2279,9 @@ int CSMDoc::Document::getState() const if (mSaving.isRunning()) state |= State_Locked | State_Saving | State_Operation; + if (mRunner.isRunning()) + state |= State_Locked | State_Running; + if (int operations = mTools.getRunningOperations()) state |= State_Locked | State_Operation | operations; @@ -2378,6 +2383,11 @@ void CSMDoc::Document::stopRunning() mRunner.stop(); } +void CSMDoc::Document::runStateChanged() +{ + emit stateChanged (getState(), this); +} + void CSMDoc::Document::progress (int current, int max, int type) { emit progress (current, max, type, 1, this); diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 9efee352d..1ddfc8e1b 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -137,6 +137,8 @@ namespace CSMDoc void operationDone (int type); + void runStateChanged(); + public slots: void progress (int current, int max, int type); diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index dd8e745b2..994db72a5 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -2,7 +2,7 @@ #include "runner.hpp" -CSMDoc::Runner::Runner() +CSMDoc::Runner::Runner() : mRunning (false) { connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (finished (int, QProcess::ExitStatus))); @@ -21,7 +21,8 @@ void CSMDoc::Runner::start() #endif mProcess.start (path); - emit runStateChanged (true); + mRunning = true; + emit runStateChanged(); } void CSMDoc::Runner::stop() @@ -29,7 +30,13 @@ void CSMDoc::Runner::stop() mProcess.kill(); } +bool CSMDoc::Runner::isRunning() const +{ + return mRunning; +} + void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) { - emit runStateChanged (false); + mRunning = false; + emit runStateChanged(); } diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index 8ab73fcf3..c564f9af7 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -11,6 +11,7 @@ namespace CSMDoc Q_OBJECT QProcess mProcess; + bool mRunning; public: @@ -20,9 +21,13 @@ namespace CSMDoc void stop(); + /// \note Running state is entered when the start function is called. This + /// is not necessarily identical to the moment the child process is started. + bool isRunning() const; + signals: - void runStateChanged (bool running); + void runStateChanged(); private slots: diff --git a/apps/opencs/model/doc/state.hpp b/apps/opencs/model/doc/state.hpp index 6e1a1c4f4..287439a8b 100644 --- a/apps/opencs/model/doc/state.hpp +++ b/apps/opencs/model/doc/state.hpp @@ -8,12 +8,13 @@ namespace CSMDoc State_Modified = 1, State_Locked = 2, State_Operation = 4, + State_Running = 8, - State_Saving = 8, - State_Verifying = 16, - State_Compiling = 32, // not implemented yet - State_Searching = 64, // not implemented yet - State_Loading = 128 // pseudo-state; can not be encountered in a loaded document + State_Saving = 16, + State_Verifying = 32, + State_Compiling = 64, // not implemented yet + State_Searching = 128, // not implemented yet + State_Loading = 256 // pseudo-state; can not be encountered in a loaded document }; } diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 9d1bb40e8..2e60130a1 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -242,13 +242,13 @@ void CSVDoc::View::setupDebugMenu() debug->addSeparator(); - QAction *run = new QAction (tr ("Run OpenMW"), this); - connect (run, SIGNAL (triggered()), this, SLOT (run())); - debug->addAction (run); + mRunDebug = new QAction (tr ("Run OpenMW"), this); + connect (mRunDebug, SIGNAL (triggered()), this, SLOT (run())); + debug->addAction (mRunDebug); - QAction *stop = new QAction (tr ("Shutdown OpenMW"), this); - connect (stop, SIGNAL (triggered()), this, SLOT (stop())); - debug->addAction (stop); + mStopDebug = new QAction (tr ("Shutdown OpenMW"), this); + connect (mStopDebug, SIGNAL (triggered()), this, SLOT (stop())); + debug->addAction (mStopDebug); } void CSVDoc::View::setupUi() @@ -290,6 +290,9 @@ void CSVDoc::View::updateActions() mSave->setEnabled (!(mDocument->getState() & CSMDoc::State_Saving)); mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying)); + + mRunDebug->setEnabled (!(mDocument->getState() & CSMDoc::State_Running)); + mStopDebug->setEnabled ((mDocument->getState() & CSMDoc::State_Running)); } CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index dca8f4b22..49c19a23e 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -39,6 +39,8 @@ namespace CSVDoc QAction *mSave; QAction *mVerify; QAction *mShowStatusBar; + QAction *mRunDebug; + QAction *mStopDebug; std::vector mEditingActions; Operations *mOperations; SubViewFactoryManager mSubViewFactory; From bee36c9167823d24afb2056b6f0fd86e54f10fc1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Sep 2014 11:59:04 +0200 Subject: [PATCH 33/55] block saving while OpenMW process is running --- apps/opencs/view/doc/view.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 2e60130a1..cdb5c329f 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -281,6 +281,7 @@ void CSVDoc::View::updateTitle() void CSVDoc::View::updateActions() { bool editing = !(mDocument->getState() & CSMDoc::State_Locked); + bool running = mDocument->getState() & CSMDoc::State_Running; for (std::vector::iterator iter (mEditingActions.begin()); iter!=mEditingActions.end(); ++iter) (*iter)->setEnabled (editing); @@ -288,11 +289,11 @@ void CSVDoc::View::updateActions() mUndo->setEnabled (editing & mDocument->getUndoStack().canUndo()); mRedo->setEnabled (editing & mDocument->getUndoStack().canRedo()); - mSave->setEnabled (!(mDocument->getState() & CSMDoc::State_Saving)); + mSave->setEnabled (!(mDocument->getState() & CSMDoc::State_Saving) && !running); mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying)); - mRunDebug->setEnabled (!(mDocument->getState() & CSMDoc::State_Running)); - mStopDebug->setEnabled ((mDocument->getState() & CSMDoc::State_Running)); + mRunDebug->setEnabled (!running); + mStopDebug->setEnabled (running); } CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) From a06133a50ecc3b671882d023da064b3256993d6f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 3 Sep 2014 19:14:27 +0200 Subject: [PATCH 34/55] added failed flag to operation done signal --- apps/opencs/model/doc/document.cpp | 6 +++--- apps/opencs/model/doc/document.hpp | 2 +- apps/opencs/model/doc/operation.cpp | 2 +- apps/opencs/model/doc/operation.hpp | 2 +- apps/opencs/model/tools/tools.cpp | 2 +- apps/opencs/model/tools/tools.hpp | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 87f5c584e..65050cafd 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2248,10 +2248,10 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool))); connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); - connect (&mTools, SIGNAL (done (int)), this, SLOT (operationDone (int))); + connect (&mTools, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool))); connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); - connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int))); + connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool))); connect ( &mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)), @@ -2346,7 +2346,7 @@ void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std std::cout << message << std::endl; } -void CSMDoc::Document::operationDone (int type) +void CSMDoc::Document::operationDone (int type, bool failed) { emit stateChanged (getState(), this); } diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 1ddfc8e1b..4fedd8f40 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -135,7 +135,7 @@ namespace CSMDoc void reportMessage (const CSMWorld::UniversalId& id, const std::string& message, int type); - void operationDone (int type); + void operationDone (int type, bool failed); void runStateChanged(); diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index 42a432043..533ee20a9 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -119,5 +119,5 @@ void CSMDoc::Operation::executeStage() void CSMDoc::Operation::operationDone() { - emit done (mType); + emit done (mType, mError); } \ No newline at end of file diff --git a/apps/opencs/model/doc/operation.hpp b/apps/opencs/model/doc/operation.hpp index 651283880..d5a7d4e09 100644 --- a/apps/opencs/model/doc/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -54,7 +54,7 @@ namespace CSMDoc void reportMessage (const CSMWorld::UniversalId& id, const std::string& message, int type); - void done (int type); + void done (int type, bool failed); public slots: diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index fcf98868a..4b12acfe3 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -45,7 +45,7 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false); connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); - connect (mVerifier, SIGNAL (done (int)), this, SIGNAL (done (int))); + connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); connect (mVerifier, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)), this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, int))); diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 4d677142d..7ca30e6b9 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -70,7 +70,7 @@ namespace CSMTools void progress (int current, int max, int type); - void done (int type); + void done (int type, bool failed); }; } From 3fec253409f0d13c52f024788d47a1f8ab705f23 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 3 Sep 2014 19:56:52 +0200 Subject: [PATCH 35/55] save first (if document was modified) before running OpenMW --- apps/opencs/model/doc/document.cpp | 15 +++++++++- apps/opencs/model/doc/runner.cpp | 44 ++++++++++++++++++++++++------ apps/opencs/model/doc/runner.hpp | 23 +++++++++++++++- 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 65050cafd..d6776e564 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2375,7 +2375,20 @@ bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id) void CSMDoc::Document::startRunning (const std::string& profile, const std::string& startupInstruction) { - mRunner.start(); + int state = getState(); + + if (state & State_Modified) + { + // need to save first + mRunner.start (true); + + new SaveWatcher (&mRunner, &mSaving); // no, that is not a memory leak. Qt is weird. + + if (!(state & State_Saving)) + save(); + } + else + mRunner.start(); } void CSMDoc::Document::stopRunning() diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 994db72a5..47daa8656 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -1,6 +1,7 @@ #include "runner.hpp" +#include "operation.hpp" CSMDoc::Runner::Runner() : mRunning (false) { @@ -8,26 +9,36 @@ CSMDoc::Runner::Runner() : mRunning (false) this, SLOT (finished (int, QProcess::ExitStatus))); } -void CSMDoc::Runner::start() +void CSMDoc::Runner::start (bool delayed) { - QString path = "openmw"; + if (!delayed) + { + QString path = "openmw"; #ifdef Q_OS_WIN - path.append(QString(".exe")); + path.append(QString(".exe")); #elif defined(Q_OS_MAC) - QDir dir(QCoreApplication::applicationDirPath()); - path = dir.absoluteFilePath(name); + QDir dir(QCoreApplication::applicationDirPath()); + path = dir.absoluteFilePath(name); #else - path.prepend(QString("./")); + path.prepend(QString("./")); #endif - mProcess.start (path); + mProcess.start (path); + } + mRunning = true; emit runStateChanged(); } void CSMDoc::Runner::stop() { - mProcess.kill(); + if (mProcess.state()==QProcess::NotRunning) + { + mRunning = false; + emit runStateChanged(); + } + else + mProcess.kill(); } bool CSMDoc::Runner::isRunning() const @@ -40,3 +51,20 @@ void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) mRunning = false; emit runStateChanged(); } + + +CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, Operation *operation) +: QObject (runner), mRunner (runner) +{ + connect (operation, SIGNAL (done (int, bool)), this, SLOT (saveDone (int, bool))); +} + +void CSMDoc::SaveWatcher::saveDone (int type, bool failed) +{ + if (failed) + mRunner->stop(); + else + mRunner->start(); + + deleteLater(); +} diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index c564f9af7..4a0302670 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -17,7 +17,9 @@ namespace CSMDoc Runner(); - void start(); + /// \param delayed Flag as running but do not start the OpenMW process yet (the + /// process must be started by another call of start with delayed==false) + void start (bool delayed = false); void stop(); @@ -33,6 +35,25 @@ namespace CSMDoc void finished (int exitCode, QProcess::ExitStatus exitStatus); }; + + class Operation; + + /// \brief Watch for end of save operation and restart or stop runner + class SaveWatcher : public QObject + { + Q_OBJECT + + Runner *mRunner; + + public: + + /// *this attaches itself to runner + SaveWatcher (Runner *runner, Operation *operation); + + private slots: + + void saveDone (int type, bool failed); + }; } #endif From 431abcb63aac8989c5e1d88f7972fe97115cfc7e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 3 Sep 2014 20:06:49 +0200 Subject: [PATCH 36/55] handle shutdown of OpenMW processes when shutting down OpenCS --- apps/opencs/model/doc/runner.cpp | 10 ++++++++++ apps/opencs/model/doc/runner.hpp | 2 ++ 2 files changed, 12 insertions(+) diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 47daa8656..ce34f2b71 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -9,6 +9,16 @@ CSMDoc::Runner::Runner() : mRunning (false) this, SLOT (finished (int, QProcess::ExitStatus))); } +CSMDoc::Runner::~Runner() +{ + if (mRunning) + { + disconnect (&mProcess, 0, this, 0); + mProcess.kill(); + mProcess.waitForFinished(); + } +} + void CSMDoc::Runner::start (bool delayed) { if (!delayed) diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index 4a0302670..7d1bbd505 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -17,6 +17,8 @@ namespace CSMDoc Runner(); + ~Runner(); + /// \param delayed Flag as running but do not start the OpenMW process yet (the /// process must be started by another call of start with delayed==false) void start (bool delayed = false); From 67dfaa7f35ec30f8bc1f26a0019c1132e5115be7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 4 Sep 2014 10:47:30 +0200 Subject: [PATCH 37/55] update actions in main menu when creating a new view --- apps/opencs/view/doc/view.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index cdb5c329f..974d9ae3b 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -319,6 +319,8 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to setupUi(); + updateActions(); + CSVWorld::addSubViewFactories (mSubViewFactory); CSVTools::addSubViewFactories (mSubViewFactory); From a728d6d77adba94a6b4e43361ce8ef14000b796b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 4 Sep 2014 17:45:43 +0200 Subject: [PATCH 38/55] full implementation of global run menu item (replaces earlier placeholder implementation) --- apps/opencs/CMakeLists.txt | 2 +- .../view/doc/globaldebugprofilemenu.cpp | 93 +++++++++++++++++++ .../view/doc/globaldebugprofilemenu.hpp | 49 ++++++++++ apps/opencs/view/doc/view.cpp | 21 +++-- apps/opencs/view/doc/view.hpp | 5 +- 5 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 apps/opencs/view/doc/globaldebugprofilemenu.cpp create mode 100644 apps/opencs/view/doc/globaldebugprofilemenu.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 5fbd0c5dd..c88f791ab 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -44,7 +44,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc viewmanager view operations operation subview startup filedialog newgame - filewidget adjusterwidget loader + filewidget adjusterwidget loader globaldebugprofilemenu ) diff --git a/apps/opencs/view/doc/globaldebugprofilemenu.cpp b/apps/opencs/view/doc/globaldebugprofilemenu.cpp new file mode 100644 index 000000000..82bd96326 --- /dev/null +++ b/apps/opencs/view/doc/globaldebugprofilemenu.cpp @@ -0,0 +1,93 @@ + +#include "globaldebugprofilemenu.hpp" + +#include +#include + +#include + +#include "../../model/world/idtable.hpp" +#include "../../model/world/record.hpp" + +void CSVDoc::GlobalDebugProfileMenu::rebuild() +{ + clear(); + + delete mActions; + mActions = 0; + + int idColumn = mDebugProfiles->findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int stateColumn = mDebugProfiles->findColumnIndex (CSMWorld::Columns::ColumnId_Modification); + int globalColumn = mDebugProfiles->findColumnIndex ( + CSMWorld::Columns::ColumnId_GlobalProfile); + + int size = mDebugProfiles->rowCount(); + + std::vector ids; + + for (int i=0; idata (mDebugProfiles->index (i, stateColumn)).toInt(); + + bool global = mDebugProfiles->data (mDebugProfiles->index (i, globalColumn)).toInt(); + + if (state!=CSMWorld::RecordBase::State_Deleted && global) + ids.push_back ( + mDebugProfiles->data (mDebugProfiles->index (i, idColumn)).toString()); + } + + mActions = new QActionGroup (this); + connect (mActions, SIGNAL (triggered (QAction *)), this, SLOT (actionTriggered (QAction *))); + + std::sort (ids.begin(), ids.end()); + + for (std::vector::const_iterator iter (ids.begin()); iter!=ids.end(); ++iter) + { + mActions->addAction (addAction (*iter)); + } +} + +CSVDoc::GlobalDebugProfileMenu::GlobalDebugProfileMenu (CSMWorld::IdTable *debugProfiles, + QWidget *parent) +: QMenu (parent), mDebugProfiles (debugProfiles), mActions (0) +{ + rebuild(); + + connect (mDebugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (profileAboutToBeRemoved (const QModelIndex&, int, int))); + + connect (mDebugProfiles, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (profileInserted (const QModelIndex&, int, int))); + + connect (mDebugProfiles, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (profileChanged (const QModelIndex&, const QModelIndex&))); +} + +void CSVDoc::GlobalDebugProfileMenu::updateActions (bool running) +{ + if (mActions) + mActions->setEnabled (!running); +} + +void CSVDoc::GlobalDebugProfileMenu::profileAboutToBeRemoved (const QModelIndex& parent, + int start, int end) +{ + rebuild(); +} + +void CSVDoc::GlobalDebugProfileMenu::profileInserted (const QModelIndex& parent, int start, + int end) +{ + rebuild(); +} + +void CSVDoc::GlobalDebugProfileMenu::profileChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + rebuild(); +} + +void CSVDoc::GlobalDebugProfileMenu::actionTriggered (QAction *action) +{ + emit triggered (std::string (action->text().toUtf8().constData())); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/globaldebugprofilemenu.hpp b/apps/opencs/view/doc/globaldebugprofilemenu.hpp new file mode 100644 index 000000000..0d7906cce --- /dev/null +++ b/apps/opencs/view/doc/globaldebugprofilemenu.hpp @@ -0,0 +1,49 @@ +#ifndef CSV_DOC_GLOBALDEBUGPROFILEMENU_H +#define CSV_DOC_GLOBALDEBUGPROFILEMENU_H + +#include + +class QModelIndex; +class QActionGroup; + +namespace CSMWorld +{ + class IdTable; +} + +namespace CSVDoc +{ + class GlobalDebugProfileMenu : public QMenu + { + Q_OBJECT + + CSMWorld::IdTable *mDebugProfiles; + QActionGroup *mActions; + + private: + + void rebuild(); + + public: + + GlobalDebugProfileMenu (CSMWorld::IdTable *debugProfiles, QWidget *parent = 0); + + void updateActions (bool running); + + private slots: + + void profileAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + void profileInserted (const QModelIndex& parent, int start, int end); + + void profileChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + void actionTriggered (QAction *action); + + signals: + + void triggered (const std::string& profile); + }; +} + +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 974d9ae3b..3abde7c77 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -12,6 +12,8 @@ #include "../../model/doc/document.hpp" #include "../../model/settings/usersettings.hpp" +#include "../../model/world/idtable.hpp" + #include "../world/subviews.hpp" #include "../tools/subviews.hpp" @@ -19,6 +21,7 @@ #include "viewmanager.hpp" #include "operations.hpp" #include "subview.hpp" +#include "globaldebugprofilemenu.hpp" void CSVDoc::View::closeEvent (QCloseEvent *event) { @@ -242,9 +245,15 @@ void CSVDoc::View::setupDebugMenu() debug->addSeparator(); - mRunDebug = new QAction (tr ("Run OpenMW"), this); - connect (mRunDebug, SIGNAL (triggered()), this, SLOT (run())); - debug->addAction (mRunDebug); + mGlobalDebugProfileMenu = new GlobalDebugProfileMenu ( + &dynamic_cast (*mDocument->getData().getTableModel ( + CSMWorld::UniversalId::Type_DebugProfiles)), this); + + connect (mGlobalDebugProfileMenu, SIGNAL (triggered (const std::string&)), + this, SLOT (run (const std::string&))); + + QAction *runDebug = debug->addMenu (mGlobalDebugProfileMenu); + runDebug->setText (tr ("Run OpenMW")); mStopDebug = new QAction (tr ("Shutdown OpenMW"), this); connect (mStopDebug, SIGNAL (triggered()), this, SLOT (stop())); @@ -292,7 +301,7 @@ void CSVDoc::View::updateActions() mSave->setEnabled (!(mDocument->getState() & CSMDoc::State_Saving) && !running); mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying)); - mRunDebug->setEnabled (!running); + mGlobalDebugProfileMenu->updateActions (running); mStopDebug->setEnabled (running); } @@ -620,9 +629,9 @@ void CSVDoc::View::loadErrorLog() addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_LoadErrorLog, 0)); } -void CSVDoc::View::run() +void CSVDoc::View::run (const std::string& profile, const std::string& startupInstruction) { - mDocument->startRunning ("", ""); + mDocument->startRunning (profile, startupInstruction); } void CSVDoc::View::stop() diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 49c19a23e..23be54302 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -25,6 +25,7 @@ namespace CSVDoc { class ViewManager; class Operations; + class GlobalDebugProfileMenu; class View : public QMainWindow { @@ -39,12 +40,12 @@ namespace CSVDoc QAction *mSave; QAction *mVerify; QAction *mShowStatusBar; - QAction *mRunDebug; QAction *mStopDebug; std::vector mEditingActions; Operations *mOperations; SubViewFactoryManager mSubViewFactory; QMainWindow mSubViewWindow; + GlobalDebugProfileMenu *mGlobalDebugProfileMenu; // not implemented @@ -204,7 +205,7 @@ namespace CSVDoc void loadErrorLog(); - void run(); + void run (const std::string& profile, const std::string& startupInstruction = ""); void stop(); }; From 61a92da37410b404af6a49171ae819e52fbf98e4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 5 Sep 2014 11:03:16 +0200 Subject: [PATCH 39/55] use --new-game/--skip-menu switches when running from OpenCS --- apps/opencs/model/doc/document.cpp | 2 ++ apps/opencs/model/doc/runner.cpp | 17 ++++++++++++++++- apps/opencs/model/doc/runner.hpp | 5 +++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index d6776e564..1f73770eb 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2375,6 +2375,8 @@ bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id) void CSMDoc::Document::startRunning (const std::string& profile, const std::string& startupInstruction) { + mRunner.configure (getData().getDebugProfiles().getRecord (profile).get()); + int state = getState(); if (state & State_Modified) diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index ce34f2b71..8b26668a7 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -7,6 +7,8 @@ CSMDoc::Runner::Runner() : mRunning (false) { connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (finished (int, QProcess::ExitStatus))); + + mProfile.blank(); } CSMDoc::Runner::~Runner() @@ -33,7 +35,15 @@ void CSMDoc::Runner::start (bool delayed) path.prepend(QString("./")); #endif - mProcess.start (path); + QStringList arguments; + arguments << "--skip-menu"; + + if (mProfile.mFlags & ESM::DebugProfile::Flag_BypassNewGame) + arguments << "--new-game=0"; + else + arguments << "--new-game=1"; + + mProcess.start (path, arguments); } mRunning = true; @@ -56,6 +66,11 @@ bool CSMDoc::Runner::isRunning() const return mRunning; } +void CSMDoc::Runner::configure (const ESM::DebugProfile& profile) +{ + mProfile = profile; +} + void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) { mRunning = false; diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index 7d1bbd505..00092d0fe 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace CSMDoc { class Runner : public QObject @@ -12,6 +14,7 @@ namespace CSMDoc QProcess mProcess; bool mRunning; + ESM::DebugProfile mProfile; public: @@ -29,6 +32,8 @@ namespace CSMDoc /// is not necessarily identical to the moment the child process is started. bool isRunning() const; + void configure (const ESM::DebugProfile& profile); + signals: void runStateChanged(); From 5e022195b8bd427e315c27d928ceacf8f865f46a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 5 Sep 2014 11:40:01 +0200 Subject: [PATCH 40/55] create startup script when running from OpenCS --- apps/opencs/model/doc/document.cpp | 3 ++- apps/opencs/model/doc/runner.cpp | 34 ++++++++++++++++++++++++++++-- apps/opencs/model/doc/runner.hpp | 7 +++++- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 1f73770eb..17d624be7 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2375,7 +2375,8 @@ bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id) void CSMDoc::Document::startRunning (const std::string& profile, const std::string& startupInstruction) { - mRunner.configure (getData().getDebugProfiles().getRecord (profile).get()); + mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), + startupInstruction); int state = getState(); diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 8b26668a7..67bd5e4d2 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -1,9 +1,12 @@ #include "runner.hpp" +#include +#include + #include "operation.hpp" -CSMDoc::Runner::Runner() : mRunning (false) +CSMDoc::Runner::Runner() : mRunning (false), mStartup (0) { connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (finished (int, QProcess::ExitStatus))); @@ -23,6 +26,12 @@ CSMDoc::Runner::~Runner() void CSMDoc::Runner::start (bool delayed) { + if (mStartup) + { + delete mStartup; + mStartup = 0; + } + if (!delayed) { QString path = "openmw"; @@ -35,6 +44,20 @@ void CSMDoc::Runner::start (bool delayed) path.prepend(QString("./")); #endif + mStartup = new QTemporaryFile (this); + mStartup->open(); + + { + QTextStream stream (mStartup); + + if (!mStartupInstruction.empty()) + stream << QString::fromUtf8 (mStartupInstruction.c_str()) << '\n'; + + stream << QString::fromUtf8 (mProfile.mScriptText.c_str()); + } + + mStartup->close(); + QStringList arguments; arguments << "--skip-menu"; @@ -43,6 +66,8 @@ void CSMDoc::Runner::start (bool delayed) else arguments << "--new-game=1"; + arguments << ("--script-run="+mStartup->fileName()); + mProcess.start (path, arguments); } @@ -52,6 +77,9 @@ void CSMDoc::Runner::start (bool delayed) void CSMDoc::Runner::stop() { + delete mStartup; + mStartup = 0; + if (mProcess.state()==QProcess::NotRunning) { mRunning = false; @@ -66,9 +94,11 @@ bool CSMDoc::Runner::isRunning() const return mRunning; } -void CSMDoc::Runner::configure (const ESM::DebugProfile& profile) +void CSMDoc::Runner::configure (const ESM::DebugProfile& profile, + const std::string& startupInstruction) { mProfile = profile; + mStartupInstruction = startupInstruction; } void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index 00092d0fe..f63968e3b 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -6,6 +6,8 @@ #include +class QTemporaryFile; + namespace CSMDoc { class Runner : public QObject @@ -15,6 +17,8 @@ namespace CSMDoc QProcess mProcess; bool mRunning; ESM::DebugProfile mProfile; + std::string mStartupInstruction; + QTemporaryFile *mStartup; public: @@ -32,7 +36,8 @@ namespace CSMDoc /// is not necessarily identical to the moment the child process is started. bool isRunning() const; - void configure (const ESM::DebugProfile& profile); + void configure (const ESM::DebugProfile& profile, + const std::string& startupInstruction); signals: From cf05d3c69f64fef6f82a4570191b3975e0cfded9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 5 Sep 2014 13:49:34 +0200 Subject: [PATCH 41/55] added run log --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/doc/document.cpp | 5 +++++ apps/opencs/model/doc/document.hpp | 2 ++ apps/opencs/model/doc/runner.cpp | 18 ++++++++++++++++++ apps/opencs/model/doc/runner.hpp | 6 ++++++ apps/opencs/model/world/universalid.cpp | 1 + apps/opencs/model/world/universalid.hpp | 3 ++- apps/opencs/view/doc/runlogsubview.cpp | 20 ++++++++++++++++++++ apps/opencs/view/doc/runlogsubview.hpp | 20 ++++++++++++++++++++ apps/opencs/view/doc/view.cpp | 13 +++++++++++++ apps/opencs/view/doc/view.hpp | 2 ++ 11 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 apps/opencs/view/doc/runlogsubview.cpp create mode 100644 apps/opencs/view/doc/runlogsubview.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index c88f791ab..417d57981 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -44,7 +44,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc viewmanager view operations operation subview startup filedialog newgame - filewidget adjusterwidget loader globaldebugprofilemenu + filewidget adjusterwidget loader globaldebugprofilemenu runlogsubview ) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 17d624be7..8e414fb9c 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2399,6 +2399,11 @@ void CSMDoc::Document::stopRunning() mRunner.stop(); } +QTextDocument *CSMDoc::Document::getRunLog() +{ + return mRunner.getLog(); +} + void CSMDoc::Document::runStateChanged() { emit stateChanged (getState(), this); diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 4fedd8f40..29235e6e4 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -122,6 +122,8 @@ namespace CSMDoc void stopRunning(); + QTextDocument *getRunLog(); + signals: void stateChanged (int state, CSMDoc::Document *document); diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 67bd5e4d2..295733a5a 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -11,6 +11,11 @@ CSMDoc::Runner::Runner() : mRunning (false), mStartup (0) connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (finished (int, QProcess::ExitStatus))); + connect (&mProcess, SIGNAL (readyReadStandardOutput()), + this, SLOT (readyReadStandardOutput())); + + mProcess.setProcessChannelMode (QProcess::MergedChannels); + mProfile.blank(); } @@ -34,6 +39,8 @@ void CSMDoc::Runner::start (bool delayed) if (!delayed) { + mLog.clear(); + QString path = "openmw"; #ifdef Q_OS_WIN path.append(QString(".exe")); @@ -107,6 +114,17 @@ void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) emit runStateChanged(); } +QTextDocument *CSMDoc::Runner::getLog() +{ + return &mLog; +} + +void CSMDoc::Runner::readyReadStandardOutput() +{ + mLog.setPlainText ( + mLog.toPlainText() + QString::fromUtf8 (mProcess.readAllStandardOutput())); +} + CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, Operation *operation) : QObject (runner), mRunner (runner) diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index f63968e3b..9d0273f3e 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -19,6 +20,7 @@ namespace CSMDoc ESM::DebugProfile mProfile; std::string mStartupInstruction; QTemporaryFile *mStartup; + QTextDocument mLog; public: @@ -39,6 +41,8 @@ namespace CSMDoc void configure (const ESM::DebugProfile& profile, const std::string& startupInstruction); + QTextDocument *getLog(); + signals: void runStateChanged(); @@ -46,6 +50,8 @@ namespace CSMDoc private slots: void finished (int exitCode, QProcess::ExitStatus exitStatus); + + void readyReadStandardOutput(); }; class Operation; diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 7d2cce0de..d338a4a3b 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -51,6 +51,7 @@ namespace { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Textures, "Textures", 0 }, { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Videos, "Videos", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_DebugProfiles, "Debug Profiles", 0 }, + { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_RunLog, "Run Log", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 8f3437220..069beed4b 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -121,7 +121,8 @@ namespace CSMWorld Type_Videos, Type_Video, Type_DebugProfiles, - Type_DebugProfile + Type_DebugProfile, + Type_RunLog }; enum { NumberOfTypes = Type_DebugProfile+1 }; diff --git a/apps/opencs/view/doc/runlogsubview.cpp b/apps/opencs/view/doc/runlogsubview.cpp new file mode 100644 index 000000000..68e888e8d --- /dev/null +++ b/apps/opencs/view/doc/runlogsubview.cpp @@ -0,0 +1,20 @@ + +#include "runlogsubview.hpp" + +#include + +CSVDoc::RunLogSubView::RunLogSubView (const CSMWorld::UniversalId& id, + CSMDoc::Document& document) +: SubView (id) +{ + QTextEdit *edit = new QTextEdit (this); + edit->setDocument (document.getRunLog()); + edit->setReadOnly (true); + + setWidget (edit); +} + +void CSVDoc::RunLogSubView::setEditLock (bool locked) +{ + // ignored since this SubView does not have editing +} \ No newline at end of file diff --git a/apps/opencs/view/doc/runlogsubview.hpp b/apps/opencs/view/doc/runlogsubview.hpp new file mode 100644 index 000000000..cfb676a37 --- /dev/null +++ b/apps/opencs/view/doc/runlogsubview.hpp @@ -0,0 +1,20 @@ +#ifndef CSV_DOC_RUNLOGSUBVIEW_H +#define CSV_DOC_RUNLOGSUBVIEW_H + +#include "subview.hpp" + +namespace CSVDoc +{ + class RunLogSubView : public SubView + { + Q_OBJECT + + public: + + RunLogSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + + virtual void setEditLock (bool locked); + }; +} + +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 3abde7c77..cf5148391 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -22,6 +22,8 @@ #include "operations.hpp" #include "subview.hpp" #include "globaldebugprofilemenu.hpp" +#include "runlogsubview.hpp" +#include "subviewfactoryimp.hpp" void CSVDoc::View::closeEvent (QCloseEvent *event) { @@ -258,6 +260,10 @@ void CSVDoc::View::setupDebugMenu() mStopDebug = new QAction (tr ("Shutdown OpenMW"), this); connect (mStopDebug, SIGNAL (triggered()), this, SLOT (stop())); debug->addAction (mStopDebug); + + QAction *runLog = new QAction (tr ("Run Log"), this); + connect (runLog, SIGNAL (triggered()), this, SLOT (addRunLogSubView())); + debug->addAction (runLog); } void CSVDoc::View::setupUi() @@ -333,6 +339,8 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to CSVWorld::addSubViewFactories (mSubViewFactory); CSVTools::addSubViewFactories (mSubViewFactory); + mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory); + connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int))); } @@ -583,6 +591,11 @@ void CSVDoc::View::addDebugProfilesSubView() addSubView (CSMWorld::UniversalId::Type_DebugProfiles); } +void CSVDoc::View::addRunLogSubView() +{ + addSubView (CSMWorld::UniversalId::Type_RunLog); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 23be54302..9b4f2099b 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -201,6 +201,8 @@ namespace CSVDoc void addDebugProfilesSubView(); + void addRunLogSubView(); + void toggleShowStatusBar (bool show); void loadErrorLog(); From 64cf0870c6d2bae1ea73cc7a2630e285bde082ae Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 6 Sep 2014 12:24:09 +0200 Subject: [PATCH 42/55] set content files when running OpenMW from OpenCS --- apps/opencs/model/doc/document.cpp | 8 +++++++- apps/opencs/model/doc/runner.cpp | 9 ++++++++- apps/opencs/model/doc/runner.hpp | 5 +++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 8e414fb9c..ce216cfd6 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2375,7 +2375,13 @@ bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id) void CSMDoc::Document::startRunning (const std::string& profile, const std::string& startupInstruction) { - mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), + std::vector contentFiles; + + for (std::vector::const_iterator iter (mContentFiles.begin()); + iter!=mContentFiles.end(); ++iter) + contentFiles.push_back (iter->filename().string()); + + mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), contentFiles, startupInstruction); int state = getState(); diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 295733a5a..d97d5bb35 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -75,6 +75,12 @@ void CSMDoc::Runner::start (bool delayed) arguments << ("--script-run="+mStartup->fileName()); + for (std::vector::const_iterator iter (mContentFiles.begin()); + iter!=mContentFiles.end(); ++iter) + { + arguments << QString::fromUtf8 (("--content="+*iter).c_str()); + } + mProcess.start (path, arguments); } @@ -102,9 +108,10 @@ bool CSMDoc::Runner::isRunning() const } void CSMDoc::Runner::configure (const ESM::DebugProfile& profile, - const std::string& startupInstruction) + const std::vector& contentFiles, const std::string& startupInstruction) { mProfile = profile; + mContentFiles = contentFiles; mStartupInstruction = startupInstruction; } diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index 9d0273f3e..1505a96dc 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -1,6 +1,9 @@ #ifndef CSM_DOC_RUNNER_H #define CSM_DOC_RUNNER_H +#include +#include + #include #include #include @@ -18,6 +21,7 @@ namespace CSMDoc QProcess mProcess; bool mRunning; ESM::DebugProfile mProfile; + std::vector mContentFiles; std::string mStartupInstruction; QTemporaryFile *mStartup; QTextDocument mLog; @@ -39,6 +43,7 @@ namespace CSMDoc bool isRunning() const; void configure (const ESM::DebugProfile& profile, + const std::vector& contentFiles, const std::string& startupInstruction); QTextDocument *getLog(); From 51128d2d5785aeae1ca6af365c7ed3ce8953d3e5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 6 Sep 2014 16:11:06 +0200 Subject: [PATCH 43/55] added run button to scene subview toolbar --- apps/opencs/CMakeLists.txt | 2 +- .../view/render/pagedworldspacewidget.cpp | 14 ++++++ .../view/render/pagedworldspacewidget.hpp | 2 + .../view/render/unpagedworldspacewidget.cpp | 17 +++++++ .../view/render/unpagedworldspacewidget.hpp | 2 + apps/opencs/view/render/worldspacewidget.cpp | 49 ++++++++++++++++++- apps/opencs/view/render/worldspacewidget.hpp | 13 ++++- apps/opencs/view/widget/pushbutton.cpp | 4 ++ apps/opencs/view/widget/pushbutton.hpp | 1 + apps/opencs/view/widget/scenetool.cpp | 4 +- apps/opencs/view/widget/scenetool.hpp | 2 +- apps/opencs/view/widget/scenetoolrun.cpp | 35 +++++++++++++ apps/opencs/view/widget/scenetoolrun.hpp | 40 +++++++++++++++ apps/opencs/view/world/scenesubview.cpp | 4 ++ 14 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 apps/opencs/view/widget/scenetoolrun.cpp create mode 100644 apps/opencs/view/widget/scenetoolrun.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 417d57981..727c4d7b3 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -69,7 +69,7 @@ opencs_units_noqt (view/world ) opencs_units (view/widget - scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle + scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun ) opencs_units (view/render diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 21d88fb89..aaa624103 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -133,6 +133,20 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent flagAsModified(); } +std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() +{ + Ogre::Vector3 position = getCamera()->getPosition(); + + std::ostringstream stream; + + stream + << "player->position " + << position.x << ", " << position.y << ", " << position.z + << ", 0"; + + return stream.str(); +} + CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) : WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default") { diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index ec4485697..0c0022498 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -42,6 +42,8 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + virtual std::string getStartupInstruction(); + public: PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 5175eba6e..b7e73417a 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -1,7 +1,10 @@ #include "unpagedworldspacewidget.hpp" +#include + #include +#include #include @@ -149,6 +152,20 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare flagAsModified(); } +std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() +{ + Ogre::Vector3 position = getCamera()->getPosition(); + + std::ostringstream stream; + + stream + << "player->positionCell " + << position.x << ", " << position.y << ", " << position.z + << ", 0, \"" << mCellId << "\""; + + return stream.str(); +} + CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const { switch(type) diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 505d60735..a7e8e9ff5 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -60,6 +60,8 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + virtual std::string getStartupInstruction(); + private slots: void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 4d3c7f666..40324f415 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -1,6 +1,8 @@ #include "worldspacewidget.hpp" +#include + #include #include #include @@ -8,14 +10,16 @@ #include #include "../../model/world/universalid.hpp" +#include "../../model/world/idtable.hpp" #include "../widget/scenetoolmode.hpp" #include "../widget/scenetooltoggle.hpp" +#include "../widget/scenetoolrun.hpp" #include "elements.hpp" CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) -: SceneWidget (parent), mDocument(document) +: SceneWidget (parent), mDocument(document), mRun (0) { setAcceptDrops(true); @@ -112,6 +116,44 @@ CSVWidget::SceneToolToggle *CSVRender::WorldspaceWidget::makeSceneVisibilitySele return mSceneElements; } +CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool ( + CSVWidget::SceneToolbar *parent) +{ + CSMWorld::IdTable& debugProfiles = dynamic_cast ( + *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles)); + + std::vector profiles; + + int idColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int stateColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Modification); + int defaultColumn = debugProfiles.findColumnIndex ( + CSMWorld::Columns::ColumnId_DefaultProfile); + + int size = debugProfiles.rowCount(); + + for (int i=0; i& data) { @@ -201,6 +243,11 @@ void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) } //not handling drops from different documents at the moment } +void CSVRender::WorldspaceWidget::runRequest (const std::string& profile) +{ + mDocument.startRunning (profile, getStartupInstruction()); +} + void CSVRender::WorldspaceWidget::elementSelectionChanged() { setVisibilityMask (getElementMask()); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index e21ad5ec2..0c74b24bc 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -18,6 +18,7 @@ namespace CSVWidget class SceneToolMode; class SceneToolToggle; class SceneToolbar; + class SceneToolRun; } namespace CSVRender @@ -30,6 +31,8 @@ namespace CSVRender CSVRender::NavigationFree mFree; CSVRender::NavigationOrbit mOrbit; CSVWidget::SceneToolToggle *mSceneElements; + CSVWidget::SceneToolRun *mRun; + CSMDoc::Document& mDocument; public: @@ -60,6 +63,10 @@ namespace CSVRender CSVWidget::SceneToolToggle *makeSceneVisibilitySelector ( CSVWidget::SceneToolbar *parent); + /// \attention The created tool is not added to the toolbar (via addTool). Doing + /// that is the responsibility of the calling function. + CSVWidget::SceneToolRun *makeRunTool (CSVWidget::SceneToolbar *parent); + void selectDefaultNavigationMode(); static dropType getDropType(const std::vector& data); @@ -77,8 +84,6 @@ namespace CSVRender virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle *tool); - const CSMDoc::Document& mDocument; - private: void dragEnterEvent(QDragEnterEvent *event); @@ -87,6 +92,8 @@ namespace CSVRender void dragMoveEvent(QDragMoveEvent *event); + virtual std::string getStartupInstruction() = 0; + private slots: void selectNavigationMode (const std::string& mode); @@ -104,6 +111,8 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0; + virtual void runRequest (const std::string& profile); + protected slots: void elementSelectionChanged(); diff --git a/apps/opencs/view/widget/pushbutton.cpp b/apps/opencs/view/widget/pushbutton.cpp index 307ea1a75..21f5f0387 100644 --- a/apps/opencs/view/widget/pushbutton.cpp +++ b/apps/opencs/view/widget/pushbutton.cpp @@ -20,6 +20,10 @@ void CSVWidget::PushButton::setExtendedToolTip() break; + case Type_TopAction: + + break; + case Type_Mode: tooltip += diff --git a/apps/opencs/view/widget/pushbutton.hpp b/apps/opencs/view/widget/pushbutton.hpp index 64b38db2e..0b5ad6833 100644 --- a/apps/opencs/view/widget/pushbutton.hpp +++ b/apps/opencs/view/widget/pushbutton.hpp @@ -14,6 +14,7 @@ namespace CSVWidget enum Type { Type_TopMode, // top level button for mode selector panel + Type_TopAction, // top level button that triggers an action Type_Mode, // mode button Type_Toggle }; diff --git a/apps/opencs/view/widget/scenetool.cpp b/apps/opencs/view/widget/scenetool.cpp index e3f2dfd1c..8239074b6 100644 --- a/apps/opencs/view/widget/scenetool.cpp +++ b/apps/opencs/view/widget/scenetool.cpp @@ -3,8 +3,8 @@ #include "scenetoolbar.hpp" -CSVWidget::SceneTool::SceneTool (SceneToolbar *parent) -: PushButton (PushButton::Type_TopMode, "", parent) +CSVWidget::SceneTool::SceneTool (SceneToolbar *parent, Type type) +: PushButton (type, "", parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); setIconSize (QSize (parent->getIconSize(), parent->getIconSize())); diff --git a/apps/opencs/view/widget/scenetool.hpp b/apps/opencs/view/widget/scenetool.hpp index 24099683e..1aa4df9f7 100644 --- a/apps/opencs/view/widget/scenetool.hpp +++ b/apps/opencs/view/widget/scenetool.hpp @@ -14,7 +14,7 @@ namespace CSVWidget public: - SceneTool (SceneToolbar *parent); + SceneTool (SceneToolbar *parent, Type type = Type_TopMode); virtual void showPanel (const QPoint& position) = 0; diff --git a/apps/opencs/view/widget/scenetoolrun.cpp b/apps/opencs/view/widget/scenetoolrun.cpp new file mode 100644 index 000000000..b2f467559 --- /dev/null +++ b/apps/opencs/view/widget/scenetoolrun.cpp @@ -0,0 +1,35 @@ + +#include "scenetoolrun.hpp" + +void CSVWidget::SceneToolRun::adjustToolTips() +{ + QString toolTip = mToolTip; + + if (mCurrentIndex==-1) + toolTip += "

No debug profile selected (function disabled)"; + else + toolTip += "

Debug profile: " + QString::fromUtf8 (mProfiles[mCurrentIndex].c_str()); + + setToolTip (toolTip); +} + +void CSVWidget::SceneToolRun::updateIcon() +{ + setIcon (QIcon (mCurrentIndex==-1 ? mIconDisabled : mIcon)); +} + +CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& toolTip, + const QString& icon, const QString& iconDisabled, const std::vector& profiles) +: SceneTool (parent, Type_TopAction), mProfiles (profiles), + mCurrentIndex (profiles.empty() ? -1 : 0), mToolTip (toolTip), mIcon (icon), + mIconDisabled (iconDisabled) +{ + updateIcon(); + adjustToolTips(); +} + +void CSVWidget::SceneToolRun::showPanel (const QPoint& position) +{ + if (mCurrentIndex!=-1) + emit runRequest (mProfiles[mCurrentIndex]); +} diff --git a/apps/opencs/view/widget/scenetoolrun.hpp b/apps/opencs/view/widget/scenetoolrun.hpp new file mode 100644 index 000000000..cf16a172d --- /dev/null +++ b/apps/opencs/view/widget/scenetoolrun.hpp @@ -0,0 +1,40 @@ +#ifndef CSV_WIDGET_SCENETOOLRUN_H +#define CSV_WIDGET_SCENETOOLRUN_H + +#include +#include + +#include "scenetool.hpp" + +namespace CSVWidget +{ + class SceneToolRun : public SceneTool + { + Q_OBJECT + + std::vector mProfiles; + int mCurrentIndex; + QString mToolTip; + QString mIcon; + QString mIconDisabled; + + private: + + void adjustToolTips(); + + void updateIcon(); + + public: + + SceneToolRun (SceneToolbar *parent, const QString& toolTip, const QString& icon, + const QString& iconDisabled, const std::vector& profiles); + + virtual void showPanel (const QPoint& position); + + signals: + + void runRequest (const std::string& profile); + }; +} + +#endif diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 3c5b38a22..3afbbc805 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -20,6 +20,7 @@ #include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolmode.hpp" #include "../widget/scenetooltoggle.hpp" +#include "../widget/scenetoolrun.hpp" #include "tablebottombox.hpp" #include "creator.hpp" @@ -121,6 +122,9 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp toolbar->addTool (controlVisibilityTool); } + CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar); + toolbar->addTool (runTool); + return toolbar; } From f913d51e354b9e5db2b1226e5b1707a032c0d49d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 7 Sep 2014 12:55:52 +0200 Subject: [PATCH 44/55] remove deleted debug profiles from run tool --- apps/opencs/view/render/worldspacewidget.cpp | 55 ++++++++++++++++++++ apps/opencs/view/render/worldspacewidget.hpp | 6 +++ apps/opencs/view/widget/scenetoolrun.cpp | 19 +++++++ apps/opencs/view/widget/scenetoolrun.hpp | 2 + 4 files changed, 82 insertions(+) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 40324f415..fd7ead6e5 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -42,6 +42,14 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg this, SLOT (referenceAboutToBeRemoved (const QModelIndex&, int, int))); connect (references, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (referenceAdded (const QModelIndex&, int, int))); + + QAbstractItemModel *debugProfiles = + document.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles); + + connect (debugProfiles, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (debugProfileDataChanged (const QModelIndex&, const QModelIndex&))); + connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int))); } void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) @@ -248,6 +256,53 @@ void CSVRender::WorldspaceWidget::runRequest (const std::string& profile) mDocument.startRunning (profile, getStartupInstruction()); } +void CSVRender::WorldspaceWidget::debugProfileDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + if (!mRun) + return; + + CSMWorld::IdTable& debugProfiles = dynamic_cast ( + *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles)); + + int idColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int stateColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Modification); + + for (int i=topLeft.row(); i<=bottomRight.row(); ++i) + { + int state = debugProfiles.data (debugProfiles.index (i, stateColumn)).toInt(); + + // As of version 0.33 this case can not happen because debug profiles exist only in + // project or session scope, which means they will never be in deleted state. But we + // are adding the code for the sake of completeness and to avoid surprises if debug + // profile ever get extended to content scope. + if (state==CSMWorld::RecordBase::State_Deleted) + mRun->removeProfile (debugProfiles.data ( + debugProfiles.index (i, idColumn)).toString().toUtf8().constData()); + } +} + +void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelIndex& parent, + int start, int end) +{ + if (parent.isValid()) + return; + + if (!mRun) + return; + + CSMWorld::IdTable& debugProfiles = dynamic_cast ( + *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles)); + + int idColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Id); + + for (int i=start; i<=end; ++i) + { + mRun->removeProfile (debugProfiles.data ( + debugProfiles.index (i, idColumn)).toString().toUtf8().constData()); + } +} + void CSVRender::WorldspaceWidget::elementSelectionChanged() { setVisibilityMask (getElementMask()); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 0c74b24bc..d730b21a8 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -113,6 +113,12 @@ namespace CSVRender virtual void runRequest (const std::string& profile); + void debugProfileDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight); + + void debugProfileAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + protected slots: void elementSelectionChanged(); diff --git a/apps/opencs/view/widget/scenetoolrun.cpp b/apps/opencs/view/widget/scenetoolrun.cpp index b2f467559..ce2dbe76f 100644 --- a/apps/opencs/view/widget/scenetoolrun.cpp +++ b/apps/opencs/view/widget/scenetoolrun.cpp @@ -33,3 +33,22 @@ void CSVWidget::SceneToolRun::showPanel (const QPoint& position) if (mCurrentIndex!=-1) emit runRequest (mProfiles[mCurrentIndex]); } + +void CSVWidget::SceneToolRun::removeProfile (const std::string& profile) +{ + std::pair::iterator, std::vector::iterator> + result = std::equal_range (mProfiles.begin(), mProfiles.end(), profile); + + if (result.first!=result.second) + { + mProfiles.erase (result.first); + + if (mCurrentIndex>=static_cast (mProfiles.size())) + --mCurrentIndex; + + if (mCurrentIndex==-1) + updateIcon(); + + adjustToolTips(); + } +} \ No newline at end of file diff --git a/apps/opencs/view/widget/scenetoolrun.hpp b/apps/opencs/view/widget/scenetoolrun.hpp index cf16a172d..50008dae9 100644 --- a/apps/opencs/view/widget/scenetoolrun.hpp +++ b/apps/opencs/view/widget/scenetoolrun.hpp @@ -31,6 +31,8 @@ namespace CSVWidget virtual void showPanel (const QPoint& position); + void removeProfile (const std::string& profile); + signals: void runRequest (const std::string& profile); From 4337d051261d4dee6066d9832ea26885701014ea Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 7 Sep 2014 13:35:30 +0200 Subject: [PATCH 45/55] added right-click handling support to SceneTool class --- apps/opencs/view/widget/pushbutton.cpp | 5 +++++ apps/opencs/view/widget/pushbutton.hpp | 2 ++ apps/opencs/view/widget/scenetool.cpp | 17 ++++++++++++++++- apps/opencs/view/widget/scenetool.hpp | 8 ++++++++ apps/opencs/view/widget/scenetoolrun.cpp | 5 +++++ apps/opencs/view/widget/scenetoolrun.hpp | 2 ++ 6 files changed, 38 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/widget/pushbutton.cpp b/apps/opencs/view/widget/pushbutton.cpp index 21f5f0387..f23462585 100644 --- a/apps/opencs/view/widget/pushbutton.cpp +++ b/apps/opencs/view/widget/pushbutton.cpp @@ -91,4 +91,9 @@ bool CSVWidget::PushButton::hasKeepOpen() const QString CSVWidget::PushButton::getBaseToolTip() const { return mToolTip; +} + +CSVWidget::PushButton::Type CSVWidget::PushButton::getType() const +{ + return mType; } \ No newline at end of file diff --git a/apps/opencs/view/widget/pushbutton.hpp b/apps/opencs/view/widget/pushbutton.hpp index 0b5ad6833..35062a137 100644 --- a/apps/opencs/view/widget/pushbutton.hpp +++ b/apps/opencs/view/widget/pushbutton.hpp @@ -51,6 +51,8 @@ namespace CSVWidget /// Return tooltip used at construction (without any button-specific modifications) QString getBaseToolTip() const; + + Type getType() const; }; } diff --git a/apps/opencs/view/widget/scenetool.cpp b/apps/opencs/view/widget/scenetool.cpp index 8239074b6..b8e9f895f 100644 --- a/apps/opencs/view/widget/scenetool.cpp +++ b/apps/opencs/view/widget/scenetool.cpp @@ -1,6 +1,8 @@ #include "scenetool.hpp" +#include + #include "scenetoolbar.hpp" CSVWidget::SceneTool::SceneTool (SceneToolbar *parent, Type type) @@ -13,7 +15,20 @@ CSVWidget::SceneTool::SceneTool (SceneToolbar *parent, Type type) connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); } +void CSVWidget::SceneTool::activate() {} + +void CSVWidget::SceneTool::mouseReleaseEvent (QMouseEvent *event) +{ + if (getType()==Type_TopAction && event->button()==Qt::RightButton) + showPanel (parentWidget()->mapToGlobal (pos())); + else + PushButton::mouseReleaseEvent (event); +} + void CSVWidget::SceneTool::openRequest() { - showPanel (parentWidget()->mapToGlobal (pos())); + if (getType()==Type_TopAction) + activate(); + else + showPanel (parentWidget()->mapToGlobal (pos())); } diff --git a/apps/opencs/view/widget/scenetool.hpp b/apps/opencs/view/widget/scenetool.hpp index 1aa4df9f7..cdea88096 100644 --- a/apps/opencs/view/widget/scenetool.hpp +++ b/apps/opencs/view/widget/scenetool.hpp @@ -18,6 +18,14 @@ namespace CSVWidget virtual void showPanel (const QPoint& position) = 0; + /// This function will only called for buttons of type Type_TopAction. The default + /// implementation is empty. + virtual void activate(); + + protected: + + void mouseReleaseEvent (QMouseEvent *event); + private slots: void openRequest(); diff --git a/apps/opencs/view/widget/scenetoolrun.cpp b/apps/opencs/view/widget/scenetoolrun.cpp index ce2dbe76f..4a89c9fe9 100644 --- a/apps/opencs/view/widget/scenetoolrun.cpp +++ b/apps/opencs/view/widget/scenetoolrun.cpp @@ -29,6 +29,11 @@ CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& tool } void CSVWidget::SceneToolRun::showPanel (const QPoint& position) +{ + +} + +void CSVWidget::SceneToolRun::activate() { if (mCurrentIndex!=-1) emit runRequest (mProfiles[mCurrentIndex]); diff --git a/apps/opencs/view/widget/scenetoolrun.hpp b/apps/opencs/view/widget/scenetoolrun.hpp index 50008dae9..b1ea3229d 100644 --- a/apps/opencs/view/widget/scenetoolrun.hpp +++ b/apps/opencs/view/widget/scenetoolrun.hpp @@ -31,6 +31,8 @@ namespace CSVWidget virtual void showPanel (const QPoint& position); + virtual void activate(); + void removeProfile (const std::string& profile); signals: From 3f24593dba1d2fa80f23ef85ca7f0bc0c555f305 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 7 Sep 2014 14:40:50 +0200 Subject: [PATCH 46/55] added profile selection panel --- apps/opencs/view/widget/scenetoolrun.cpp | 62 ++++++++++++++++++++++++ apps/opencs/view/widget/scenetoolrun.hpp | 14 ++++++ 2 files changed, 76 insertions(+) diff --git a/apps/opencs/view/widget/scenetoolrun.cpp b/apps/opencs/view/widget/scenetoolrun.cpp index 4a89c9fe9..f378725ae 100644 --- a/apps/opencs/view/widget/scenetoolrun.cpp +++ b/apps/opencs/view/widget/scenetoolrun.cpp @@ -1,6 +1,12 @@ #include "scenetoolrun.hpp" +#include +#include +#include +#include +#include + void CSVWidget::SceneToolRun::adjustToolTips() { QString toolTip = mToolTip; @@ -8,7 +14,10 @@ void CSVWidget::SceneToolRun::adjustToolTips() if (mCurrentIndex==-1) toolTip += "

No debug profile selected (function disabled)"; else + { toolTip += "

Debug profile: " + QString::fromUtf8 (mProfiles[mCurrentIndex].c_str()); + toolTip += "

(right click to switch to a different profile)"; + } setToolTip (toolTip); } @@ -18,6 +27,19 @@ void CSVWidget::SceneToolRun::updateIcon() setIcon (QIcon (mCurrentIndex==-1 ? mIconDisabled : mIcon)); } +void CSVWidget::SceneToolRun::updatePanel() +{ + mTable->setRowCount (mProfiles.size()); + + for (int i=0; i (mProfiles.size()); ++i) + { + mTable->setItem (i, 0, new QTableWidgetItem (QString::fromUtf8 (mProfiles[i].c_str()))); + + mTable->setItem (i, 1, new QTableWidgetItem ( + QApplication::style()->standardIcon (QStyle::SP_TitleBarCloseButton), "")); + } +} + CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& toolTip, const QString& icon, const QString& iconDisabled, const std::vector& profiles) : SceneTool (parent, Type_TopAction), mProfiles (profiles), @@ -26,11 +48,34 @@ CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& tool { updateIcon(); adjustToolTips(); + + mPanel = new QFrame (this, Qt::Popup); + + QHBoxLayout *layout = new QHBoxLayout (mPanel); + + layout->setContentsMargins (QMargins (0, 0, 0, 0)); + + mTable = new QTableWidget (0, 2, this); + + mTable->setShowGrid (false); + mTable->verticalHeader()->hide(); + mTable->horizontalHeader()->hide(); + mTable->horizontalHeader()->setResizeMode (0, QHeaderView::Stretch); + mTable->horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents); + mTable->setSelectionMode (QAbstractItemView::NoSelection); + + layout->addWidget (mTable); + + connect (mTable, SIGNAL (clicked (const QModelIndex&)), + this, SLOT (clicked (const QModelIndex&))); } void CSVWidget::SceneToolRun::showPanel (const QPoint& position) { + updatePanel(); + mPanel->move (position); + mPanel->show(); } void CSVWidget::SceneToolRun::activate() @@ -56,4 +101,21 @@ void CSVWidget::SceneToolRun::removeProfile (const std::string& profile) adjustToolTips(); } +} + +void CSVWidget::SceneToolRun::clicked (const QModelIndex& index) +{ + if (index.column()==0) + { + // select profile + mCurrentIndex = index.row(); + mPanel->hide(); + adjustToolTips(); + } + else if (index.column()==1) + { + // remove profile from list + removeProfile (mProfiles.at (index.row())); + updatePanel(); + } } \ No newline at end of file diff --git a/apps/opencs/view/widget/scenetoolrun.hpp b/apps/opencs/view/widget/scenetoolrun.hpp index b1ea3229d..609ddcd34 100644 --- a/apps/opencs/view/widget/scenetoolrun.hpp +++ b/apps/opencs/view/widget/scenetoolrun.hpp @@ -6,6 +6,10 @@ #include "scenetool.hpp" +class QFrame; +class QTableWidget; +class QModelIndex; + namespace CSVWidget { class SceneToolRun : public SceneTool @@ -17,6 +21,8 @@ namespace CSVWidget QString mToolTip; QString mIcon; QString mIconDisabled; + QFrame *mPanel; + QTableWidget *mTable; private: @@ -24,6 +30,8 @@ namespace CSVWidget void updateIcon(); + void updatePanel(); + public: SceneToolRun (SceneToolbar *parent, const QString& toolTip, const QString& icon, @@ -33,8 +41,14 @@ namespace CSVWidget virtual void activate(); + /// \attention This function does not remove the profile from the profile selection + /// panel. void removeProfile (const std::string& profile); + private slots: + + void clicked (const QModelIndex& index); + signals: void runRequest (const std::string& profile); From 5a9376450b1a69ff4f359a59f2379d6f92381f5f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 11 Sep 2014 11:27:56 +0200 Subject: [PATCH 47/55] some cleanup of the scene view drop code --- .../view/render/pagedworldspacewidget.cpp | 6 +- .../view/render/pagedworldspacewidget.hpp | 2 +- .../view/render/unpagedworldspacewidget.cpp | 6 +- .../view/render/unpagedworldspacewidget.hpp | 2 +- apps/opencs/view/render/worldspacewidget.cpp | 56 +++++-------------- apps/opencs/view/render/worldspacewidget.hpp | 13 ++--- 6 files changed, 28 insertions(+), 57 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index aaa624103..47ac1d9ad 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -240,14 +240,14 @@ void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld:: } } -CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const +CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::DropType type) const { switch (type) { - case cellsExterior: + case Type_CellsExterior: return canHandle; - case cellsInterior: + case Type_CellsInterior: return needUnpaged; default: diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 0c0022498..90053265e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -59,7 +59,7 @@ namespace CSVRender virtual void handleDrop(const std::vector& data); - virtual dropRequirments getDropRequirements(dropType type) const; + virtual dropRequirments getDropRequirements(DropType type) const; /// \attention The created tool is not added to the toolbar (via addTool). Doing /// that is the responsibility of the calling function. diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index b7e73417a..a85134c29 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -166,14 +166,14 @@ std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() return stream.str(); } -CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const +CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::DropType type) const { switch(type) { - case cellsInterior: + case Type_CellsInterior: return canHandle; - case cellsExterior: + case Type_CellsExterior: return needPaged; default: diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index a7e8e9ff5..f604419d6 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -41,7 +41,7 @@ namespace CSVRender UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget *parent); - virtual dropRequirments getDropRequirements(dropType type) const; + virtual dropRequirments getDropRequirements(DropType type) const; virtual void handleDrop(const std::vector& data); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index fd7ead6e5..6f5b2410b 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -162,54 +162,26 @@ CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool ( return mRun; } -CSVRender::WorldspaceWidget::dropType CSVRender::WorldspaceWidget::getDropType ( +CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType ( const std::vector< CSMWorld::UniversalId >& data) { - dropType output = notCells; - bool firstIteration = true; + DropType output = Type_Other; - for (unsigned i = 0; i < data.size(); ++i) + for (std::vector::const_iterator iter (data.begin()); + iter!=data.end(); ++iter) { - if (data[i].getType() == CSMWorld::UniversalId::Type_Cell || - data[i].getType() == CSMWorld::UniversalId::Type_Cell_Missing) + DropType type = Type_Other; + + if (iter->getType()==CSMWorld::UniversalId::Type_Cell || + iter->getType()==CSMWorld::UniversalId::Type_Cell_Missing) { - if (*(data[i].getId().begin()) == '#') //exterior - { - if (firstIteration) - { - output = cellsExterior; - firstIteration = false; - continue; - } - - if (output == cellsInterior) - { - output = cellsMixed; - break; - } else { - output = cellsInterior; - } - } else //interior - { - if (firstIteration) - { - output = cellsInterior; - firstIteration = false; - continue; - } - - if (output == cellsExterior) - { - output = cellsMixed; - break; - } else { - output = cellsInterior; - } - } - } else { - output = notCells; - break; + type = iter->getId().substr (0, 1)=="#" ? Type_CellsExterior : Type_CellsInterior; } + + if (iter==data.begin()) + output = type; + else if (output!=type) // mixed types -> ignore + return Type_Other; } return output; diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index d730b21a8..99c56bd10 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -36,12 +36,11 @@ namespace CSVRender public: - enum dropType + enum DropType { - cellsMixed, - cellsInterior, - cellsExterior, - notCells + Type_CellsInterior, + Type_CellsExterior, + Type_Other }; enum dropRequirments @@ -69,9 +68,9 @@ namespace CSVRender void selectDefaultNavigationMode(); - static dropType getDropType(const std::vector& data); + static DropType getDropType(const std::vector& data); - virtual dropRequirments getDropRequirements(dropType type) const = 0; + virtual dropRequirments getDropRequirements(DropType type) const = 0; virtual void useViewHint (const std::string& hint); ///< Default-implementation: ignored. From 0db288ce07cf563c02024a1fca4a2b8ef361b051 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 11 Sep 2014 13:04:20 +0200 Subject: [PATCH 48/55] generalising and cleaning up drop implementation of worldspace widget --- .../opencs/view/render/pagedworldspacewidget.cpp | 16 +++++++++++++++- .../opencs/view/render/pagedworldspacewidget.hpp | 4 +++- .../view/render/unpagedworldspacewidget.cpp | 15 ++++++++++++++- .../view/render/unpagedworldspacewidget.hpp | 4 +++- apps/opencs/view/render/worldspacewidget.cpp | 12 ++++++++++++ apps/opencs/view/render/worldspacewidget.hpp | 6 ++++-- apps/opencs/view/world/scenesubview.cpp | 8 +++++--- 7 files changed, 56 insertions(+), 9 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 47ac1d9ad..ab594826d 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -220,8 +220,15 @@ std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (co return std::make_pair(x, y); } -void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data) +bool CSVRender::PagedWorldspaceWidget::handleDrop ( + const std::vector< CSMWorld::UniversalId >& data, DropType type) { + if (WorldspaceWidget::handleDrop (data, type)) + return true; + + if (type!=Type_CellsExterior) + return false; + bool selectionChanged = false; for (unsigned i = 0; i < data.size(); ++i) { @@ -238,10 +245,17 @@ void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld:: emit cellSelectionChanged(mSelection); } + + return true; } CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::DropType type) const { + dropRequirments requirements = WorldspaceWidget::getDropRequirements (type); + + if (requirements!=ignored) + return requirements; + switch (type) { case Type_CellsExterior: diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 90053265e..249c0c5fb 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -57,7 +57,9 @@ namespace CSVRender void setCellSelection (const CSMWorld::CellSelection& selection); - virtual void handleDrop(const std::vector& data); + /// \return Drop handled? + virtual bool handleDrop (const std::vector& data, + DropType type); virtual dropRequirments getDropRequirements(DropType type) const; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index a85134c29..7072c17a6 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -89,13 +89,21 @@ void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelI emit closeRequest(); } -void CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data) +bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector& data, DropType type) { + if (WorldspaceWidget::handleDrop (data, type)) + return true; + + if (type!=Type_CellsInterior) + return false; + mCellId = data.begin()->getId(); update(); emit cellChanged(*data.begin()); /// \todo replace mCell + + return true; } void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, @@ -168,6 +176,11 @@ std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::DropType type) const { + dropRequirments requirements = WorldspaceWidget::getDropRequirements (type); + + if (requirements!=ignored) + return requirements; + switch(type) { case Type_CellsInterior: diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index f604419d6..5924abaa9 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -43,7 +43,9 @@ namespace CSVRender virtual dropRequirments getDropRequirements(DropType type) const; - virtual void handleDrop(const std::vector& data); + /// \return Drop handled? + virtual bool handleDrop (const std::vector& data, + DropType type); private: diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 6f5b2410b..c95d2f51d 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -187,6 +187,18 @@ CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType ( return output; } +CSVRender::WorldspaceWidget::dropRequirments + CSVRender::WorldspaceWidget::getDropRequirements (DropType type) const +{ + return ignored; +} + +bool CSVRender::WorldspaceWidget::handleDrop (const std::vector& data, + DropType type) +{ + return false; +} + unsigned int CSVRender::WorldspaceWidget::getElementMask() const { return mSceneElements->getSelection(); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 99c56bd10..41d4964d0 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -70,12 +70,14 @@ namespace CSVRender static DropType getDropType(const std::vector& data); - virtual dropRequirments getDropRequirements(DropType type) const = 0; + virtual dropRequirments getDropRequirements(DropType type) const; virtual void useViewHint (const std::string& hint); ///< Default-implementation: ignored. - virtual void handleDrop(const std::vector& data) = 0; + /// \return Drop handled? + virtual bool handleDrop (const std::vector& data, + DropType type); virtual unsigned int getElementMask() const; diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 3afbbc805..52bd47b54 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -198,10 +198,12 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI CSVRender::UnpagedWorldspaceWidget* unPagedNewWidget = NULL; CSVWidget::SceneToolbar* toolbar = NULL; - switch (mScene->getDropRequirements(CSVRender::WorldspaceWidget::getDropType(data))) + CSVRender::WorldspaceWidget::DropType type = CSVRender::WorldspaceWidget::getDropType (data); + + switch (mScene->getDropRequirements (type)) { case CSVRender::WorldspaceWidget::canHandle: - mScene->handleDrop(data); + mScene->handleDrop (data, type); break; case CSVRender::WorldspaceWidget::needPaged: @@ -209,7 +211,7 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI toolbar = makeToolbar(pagedNewWidget, widget_Paged); makeConnections(pagedNewWidget); replaceToolbarAndWorldspace(pagedNewWidget, toolbar); - mScene->handleDrop(data); + mScene->handleDrop (data, type); break; case CSVRender::WorldspaceWidget::needUnpaged: From 717c1b15f548982349e19f018ce06fbc9d8981af Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 11 Sep 2014 13:07:28 +0200 Subject: [PATCH 49/55] fixed drop implementation for unpaged worldspace (wasn't updating cell object) --- apps/opencs/view/render/unpagedworldspacewidget.cpp | 4 ++-- apps/opencs/view/render/worldspacewidget.cpp | 5 +++++ apps/opencs/view/render/worldspacewidget.hpp | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 7072c17a6..aab3791fc 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -98,11 +98,11 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorgetId(); + mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId)); + update(); emit cellChanged(*data.begin()); - /// \todo replace mCell - return true; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index c95d2f51d..7f1d06c91 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -213,6 +213,11 @@ void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( tool->addButton (":armor.png", Element_Pathgrid, ":armor.png", "Pathgrid"); } +CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument() +{ + return mDocument; +} + void CSVRender::WorldspaceWidget::dragEnterEvent (QDragEnterEvent* event) { event->accept(); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 41d4964d0..e684b180f 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -85,6 +85,8 @@ namespace CSVRender virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle *tool); + CSMDoc::Document& getDocument(); + private: void dragEnterEvent(QDragEnterEvent *event); From 3ed2edb7cbba38865da070f4c6e8586671301251 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 13 Sep 2014 18:53:35 +0200 Subject: [PATCH 50/55] rewrote run tool profile management --- apps/opencs/view/widget/scenetoolrun.cpp | 66 +++++++++++++++++------- apps/opencs/view/widget/scenetoolrun.hpp | 12 +++-- 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/apps/opencs/view/widget/scenetoolrun.cpp b/apps/opencs/view/widget/scenetoolrun.cpp index f378725ae..92f3193fe 100644 --- a/apps/opencs/view/widget/scenetoolrun.cpp +++ b/apps/opencs/view/widget/scenetoolrun.cpp @@ -1,6 +1,8 @@ #include "scenetoolrun.hpp" +#include + #include #include #include @@ -11,11 +13,11 @@ void CSVWidget::SceneToolRun::adjustToolTips() { QString toolTip = mToolTip; - if (mCurrentIndex==-1) + if (mSelected==mProfiles.end()) toolTip += "

No debug profile selected (function disabled)"; else { - toolTip += "

Debug profile: " + QString::fromUtf8 (mProfiles[mCurrentIndex].c_str()); + toolTip += "

Debug profile: " + QString::fromUtf8 (mSelected->c_str()); toolTip += "

(right click to switch to a different profile)"; } @@ -24,16 +26,19 @@ void CSVWidget::SceneToolRun::adjustToolTips() void CSVWidget::SceneToolRun::updateIcon() { - setIcon (QIcon (mCurrentIndex==-1 ? mIconDisabled : mIcon)); + setIcon (QIcon (mSelected==mProfiles.end() ? mIconDisabled : mIcon)); } void CSVWidget::SceneToolRun::updatePanel() { mTable->setRowCount (mProfiles.size()); - for (int i=0; i (mProfiles.size()); ++i) + int i = 0; + + for (std::set::const_iterator iter (mProfiles.begin()); iter!=mProfiles.end(); + ++iter, ++i) { - mTable->setItem (i, 0, new QTableWidgetItem (QString::fromUtf8 (mProfiles[i].c_str()))); + mTable->setItem (i, 0, new QTableWidgetItem (QString::fromUtf8 (iter->c_str()))); mTable->setItem (i, 1, new QTableWidgetItem ( QApplication::style()->standardIcon (QStyle::SP_TitleBarCloseButton), "")); @@ -42,8 +47,8 @@ void CSVWidget::SceneToolRun::updatePanel() CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& toolTip, const QString& icon, const QString& iconDisabled, const std::vector& profiles) -: SceneTool (parent, Type_TopAction), mProfiles (profiles), - mCurrentIndex (profiles.empty() ? -1 : 0), mToolTip (toolTip), mIcon (icon), +: SceneTool (parent, Type_TopAction), mProfiles (profiles.begin(), profiles.end()), + mSelected (mProfiles.begin()), mToolTip (toolTip), mIcon (icon), mIconDisabled (iconDisabled) { updateIcon(); @@ -80,42 +85,67 @@ void CSVWidget::SceneToolRun::showPanel (const QPoint& position) void CSVWidget::SceneToolRun::activate() { - if (mCurrentIndex!=-1) - emit runRequest (mProfiles[mCurrentIndex]); + if (mSelected!=mProfiles.end()) + emit runRequest (*mSelected); } void CSVWidget::SceneToolRun::removeProfile (const std::string& profile) { - std::pair::iterator, std::vector::iterator> - result = std::equal_range (mProfiles.begin(), mProfiles.end(), profile); + std::set::iterator iter = mProfiles.find (profile); - if (result.first!=result.second) + if (iter!=mProfiles.end()) { - mProfiles.erase (result.first); + if (iter==mSelected) + { + if (iter!=mProfiles.begin()) + --mSelected; + else + ++mSelected; + } - if (mCurrentIndex>=static_cast (mProfiles.size())) - --mCurrentIndex; + mProfiles.erase (iter); - if (mCurrentIndex==-1) + if (mSelected==mProfiles.end()) updateIcon(); adjustToolTips(); } } +void CSVWidget::SceneToolRun::addProfile (const std::string& profile) +{ + std::set::iterator iter = mProfiles.find (profile); + + if (iter==mProfiles.end()) + { + mProfiles.insert (profile); + + if (mSelected==mProfiles.end()) + { + mSelected = mProfiles.begin(); + updateIcon(); + } + + adjustToolTips(); + } +} + void CSVWidget::SceneToolRun::clicked (const QModelIndex& index) { if (index.column()==0) { // select profile - mCurrentIndex = index.row(); + mSelected = mProfiles.begin(); + std::advance (mSelected, index.row()); mPanel->hide(); adjustToolTips(); } else if (index.column()==1) { // remove profile from list - removeProfile (mProfiles.at (index.row())); + std::set::iterator iter = mProfiles.begin(); + std::advance (iter, index.row()); + removeProfile (*iter); updatePanel(); } } \ No newline at end of file diff --git a/apps/opencs/view/widget/scenetoolrun.hpp b/apps/opencs/view/widget/scenetoolrun.hpp index 609ddcd34..4396c2288 100644 --- a/apps/opencs/view/widget/scenetoolrun.hpp +++ b/apps/opencs/view/widget/scenetoolrun.hpp @@ -1,7 +1,7 @@ #ifndef CSV_WIDGET_SCENETOOLRUN_H #define CSV_WIDGET_SCENETOOLRUN_H -#include +#include #include #include "scenetool.hpp" @@ -16,8 +16,8 @@ namespace CSVWidget { Q_OBJECT - std::vector mProfiles; - int mCurrentIndex; + std::set mProfiles; + std::set::iterator mSelected; QString mToolTip; QString mIcon; QString mIconDisabled; @@ -45,6 +45,12 @@ namespace CSVWidget /// panel. void removeProfile (const std::string& profile); + /// \attention This function doe not add the profile to the profile selection + /// panel. This only happens when the panel is re-opened. + /// + /// \note Adding profiles that are already listed is a no-op. + void addProfile (const std::string& profile); + private slots: void clicked (const QModelIndex& index); From 1254198d90b0e2f656c0e4971f36cbace417f8aa Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 13 Sep 2014 18:54:29 +0200 Subject: [PATCH 51/55] add debug profiles to scene subviews view drag and drop --- apps/opencs/view/render/worldspacewidget.cpp | 17 +++++++++++++++++ apps/opencs/view/render/worldspacewidget.hpp | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 7f1d06c91..fa304dd82 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -177,6 +177,8 @@ CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType ( { type = iter->getId().substr (0, 1)=="#" ? Type_CellsExterior : Type_CellsInterior; } + else if (iter->getType()==CSMWorld::UniversalId::Type_DebugProfile) + type = Type_DebugProfile; if (iter==data.begin()) output = type; @@ -190,12 +192,27 @@ CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType ( CSVRender::WorldspaceWidget::dropRequirments CSVRender::WorldspaceWidget::getDropRequirements (DropType type) const { + if (type==Type_DebugProfile) + return canHandle; + return ignored; } bool CSVRender::WorldspaceWidget::handleDrop (const std::vector& data, DropType type) { + if (type==Type_DebugProfile) + { + if (mRun) + { + for (std::vector::const_iterator iter (data.begin()); + iter!=data.end(); ++iter) + mRun->addProfile (iter->getId()); + } + + return true; + } + return false; } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index e684b180f..0754e9ecf 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -40,7 +40,8 @@ namespace CSVRender { Type_CellsInterior, Type_CellsExterior, - Type_Other + Type_Other, + Type_DebugProfile }; enum dropRequirments From 10fa205ced4e3beff9bd570f2834293041487ca3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 13 Sep 2014 20:41:57 +0200 Subject: [PATCH 52/55] fixed --data switch (was missing composing option) --- apps/opencs/editor.cpp | 2 +- apps/openmw/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 44d66b236..e8e2d9077 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -80,7 +80,7 @@ std::pair > CS::Editor::readConfi boost::program_options::options_description desc("Syntax: opencs \nAllowed options"); desc.add_options() - ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()) + ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()->composing()) ("data-local", boost::program_options::value()->default_value("")) ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) ("encoding", boost::program_options::value()->default_value("win1252")) diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index f81df31ff..ebadeb732 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -105,7 +105,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("help", "print help message") ("version", "print version information and quit") ("data", bpo::value()->default_value(Files::PathContainer(), "data") - ->multitoken(), "set data directories (later directories have higher priority)") + ->multitoken()->composing(), "set data directories (later directories have higher priority)") ("data-local", bpo::value()->default_value(""), "set local data directory (highest priority)") From 081588f484964dda0a134e800c19ba3461eb8545 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 13 Sep 2014 20:48:24 +0200 Subject: [PATCH 53/55] add project file to content file list when running OpenMW from OpenCS --- apps/opencs/model/doc/document.cpp | 3 ++- apps/opencs/model/doc/runner.cpp | 11 +++++++++-- apps/opencs/model/doc/runner.hpp | 5 ++++- apps/openmw/mwworld/esmstore.cpp | 8 +++++++- apps/openmw/mwworld/worldimp.cpp | 7 ++++--- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index ce216cfd6..5fe846ada 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2211,7 +2211,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, mTools (*this), mResDir(resDir), mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), - mSaving (*this, mProjectPath, encoding) + mSaving (*this, mProjectPath, encoding), + mRunner (mProjectPath) { if (mContentFiles.empty()) throw std::runtime_error ("Empty content file sequence"); diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index d97d5bb35..d473a7e7a 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -6,7 +6,8 @@ #include "operation.hpp" -CSMDoc::Runner::Runner() : mRunning (false), mStartup (0) +CSMDoc::Runner::Runner (const boost::filesystem::path& projectPath) +: mRunning (false), mStartup (0), mProjectPath (projectPath) { connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (finished (int, QProcess::ExitStatus))); @@ -73,7 +74,10 @@ void CSMDoc::Runner::start (bool delayed) else arguments << "--new-game=1"; - arguments << ("--script-run="+mStartup->fileName()); + arguments << ("--script-run="+mStartup->fileName());; + + arguments << + QString::fromUtf8 (("--data="+mProjectPath.parent_path().string()).c_str()); for (std::vector::const_iterator iter (mContentFiles.begin()); iter!=mContentFiles.end(); ++iter) @@ -81,6 +85,9 @@ void CSMDoc::Runner::start (bool delayed) arguments << QString::fromUtf8 (("--content="+*iter).c_str()); } + arguments + << QString::fromUtf8 (("--content="+mProjectPath.filename().string()).c_str()); + mProcess.start (path, arguments); } diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index 1505a96dc..38b52a73b 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -4,6 +4,8 @@ #include #include +#include + #include #include #include @@ -25,10 +27,11 @@ namespace CSMDoc std::string mStartupInstruction; QTemporaryFile *mStartup; QTextDocument mLog; + boost::filesystem::path mProjectPath; public: - Runner(); + Runner (const boost::filesystem::path& projectPath); ~Runner(); diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 12831e7dc..1b5d3d1e9 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -81,7 +81,13 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener) mMagicEffects.load (esm); } else if (n.val == ESM::REC_SKIL) { mSkills.load (esm); - } else { + } + else if (n.val==ESM::REC_FILT || ESM::REC_DBGP) + { + // ignore project file only records + esm.skipRecord(); + } + else { std::stringstream error; error << "Unknown record: " << n.toString(); throw std::runtime_error(error.str()); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a84e4781d..6c1920a22 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -174,8 +174,9 @@ namespace MWWorld gameContentLoader.addLoader(".esm", &esmLoader); gameContentLoader.addLoader(".esp", &esmLoader); - gameContentLoader.addLoader(".omwgame", &omwLoader); - gameContentLoader.addLoader(".omwaddon", &omwLoader); + gameContentLoader.addLoader(".omwgame", &esmLoader); + gameContentLoader.addLoader(".omwaddon", &esmLoader); + gameContentLoader.addLoader(".project", &esmLoader); loadContentFiles(fileCollections, contentFiles, gameContentLoader); @@ -2435,7 +2436,7 @@ namespace MWWorld if (!selectedSpell.empty()) { const ESM::Spell* spell = getStore().get().search(selectedSpell); - + // A power can be used once per 24h if (spell->mData.mType == ESM::Spell::ST_Power) stats.getSpells().usePower(spell->mId); From 89000f61965d220fee9e5df8904bb07c8b4b44f3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 14 Sep 2014 11:28:28 +0200 Subject: [PATCH 54/55] removed unused OmwLoader --- apps/openmw/CMakeLists.txt | 10 +++++----- apps/openmw/mwworld/omwloader.cpp | 17 ----------------- apps/openmw/mwworld/omwloader.hpp | 21 --------------------- apps/openmw/mwworld/worldimp.cpp | 2 -- 4 files changed, 5 insertions(+), 45 deletions(-) delete mode 100644 apps/openmw/mwworld/omwloader.cpp delete mode 100644 apps/openmw/mwworld/omwloader.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 6df6210ee..d9a0d318f 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -65,7 +65,7 @@ add_openmw_dir (mwworld cells localscripts customdata weather inventorystore ptr actionopen actionread actionequip timestamp actionalchemy cellstore actionapply actioneat esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor - contentloader esmloader omwloader actiontrap cellreflist projectilemanager cellref + contentloader esmloader actiontrap cellreflist projectilemanager cellref ) add_openmw_dir (mwclass @@ -110,7 +110,7 @@ if (NOT ANDROID) ${APPLE_BUNDLE_RESOURCES} ) else () - add_library(openmw + add_library(openmw SHARED ${OPENMW_LIBS} ${OPENMW_LIBS_HEADER} ${OPENMW_FILES} @@ -140,18 +140,18 @@ target_link_libraries(openmw if (ANDROID) target_link_libraries(openmw - ${OGRE_STATIC_PLUGINS} + ${OGRE_STATIC_PLUGINS} EGL android log - dl + dl MyGUI.OgrePlatform MyGUIEngineStatic Plugin_StrangeButtonStatic cpufeatures BulletCollision BulletDynamics - LinearMath + LinearMath ) endif (ANDROID) diff --git a/apps/openmw/mwworld/omwloader.cpp b/apps/openmw/mwworld/omwloader.cpp deleted file mode 100644 index 8562a4fe0..000000000 --- a/apps/openmw/mwworld/omwloader.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "omwloader.hpp" - -namespace MWWorld -{ - -OmwLoader::OmwLoader(Loading::Listener& listener) - : ContentLoader(listener) -{ -} - -void OmwLoader::load(const boost::filesystem::path& filepath, int& index) -{ - ContentLoader::load(filepath.filename(), index); -} - -} /* namespace MWWorld */ - diff --git a/apps/openmw/mwworld/omwloader.hpp b/apps/openmw/mwworld/omwloader.hpp deleted file mode 100644 index cb9faa430..000000000 --- a/apps/openmw/mwworld/omwloader.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef OMWLOADER_HPP -#define OMWLOADER_HPP - -#include "contentloader.hpp" - -namespace MWWorld -{ - -/** - * @brief Placeholder for real OpenMW content loader - */ -struct OmwLoader : public ContentLoader -{ - OmwLoader(Loading::Listener& listener); - - void load(const boost::filesystem::path& filepath, int& index); -}; - -} /* namespace MWWorld */ - -#endif /* OMWLOADER_HPP */ diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6c1920a22..b78161163 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -51,7 +51,6 @@ #include "contentloader.hpp" #include "esmloader.hpp" -#include "omwloader.hpp" using namespace Ogre; @@ -170,7 +169,6 @@ namespace MWWorld GameContentLoader gameContentLoader(*listener); EsmLoader esmLoader(mStore, mEsm, encoder, *listener); - OmwLoader omwLoader(*listener); gameContentLoader.addLoader(".esm", &esmLoader); gameContentLoader.addLoader(".esp", &esmLoader); From bf6150d009f69809737cbfed7c5f76b1f1ec7780 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 14 Sep 2014 11:41:28 +0200 Subject: [PATCH 55/55] allow project scope scripts --- apps/opencs/model/doc/saving.cpp | 3 +++ apps/opencs/view/world/subviews.cpp | 8 ++++++-- components/esm/loadscpt.cpp | 6 +++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index d587ef3af..9c6932941 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -23,6 +23,9 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteCollectionStage > ( mDocument.getData().getDebugProfiles(), mState, CSMWorld::Scope_Project)); + appendStage (new WriteCollectionStage > ( + mDocument.getData().getScripts(), mState, CSMWorld::Scope_Project)); + appendStage (new CloseSaveStage (mState)); // save content file diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 1ab995343..f86aa34ff 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -33,7 +33,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Factions, CSMWorld::UniversalId::Type_Races, CSMWorld::UniversalId::Type_Sounds, - CSMWorld::UniversalId::Type_Scripts, CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, @@ -89,6 +88,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) // Other stuff (combined record tables) manager.add (CSMWorld::UniversalId::Type_RegionMap, new CSVDoc::SubViewFactory); + manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); + + // More other stuff manager.add (CSMWorld::UniversalId::Type_Filters, new CSVDoc::SubViewFactoryWithCreator >); @@ -97,7 +99,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator >); - manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); + manager.add (CSMWorld::UniversalId::Type_Scripts, + new CSVDoc::SubViewFactoryWithCreator >); // Dialogue subviews static const CSMWorld::UniversalId::Type sTableTypes2[] = diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp index 2e8f31cd2..d7303aaaf 100644 --- a/components/esm/loadscpt.cpp +++ b/components/esm/loadscpt.cpp @@ -110,7 +110,11 @@ void Script::save(ESMWriter &esm) const mVarNames.clear(); mScriptData.clear(); - mScriptText = "Begin " + mId + "\n\nEnd " + mId + "\n"; + + if (mId.find ("::")!=std::string::npos) + mScriptText = "Begin \"" + mId + "\"\n\nEnd " + mId + "\n"; + else + mScriptText = "Begin " + mId + "\n\nEnd " + mId + "\n"; } }