mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 10:53:51 +00:00
added text filter node
This commit is contained in:
parent
decd826208
commit
de956737fe
5 changed files with 172 additions and 3 deletions
|
@ -108,7 +108,7 @@ opencs_units_noqt (model/settings
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (model/filter
|
opencs_units_noqt (model/filter
|
||||||
node unarynode narynode leafnode booleannode parser andnode ornode notnode
|
node unarynode narynode leafnode booleannode parser andnode ornode notnode textnode
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/filter
|
opencs_hdrs_noqt (model/filter
|
||||||
|
|
|
@ -7,10 +7,13 @@
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "../world/columns.hpp"
|
||||||
|
|
||||||
#include "booleannode.hpp"
|
#include "booleannode.hpp"
|
||||||
#include "ornode.hpp"
|
#include "ornode.hpp"
|
||||||
#include "andnode.hpp"
|
#include "andnode.hpp"
|
||||||
#include "notnode.hpp"
|
#include "notnode.hpp"
|
||||||
|
#include "textnode.hpp"
|
||||||
|
|
||||||
namespace CSMFilter
|
namespace CSMFilter
|
||||||
{
|
{
|
||||||
|
@ -31,7 +34,8 @@ namespace CSMFilter
|
||||||
Type_Keyword_False,
|
Type_Keyword_False,
|
||||||
Type_Keyword_And,
|
Type_Keyword_And,
|
||||||
Type_Keyword_Or,
|
Type_Keyword_Or,
|
||||||
Type_Keyword_Not
|
Type_Keyword_Not,
|
||||||
|
Type_Keyword_Text
|
||||||
};
|
};
|
||||||
|
|
||||||
Type mType;
|
Type mType;
|
||||||
|
@ -162,6 +166,7 @@ CSMFilter::Token CSMFilter::Parser::checkKeywords (const Token& token)
|
||||||
{
|
{
|
||||||
"true", "false",
|
"true", "false",
|
||||||
"and", "or", "not",
|
"and", "or", "not",
|
||||||
|
"text",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -239,6 +244,10 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseImp (bool allowEmpty)
|
||||||
return boost::shared_ptr<CSMFilter::Node> (new NotNode (node));
|
return boost::shared_ptr<CSMFilter::Node> (new NotNode (node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Token::Type_Keyword_Text:
|
||||||
|
|
||||||
|
return parseText();
|
||||||
|
|
||||||
case Token::Type_EOS:
|
case Token::Type_EOS:
|
||||||
|
|
||||||
if (!allowEmpty)
|
if (!allowEmpty)
|
||||||
|
@ -261,7 +270,7 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseNAry (const Token& ke
|
||||||
|
|
||||||
Token token = getNextToken();
|
Token token = getNextToken();
|
||||||
|
|
||||||
if (!token || token.mType!=Token::Type_Open)
|
if (token.mType!=Token::Type_Open)
|
||||||
{
|
{
|
||||||
error();
|
error();
|
||||||
return boost::shared_ptr<Node>();
|
return boost::shared_ptr<Node>();
|
||||||
|
@ -302,6 +311,70 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseNAry (const Token& ke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseText()
|
||||||
|
{
|
||||||
|
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 text pattern
|
||||||
|
token = getNextToken();
|
||||||
|
|
||||||
|
if (token.mType!=Token::Type_String)
|
||||||
|
{
|
||||||
|
error();
|
||||||
|
return boost::shared_ptr<Node>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string text = token.mString;
|
||||||
|
|
||||||
|
token = getNextToken();
|
||||||
|
|
||||||
|
if (token.mType!=Token::Type_Close)
|
||||||
|
{
|
||||||
|
error();
|
||||||
|
return boost::shared_ptr<Node>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::shared_ptr<Node> (new TextNode (columnId, text));
|
||||||
|
}
|
||||||
|
|
||||||
void CSMFilter::Parser::error()
|
void CSMFilter::Parser::error()
|
||||||
{
|
{
|
||||||
mError = true;
|
mError = true;
|
||||||
|
|
|
@ -30,6 +30,8 @@ namespace CSMFilter
|
||||||
|
|
||||||
boost::shared_ptr<Node> parseNAry (const Token& keyword);
|
boost::shared_ptr<Node> parseNAry (const Token& keyword);
|
||||||
|
|
||||||
|
boost::shared_ptr<Node> parseText();
|
||||||
|
|
||||||
void error();
|
void error();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
61
apps/opencs/model/filter/textnode.cpp
Normal file
61
apps/opencs/model/filter/textnode.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
#include "textnode.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
|
#include "../world/columns.hpp"
|
||||||
|
#include "../world/idtable.hpp"
|
||||||
|
|
||||||
|
CSMFilter::TextNode::TextNode (int columnId, const std::string& text)
|
||||||
|
: mColumnId (columnId), mText (text)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool CSMFilter::TextNode::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 node test");
|
||||||
|
|
||||||
|
if (iter->second==-1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
QModelIndex index = table.index (row, iter->second);
|
||||||
|
|
||||||
|
QVariant data = table.data (index);
|
||||||
|
|
||||||
|
if (data.type()!=QVariant::String)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QRegExp regExp(QString::fromUtf8 (mText.c_str())); /// \todo make pattern syntax configurable
|
||||||
|
|
||||||
|
return regExp.exactMatch (data.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> CSMFilter::TextNode::getReferencedColumns() const
|
||||||
|
{
|
||||||
|
return std::vector<int> (1, mColumnId);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSMFilter::TextNode::toString (bool numericColumns) const
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
stream << "text (";
|
||||||
|
|
||||||
|
if (numericColumns)
|
||||||
|
stream << mColumnId;
|
||||||
|
else
|
||||||
|
stream
|
||||||
|
<< "\""
|
||||||
|
<< CSMWorld::Columns::getName (static_cast<CSMWorld::Columns::ColumnId> (mColumnId))
|
||||||
|
<< "\"";
|
||||||
|
|
||||||
|
stream << ", \"" << mText << "\")";
|
||||||
|
|
||||||
|
return stream.str();
|
||||||
|
}
|
33
apps/opencs/model/filter/textnode.hpp
Normal file
33
apps/opencs/model/filter/textnode.hpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef CSM_FILTER_TEXTNODE_H
|
||||||
|
#define CSM_FILTER_TEXTNODE_H
|
||||||
|
|
||||||
|
#include "leafnode.hpp"
|
||||||
|
|
||||||
|
namespace CSMFilter
|
||||||
|
{
|
||||||
|
class TextNode : public LeafNode
|
||||||
|
{
|
||||||
|
int mColumnId;
|
||||||
|
std::string mText;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TextNode (int columnId, const std::string& text);
|
||||||
|
|
||||||
|
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