From 25e6380884f4b9e9495516506c90975a68910e9a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 24 Aug 2013 17:40:00 +0200 Subject: [PATCH] implemented use of predefined filters --- apps/opencs/model/filter/parser.cpp | 67 +++++++++++++++++++++++------ apps/opencs/model/filter/parser.hpp | 2 +- apps/opencs/model/world/data.cpp | 10 +++++ apps/opencs/model/world/data.hpp | 4 ++ 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index 2cf882f2df..b800faa1e1 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -8,6 +8,8 @@ #include #include "../world/columns.hpp" +#include "../world/data.hpp" +#include "../world/idcollection.hpp" #include "booleannode.hpp" #include "ornode.hpp" @@ -31,6 +33,7 @@ namespace CSMFilter Type_OpenSquare, Type_CloseSquare, Type_Comma, + Type_OneShot, Type_Keyword_True, ///< \attention Keyword enums must be arranged continuously. Type_Keyword_False, Type_Keyword_And, @@ -208,6 +211,7 @@ CSMFilter::Token CSMFilter::Parser::getNextToken() case '[': ++mIndex; return Token (Token::Type_OpenSquare); case ']': ++mIndex; return Token (Token::Type_CloseSquare); case ',': ++mIndex; return Token (Token::Type_Comma); + case '?': ++mIndex; return Token (Token::Type_OneShot); } if (c=='"' || c=='_' || std::isalpha (c)) @@ -509,7 +513,7 @@ void CSMFilter::Parser::error() CSMFilter::Parser::Parser (const CSMWorld::Data& data) : mIndex (0), mError (false), mData (data) {} -bool CSMFilter::Parser::parse (const std::string& filter) +bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined) { // reset mFilter.reset(); @@ -517,23 +521,62 @@ bool CSMFilter::Parser::parse (const std::string& filter) mInput = filter; mIndex = 0; - boost::shared_ptr node = parseImp (true); + Token token = getNextToken(); - if (mError) - return false; + if (token==Token (Token::Type_OneShot)) + { + boost::shared_ptr node = parseImp (true); - if (getNextToken()!=Token (Token::Type_EOS)) - return false; + if (mError) + return false; - if (node) - mFilter = node; + if (getNextToken()!=Token (Token::Type_EOS)) + { + error(); + return false; + } + + if (node) + mFilter = node; + else + { + // Empty filter string equals to filter "true". + mFilter.reset (new BooleanNode (true)); + } + + return true; + } + else if (token.mType==Token::Type_String && allowPredefined) + { + if (getNextToken()!=Token (Token::Type_EOS)) + { + error(); + return false; + } + + int index = mData.getFilters().searchId (token.mString); + + if (index==-1) + { + error(); + return false; + } + + const CSMWorld::Record& record = mData.getFilters().getRecord (index); + + if (record.isDeleted()) + { + error(); + return false; + } + + return parse (record.get().mFilter, false); + } else { - // Empty filter string equals to filter "true". - mFilter.reset (new BooleanNode (true)); + error(); + return false; } - - return true; } boost::shared_ptr CSMFilter::Parser::getFilter() const diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index c26168611d..fbaf6972e2 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -46,7 +46,7 @@ namespace CSMFilter Parser (const CSMWorld::Data& data); - bool parse (const std::string& filter); + bool parse (const std::string& filter, bool allowPredefined = true); ///< Discards any previous calls to parse /// /// \return Success? diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 4a5dcb38fb..b9f6d17186 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -316,6 +316,16 @@ CSMWorld::RefCollection& CSMWorld::Data::getReferences() return mRefs; } +const CSMWorld::IdCollection& CSMWorld::Data::getFilters() const +{ + return mFilters; +} + +CSMWorld::IdCollection& CSMWorld::Data::getFilters() +{ + return mFilters; +} + 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 aebdd6ecda..2f8a2117e0 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -119,6 +119,10 @@ namespace CSMWorld RefCollection& getReferences(); + const IdCollection& getFilters() const; + + IdCollection& getFilters(); + QAbstractItemModel *getTableModel (const UniversalId& id); ///< If no table model is available for \a id, an exception is thrown. ///