mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 15:35:23 +00:00
added text filter node
This commit is contained in:
parent
decd826208
commit
de956737fe
@ -108,7 +108,7 @@ opencs_units_noqt (model/settings
|
||||
)
|
||||
|
||||
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
|
||||
|
@ -7,10 +7,13 @@
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "../world/columns.hpp"
|
||||
|
||||
#include "booleannode.hpp"
|
||||
#include "ornode.hpp"
|
||||
#include "andnode.hpp"
|
||||
#include "notnode.hpp"
|
||||
#include "textnode.hpp"
|
||||
|
||||
namespace CSMFilter
|
||||
{
|
||||
@ -31,7 +34,8 @@ namespace CSMFilter
|
||||
Type_Keyword_False,
|
||||
Type_Keyword_And,
|
||||
Type_Keyword_Or,
|
||||
Type_Keyword_Not
|
||||
Type_Keyword_Not,
|
||||
Type_Keyword_Text
|
||||
};
|
||||
|
||||
Type mType;
|
||||
@ -162,6 +166,7 @@ CSMFilter::Token CSMFilter::Parser::checkKeywords (const Token& token)
|
||||
{
|
||||
"true", "false",
|
||||
"and", "or", "not",
|
||||
"text",
|
||||
0
|
||||
};
|
||||
|
||||
@ -239,6 +244,10 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseImp (bool allowEmpty)
|
||||
return boost::shared_ptr<CSMFilter::Node> (new NotNode (node));
|
||||
}
|
||||
|
||||
case Token::Type_Keyword_Text:
|
||||
|
||||
return parseText();
|
||||
|
||||
case Token::Type_EOS:
|
||||
|
||||
if (!allowEmpty)
|
||||
@ -261,7 +270,7 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseNAry (const Token& ke
|
||||
|
||||
Token token = getNextToken();
|
||||
|
||||
if (!token || token.mType!=Token::Type_Open)
|
||||
if (token.mType!=Token::Type_Open)
|
||||
{
|
||||
error();
|
||||
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()
|
||||
{
|
||||
mError = true;
|
||||
|
@ -30,6 +30,8 @@ namespace CSMFilter
|
||||
|
||||
boost::shared_ptr<Node> parseNAry (const Token& keyword);
|
||||
|
||||
boost::shared_ptr<Node> parseText();
|
||||
|
||||
void error();
|
||||
|
||||
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…
x
Reference in New Issue
Block a user