From ba6edc55d457f62c9f85850f48278ee49d787187 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 13:45:50 +0200 Subject: [PATCH] added not filter node --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/filter/notnode.cpp | 10 ++++++++++ apps/opencs/model/filter/notnode.hpp | 21 +++++++++++++++++++++ apps/opencs/model/filter/parser.cpp | 24 ++++++++++++++++-------- apps/opencs/model/filter/parser.hpp | 2 +- apps/opencs/model/filter/unarynode.cpp | 8 +++++++- apps/opencs/model/filter/unarynode.hpp | 11 ++++++++--- 7 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 apps/opencs/model/filter/notnode.cpp create mode 100644 apps/opencs/model/filter/notnode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 9fb6c1be3e..c74f0db22c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -108,7 +108,7 @@ opencs_units_noqt (model/settings ) opencs_units_noqt (model/filter - node unarynode narynode leafnode booleannode parser andnode ornode + node unarynode narynode leafnode booleannode parser andnode ornode notnode ) opencs_hdrs_noqt (model/filter diff --git a/apps/opencs/model/filter/notnode.cpp b/apps/opencs/model/filter/notnode.cpp new file mode 100644 index 0000000000..1b22ea7a6a --- /dev/null +++ b/apps/opencs/model/filter/notnode.cpp @@ -0,0 +1,10 @@ + +#include "notnode.hpp" + +CSMFilter::NotNode::NotNode (boost::shared_ptr child) : UnaryNode (child, "not") {} + +bool CSMFilter::NotNode::test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const +{ + return !getChild().test (table, row, columns); +} \ No newline at end of file diff --git a/apps/opencs/model/filter/notnode.hpp b/apps/opencs/model/filter/notnode.hpp new file mode 100644 index 0000000000..b9e80b8c6d --- /dev/null +++ b/apps/opencs/model/filter/notnode.hpp @@ -0,0 +1,21 @@ +#ifndef CSM_FILTER_NOTNODE_H +#define CSM_FILTER_NOTNODE_H + +#include "unarynode.hpp" + +namespace CSMFilter +{ + class NotNode : public UnaryNode + { + public: + + NotNode (boost::shared_ptr child); + + virtual bool test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + }; +} + +#endif diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index a35c4bdfdf..5dd0392e8c 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -10,6 +10,7 @@ #include "booleannode.hpp" #include "ornode.hpp" #include "andnode.hpp" +#include "notnode.hpp" namespace CSMFilter { @@ -209,7 +210,7 @@ CSMFilter::Token CSMFilter::Parser::getNextToken() return Token (Token::Type_None); } -boost::shared_ptr CSMFilter::Parser::parseImp() +boost::shared_ptr CSMFilter::Parser::parseImp (bool allowEmpty) { if (Token token = getNextToken()) { @@ -228,8 +229,21 @@ boost::shared_ptr CSMFilter::Parser::parseImp() return parseNAry (token); + case Token::Type_Keyword_Not: + { + boost::shared_ptr node = parseImp(); + + if (mError) + return boost::shared_ptr(); + + return boost::shared_ptr (new NotNode (node)); + } + case Token::Type_EOS: + if (!allowEmpty) + error(); + return boost::shared_ptr(); default: @@ -260,12 +274,6 @@ boost::shared_ptr CSMFilter::Parser::parseNAry (const Token& ke if (mError) return boost::shared_ptr(); - if (!node.get()) - { - error(); - return boost::shared_ptr(); - } - nodes.push_back (node); Token token = getNextToken(); @@ -309,7 +317,7 @@ bool CSMFilter::Parser::parse (const std::string& filter) mInput = filter; mIndex = 0; - boost::shared_ptr node = parseImp(); + boost::shared_ptr node = parseImp (true); if (mError) return false; diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index d9f14b5d9a..13c77b09a5 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -25,7 +25,7 @@ namespace CSMFilter Token checkKeywords (const Token& token); ///< Turn string token into keyword token, if possible. - boost::shared_ptr parseImp(); + boost::shared_ptr parseImp (bool allowEmpty = false); ///< Will return a null-pointer, if there is nothing more to parse. boost::shared_ptr parseNAry (const Token& keyword); diff --git a/apps/opencs/model/filter/unarynode.cpp b/apps/opencs/model/filter/unarynode.cpp index d687b6468d..d1897f4b7a 100644 --- a/apps/opencs/model/filter/unarynode.cpp +++ b/apps/opencs/model/filter/unarynode.cpp @@ -1,7 +1,9 @@ #include "unarynode.hpp" -CSMFilter::UnaryNode::UnaryNode (boost::shared_ptr child) : mChild (child) {} +CSMFilter::UnaryNode::UnaryNode (boost::shared_ptr child, const std::string& name) +: mChild (child), mName (name) +{} const CSMFilter::Node& CSMFilter::UnaryNode::getChild() const { @@ -23,3 +25,7 @@ bool CSMFilter::UnaryNode::isSimple() const return false; } +std::string CSMFilter::UnaryNode::toString (bool numericColumns) const +{ + return mName + " " + mChild->toString (numericColumns); +} \ No newline at end of file diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp index 6483a730f4..9fd5faf3f7 100644 --- a/apps/opencs/model/filter/unarynode.hpp +++ b/apps/opencs/model/filter/unarynode.hpp @@ -1,5 +1,5 @@ -#ifndef CSM_FILTER_UNARIYNODE_H -#define CSM_FILTER_UNARIYNODE_H +#ifndef CSM_FILTER_UNARYNODE_H +#define CSM_FILTER_UNARYNODE_H #include @@ -10,10 +10,11 @@ namespace CSMFilter class UnaryNode : public Node { boost::shared_ptr mChild; + std::string mName; public: - UnaryNode (boost::shared_ptr child); + UnaryNode (boost::shared_ptr child, const std::string& name); const Node& getChild() const; @@ -26,6 +27,10 @@ namespace CSMFilter virtual bool isSimple() const; ///< \return Can this filter be displayed in simple mode. + virtual std::string toString (bool numericColumns) const; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. }; }