mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-30 00:06:42 +00:00
added numeric value filter node
This commit is contained in:
parent
537ab38985
commit
3cf60da5a7
5 changed files with 236 additions and 3 deletions
|
@ -108,7 +108,7 @@ opencs_units_noqt (model/settings
|
|||
)
|
||||
|
||||
opencs_units_noqt (model/filter
|
||||
node unarynode narynode leafnode booleannode parser andnode ornode notnode textnode
|
||||
node unarynode narynode leafnode booleannode parser andnode ornode notnode textnode valuenode
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/filter
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "andnode.hpp"
|
||||
#include "notnode.hpp"
|
||||
#include "textnode.hpp"
|
||||
#include "valuenode.hpp"
|
||||
|
||||
namespace CSMFilter
|
||||
{
|
||||
|
@ -35,7 +36,8 @@ namespace CSMFilter
|
|||
Type_Keyword_And,
|
||||
Type_Keyword_Or,
|
||||
Type_Keyword_Not,
|
||||
Type_Keyword_Text
|
||||
Type_Keyword_Text,
|
||||
Type_Keyword_Value
|
||||
};
|
||||
|
||||
Type mType;
|
||||
|
@ -169,7 +171,7 @@ CSMFilter::Token CSMFilter::Parser::checkKeywords (const Token& token)
|
|||
{
|
||||
"true", "false",
|
||||
"and", "or", "not",
|
||||
"text",
|
||||
"text", "value",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -251,6 +253,10 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseImp (bool allowEmpty)
|
|||
|
||||
return parseText();
|
||||
|
||||
case Token::Type_Keyword_Value:
|
||||
|
||||
return parseValue();
|
||||
|
||||
case Token::Type_EOS:
|
||||
|
||||
if (!allowEmpty)
|
||||
|
@ -378,6 +384,123 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseText()
|
|||
return boost::shared_ptr<Node> (new TextNode (columnId, text));
|
||||
}
|
||||
|
||||
boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseValue()
|
||||
{
|
||||
Token token = getNextToken();
|
||||
|
||||
if (token.mType!=Token::Type_Open)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (!token)
|
||||
return boost::shared_ptr<Node>();
|
||||
|
||||
// parse column ID
|
||||
int columnId = -1;
|
||||
|
||||
if (token.mType==Token::Type_Number)
|
||||
{
|
||||
if (static_cast<int> (token.mNumber)==token.mNumber)
|
||||
columnId = static_cast<int> (token.mNumber);
|
||||
}
|
||||
else if (token.mType==Token::Type_String)
|
||||
{
|
||||
columnId = CSMWorld::Columns::getId (token.mString);
|
||||
}
|
||||
|
||||
if (columnId<0)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (token.mType!=Token::Type_Comma)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
// parse value
|
||||
double lower = 0;
|
||||
double upper = 0;
|
||||
bool min = false;
|
||||
bool max = false;
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (token.mType==Token::Type_Number)
|
||||
{
|
||||
// single value
|
||||
min = max = true;
|
||||
lower = upper = token.mNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
// interval
|
||||
if (token.mType==Token::Type_OpenSquare)
|
||||
min = true;
|
||||
else if (token.mType!=Token::Type_CloseSquare && token.mType!=Token::Type_Open)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (token.mType!=Token::Type_Number)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
lower = token.mNumber;
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (token.mType!=Token::Type_Comma)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (token.mType!=Token::Type_Number)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
upper = token.mNumber;
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (token.mType==Token::Type_CloseSquare)
|
||||
max = true;
|
||||
else if (token.mType!=Token::Type_OpenSquare && token.mType!=Token::Type_Close)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
}
|
||||
|
||||
token = getNextToken();
|
||||
|
||||
if (token.mType!=Token::Type_Close)
|
||||
{
|
||||
error();
|
||||
return boost::shared_ptr<Node>();
|
||||
}
|
||||
|
||||
return boost::shared_ptr<Node> (new ValueNode (columnId, lower, upper, min, max));
|
||||
}
|
||||
|
||||
void CSMFilter::Parser::error()
|
||||
{
|
||||
mError = true;
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace CSMFilter
|
|||
|
||||
boost::shared_ptr<Node> parseText();
|
||||
|
||||
boost::shared_ptr<Node> parseValue();
|
||||
|
||||
void error();
|
||||
|
||||
public:
|
||||
|
|
71
apps/opencs/model/filter/valuenode.cpp
Normal file
71
apps/opencs/model/filter/valuenode.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
|
||||
#include "valuenode.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../world/columns.hpp"
|
||||
#include "../world/idtable.hpp"
|
||||
|
||||
CSMFilter::ValueNode::ValueNode (int columnId,
|
||||
double lower, double upper, bool min, bool max)
|
||||
: mColumnId (columnId), mLower (lower), mUpper (upper), mMin (min), mMax (max)
|
||||
{}
|
||||
|
||||
bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
|
||||
const std::map<int, int>& columns) const
|
||||
{
|
||||
const std::map<int, int>::const_iterator iter = columns.find (mColumnId);
|
||||
|
||||
if (iter==columns.end())
|
||||
throw std::logic_error ("invalid column in test value test");
|
||||
|
||||
if (iter->second==-1)
|
||||
return true;
|
||||
|
||||
QModelIndex index = table.index (row, iter->second);
|
||||
|
||||
QVariant data = table.data (index);
|
||||
|
||||
if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int &&
|
||||
data.type()!=QVariant::UInt)
|
||||
return false;
|
||||
|
||||
double value = data.toDouble();
|
||||
|
||||
if (mLower==mUpper && mMin && mMax)
|
||||
return value==mLower;
|
||||
|
||||
return (mMin ? value>=mLower : value>mLower) && (mMax ? value<=mUpper : value<mUpper);
|
||||
}
|
||||
|
||||
std::vector<int> CSMFilter::ValueNode::getReferencedColumns() const
|
||||
{
|
||||
return std::vector<int> (1, mColumnId);
|
||||
}
|
||||
|
||||
std::string CSMFilter::ValueNode::toString (bool numericColumns) const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << "value (";
|
||||
|
||||
if (numericColumns)
|
||||
stream << mColumnId;
|
||||
else
|
||||
stream
|
||||
<< "\""
|
||||
<< CSMWorld::Columns::getName (static_cast<CSMWorld::Columns::ColumnId> (mColumnId))
|
||||
<< "\"";
|
||||
|
||||
stream << ", \"";
|
||||
|
||||
if (mLower==mUpper && mMin && mMax)
|
||||
stream << mLower;
|
||||
else
|
||||
stream << (mMin ? "[" : "(") << mLower << ", " << mUpper << (mMax ? "]" : ")");
|
||||
|
||||
stream << ")";
|
||||
|
||||
return stream.str();
|
||||
}
|
37
apps/opencs/model/filter/valuenode.hpp
Normal file
37
apps/opencs/model/filter/valuenode.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef CSM_FILTER_VALUENODE_H
|
||||
#define CSM_FILTER_VALUENODE_H
|
||||
|
||||
#include "leafnode.hpp"
|
||||
|
||||
namespace CSMFilter
|
||||
{
|
||||
class ValueNode : public LeafNode
|
||||
{
|
||||
int mColumnId;
|
||||
std::string mText;
|
||||
double mLower;
|
||||
double mUpper;
|
||||
bool mMin;
|
||||
bool mMax;
|
||||
|
||||
public:
|
||||
|
||||
ValueNode (int columnId, double lower, double upper, bool min, bool max);
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
const std::map<int, int>& columns) const;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
||||
virtual std::vector<int> getReferencedColumns() const;
|
||||
///< Return a list of the IDs of the columns referenced by this node. The column mapping
|
||||
/// passed into test as columns must contain all columns listed here.
|
||||
|
||||
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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue