From 102700a49879388b6850cdcadabfc51bb1caa177 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 30 Jul 2013 12:53:03 +0200 Subject: [PATCH] added specialised Creator for references --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/commands.cpp | 8 +++ apps/opencs/model/world/commands.hpp | 4 ++ apps/opencs/model/world/data.cpp | 10 +++ apps/opencs/model/world/data.hpp | 4 ++ apps/opencs/model/world/refcollection.cpp | 12 ++-- apps/opencs/model/world/refcollection.hpp | 2 + apps/opencs/view/world/genericcreator.cpp | 10 +++ apps/opencs/view/world/genericcreator.hpp | 4 ++ apps/opencs/view/world/referencecreator.cpp | 70 +++++++++++++++++++++ apps/opencs/view/world/referencecreator.hpp | 40 ++++++++++++ apps/opencs/view/world/subviews.cpp | 9 ++- 12 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/view/world/referencecreator.cpp create mode 100644 apps/opencs/view/world/referencecreator.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 75258a175..6da863b97 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -58,7 +58,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator - cellcreator referenceablecreator + cellcreator referenceablecreator referencecreator ) opencs_units_noqt (view/world diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 9281e6e33..43ecaca63 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -31,6 +31,11 @@ CSMWorld::CreateCommand::CreateCommand (IdTable& model, const std::string& id, Q setText (("Create record " + id).c_str()); } +void CSMWorld::CreateCommand::addValue (int column, const QVariant& value) +{ + mValues[column] = value; +} + void CSMWorld::CreateCommand::setType (UniversalId::Type type) { mType = type; @@ -39,6 +44,9 @@ void CSMWorld::CreateCommand::setType (UniversalId::Type type) void CSMWorld::CreateCommand::redo() { mModel.addRecord (mId, mType); + + for (std::map::const_iterator iter (mValues.begin()); iter!=mValues.end(); ++iter) + mModel.setData (mModel.getModelIndex (mId, iter->first), iter->second); } void CSMWorld::CreateCommand::undo() diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 6272c3fb7..3fc2522ea 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -4,6 +4,7 @@ #include "record.hpp" #include +#include #include #include @@ -42,6 +43,7 @@ namespace CSMWorld IdTable& mModel; std::string mId; UniversalId::Type mType; + std::map mValues; public: @@ -49,6 +51,8 @@ namespace CSMWorld void setType (UniversalId::Type type); + void addValue (int column, const QVariant& value); + virtual void redo(); virtual void undo(); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 2a95dfafe..594bc19c2 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -300,6 +300,16 @@ CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables() return mReferenceables; } +const CSMWorld::RefCollection& CSMWorld::Data::getReferences() const +{ + return mRefs; +} + +CSMWorld::RefCollection& CSMWorld::Data::getReferences() +{ + return mRefs; +} + QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id) { std::map::iterator iter = mModelIndex.find (id.getType()); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 10a1fe50d..8b2403db3 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -112,6 +112,10 @@ namespace CSMWorld RefIdCollection& getReferenceables(); + const RefCollection& getReferences() const; + + RefCollection& getReferences(); + QAbstractItemModel *getTableModel (const UniversalId& id); ///< If no table model is available for \a id, an exception is thrown. /// diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 6a1e8045b..085817753 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -21,10 +21,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool while (cell2.getNextRef (reader, ref)) { /// \todo handle deleted and moved references - std::ostringstream stream; - stream << "ref#" << mNextId++; - - ref.load (reader, cell2, stream.str()); + ref.load (reader, cell2, getNewId()); Record record2; record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; @@ -34,4 +31,11 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool } mCells.setRecord (cellIndex, cell); +} + +std::string CSMWorld::RefCollection::getNewId() +{ + std::ostringstream stream; + stream << "ref#" << mNextId++; + return stream.str(); } \ No newline at end of file diff --git a/apps/opencs/model/world/refcollection.hpp b/apps/opencs/model/world/refcollection.hpp index a2063590b..895315a17 100644 --- a/apps/opencs/model/world/refcollection.hpp +++ b/apps/opencs/model/world/refcollection.hpp @@ -21,6 +21,8 @@ namespace CSMWorld void load (ESM::ESMReader& reader, int cellIndex, bool base); ///< Load a sequence of references. + + std::string getNewId(); }; } diff --git a/apps/opencs/view/world/genericcreator.cpp b/apps/opencs/view/world/genericcreator.cpp index 6c402818c..7502b6555 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -46,6 +46,16 @@ std::string CSVWorld::GenericCreator::getId() const void CSVWorld::GenericCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const {} +const CSMWorld::Data& CSVWorld::GenericCreator::getData() const +{ + return mData; +} + +CSMWorld::Data& CSVWorld::GenericCreator::getData() +{ + return mData; +} + CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) : mData (data), mUndoStack (undoStack), mListId (id), mLocked (false) diff --git a/apps/opencs/view/world/genericcreator.hpp b/apps/opencs/view/world/genericcreator.hpp index 9022b7e39..5409f0839 100644 --- a/apps/opencs/view/world/genericcreator.hpp +++ b/apps/opencs/view/world/genericcreator.hpp @@ -44,6 +44,10 @@ namespace CSVWorld virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + const CSMWorld::Data& getData() const; + + CSMWorld::Data& getData(); + public: GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, diff --git a/apps/opencs/view/world/referencecreator.cpp b/apps/opencs/view/world/referencecreator.cpp new file mode 100644 index 000000000..48a168a35 --- /dev/null +++ b/apps/opencs/view/world/referencecreator.cpp @@ -0,0 +1,70 @@ + +#include "referencecreator.hpp" + +#include +#include + +#include "../../model/world/data.hpp" +#include "../../model/world/commands.hpp" + +std::string CSVWorld::ReferenceCreator::getId() const +{ + return mId; +} + +void CSVWorld::ReferenceCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const +{ + /// \todo avoid using hard-coded column numbers + command.addValue (2, mCell->text()); +} + +CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id) +: GenericCreator (data, undoStack, id) +{ + QLabel *label = new QLabel ("Cell", this); + insertBeforeButtons (label, false); + + mCell = new QLineEdit (this); + insertBeforeButtons (mCell, true); + + setManualEditing (false); + + connect (mCell, SIGNAL (textChanged (const QString&)), this, SLOT (cellChanged())); +} + +void CSVWorld::ReferenceCreator::reset() +{ + mCell->setText (""); + mId = getData().getReferences().getNewId(); + GenericCreator::reset(); +} + +std::string CSVWorld::ReferenceCreator::getErrors() const +{ + std::string errors = GenericCreator::getErrors(); + + std::string cell = mCell->text().toUtf8().constData(); + + if (cell.empty()) + { + if (!errors.empty()) + errors += "
"; + + errors += "Missing Cell ID"; + } + else if (getData().getCells().searchId (cell)==-1) + { + if (!errors.empty()) + errors += "
"; + + errors += "Invalid Cell ID"; + } + + return errors; +} + +void CSVWorld::ReferenceCreator::cellChanged() +{ + update(); +} \ No newline at end of file diff --git a/apps/opencs/view/world/referencecreator.hpp b/apps/opencs/view/world/referencecreator.hpp new file mode 100644 index 000000000..27f81564f --- /dev/null +++ b/apps/opencs/view/world/referencecreator.hpp @@ -0,0 +1,40 @@ +#ifndef CSV_WORLD_REFERENCECREATOR_H +#define CSV_WORLD_REFERENCECREATOR_H + +#include "genericcreator.hpp" + +class QLineEdit; + +namespace CSVWorld +{ + class ReferenceCreator : public GenericCreator + { + Q_OBJECT + + QLineEdit *mCell; + std::string mId; + + private: + + virtual std::string getId() const; + + virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + + public: + + ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id); + + virtual void reset(); + + 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. + + private slots: + + void cellChanged(); + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 22eb0ea4c..8990e2c72 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -10,9 +10,12 @@ #include "genericcreator.hpp" #include "cellcreator.hpp" #include "referenceablecreator.hpp" +#include "referencecreator.hpp" void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) { + // Regular record tables (including references which are actually sub-records, but are promoted + // to top-level records within the editor) manager.add (CSMWorld::UniversalId::Type_Gmsts, new CSVDoc::SubViewFactoryWithCreator); @@ -30,7 +33,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, - CSMWorld::UniversalId::Type_References, CSMWorld::UniversalId::Type_None // end marker }; @@ -45,7 +47,12 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Referenceables, new CSVDoc::SubViewFactoryWithCreator >); + manager.add (CSMWorld::UniversalId::Type_References, + new CSVDoc::SubViewFactoryWithCreator >); + + // Subviews for editing/viewing individual records manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory); + // Other stuff (combined record tables) manager.add (CSMWorld::UniversalId::Type_RegionMap, new CSVDoc::SubViewFactory); } \ No newline at end of file