added and and or filter nodes

pull/51/head
Marc Zinnschlag 12 years ago
parent 50041fc211
commit 806e9a2888

@ -108,7 +108,7 @@ opencs_units_noqt (model/settings
)
opencs_units_noqt (model/filter
node unarynode narynode leafnode booleannode parser
node unarynode narynode leafnode booleannode parser andnode ornode
)
opencs_hdrs_noqt (model/filter

@ -0,0 +1,20 @@
#include "andnode.hpp"
#include <sstream>
CSMFilter::AndNode::AndNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: NAryNode (nodes, "and")
{}
bool CSMFilter::AndNode::test (const CSMWorld::IdTable& table, int row,
const std::map<int, int>& columns) const
{
int size = getSize();
for (int i=0; i<size; ++i)
if (!(*this)[i].test (table, row, columns))
return false;
return true;
}

@ -0,0 +1,23 @@
#ifndef CSM_FILTER_ANDNODE_H
#define CSM_FILTER_ANDNODE_H
#include "narynode.hpp"
namespace CSMFilter
{
class AndNode : public NAryNode
{
bool mAnd;
public:
AndNode (const std::vector<boost::shared_ptr<Node> >& nodes);
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
};
}
#endif

@ -1,8 +1,11 @@
#include "narynode.hpp"
CSMFilter::NAryNode::NAryNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: mNodes (nodes)
#include <sstream>
CSMFilter::NAryNode::NAryNode (const std::vector<boost::shared_ptr<Node> >& nodes,
const std::string& name)
: mNodes (nodes), mName (name)
{}
int CSMFilter::NAryNode::getSize() const
@ -30,6 +33,30 @@ std::vector<int> CSMFilter::NAryNode::getReferencedColumns() const
return columns;
}
std::string CSMFilter::NAryNode::toString (bool numericColumns) const
{
std::ostringstream stream;
stream << mName << " (";
bool first = true;
int size = getSize();
for (int i=0; i<size; ++i)
{
if (first)
first = false;
else
stream << ", ";
stream << (*this)[i].toString (numericColumns);
}
stream << ")";
return stream.str();
}
bool CSMFilter::NAryNode::isSimple() const
{
return false;

@ -2,6 +2,7 @@
#define CSM_FILTER_NARYNODE_H
#include <vector>
#include <string>
#include <boost/shared_ptr.hpp>
@ -12,10 +13,11 @@ namespace CSMFilter
class NAryNode : public Node
{
std::vector<boost::shared_ptr<Node> > mNodes;
std::string mName;
public:
NAryNode (const std::vector<boost::shared_ptr<Node> >& nodes);
NAryNode (const std::vector<boost::shared_ptr<Node> >& nodes, const std::string& name);
int getSize() const;
@ -25,6 +27,11 @@ namespace CSMFilter
///< 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.
virtual bool isSimple() const;
///< \return Can this filter be displayed in simple mode.

@ -0,0 +1,20 @@
#include "ornode.hpp"
#include <sstream>
CSMFilter::OrNode::OrNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: NAryNode (nodes, "or")
{}
bool CSMFilter::OrNode::test (const CSMWorld::IdTable& table, int row,
const std::map<int, int>& columns) const
{
int size = getSize();
for (int i=0; i<size; ++i)
if ((*this)[i].test (table, row, columns))
return true;
return false;
}

@ -0,0 +1,23 @@
#ifndef CSM_FILTER_ORNODE_H
#define CSM_FILTER_ORNODE_H
#include "narynode.hpp"
namespace CSMFilter
{
class OrNode : public NAryNode
{
bool mAnd;
public:
OrNode (const std::vector<boost::shared_ptr<Node> >& nodes);
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
};
}
#endif

@ -8,6 +8,8 @@
#include <components/misc/stringops.hpp>
#include "booleannode.hpp"
#include "ornode.hpp"
#include "andnode.hpp"
namespace CSMFilter
{
@ -209,12 +211,89 @@ CSMFilter::Token CSMFilter::Parser::getNextToken()
boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseImp()
{
if (Token token = getNextToken())
{
switch (token.mType)
{
case Token::Type_Keyword_True:
return boost::shared_ptr<CSMFilter::Node> (new BooleanNode (true));
case Token::Type_Keyword_False:
return boost::shared_ptr<CSMFilter::Node> (new BooleanNode (false));
case Token::Type_Keyword_And:
case Token::Type_Keyword_Or:
return parseNAry (token);
case Token::Type_EOS:
return boost::shared_ptr<Node>();
default:
error();
}
}
return boost::shared_ptr<Node>();
}
boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseNAry (const Token& keyword)
{
std::vector<boost::shared_ptr<Node> > nodes;
Token token = getNextToken();
if (!token || token.mType!=Token::Type_Open)
{
error();
return boost::shared_ptr<Node>();
}
for (;;)
{
boost::shared_ptr<Node> node = parseImp();
if (mError)
return boost::shared_ptr<Node>();
if (!node.get())
{
error();
return boost::shared_ptr<Node>();
}
nodes.push_back (node);
Token token = getNextToken();
if (!token || (token.mType!=Token::Type_Close && token.mType!=Token::Type_Comma))
{
error();
return boost::shared_ptr<Node>();
}
if (token.mType==Token::Type_Close)
break;
}
if (nodes.empty())
{
error();
return boost::shared_ptr<Node>();
}
switch (keyword.mType)
{
case Token::Type_Keyword_And: return boost::shared_ptr<CSMFilter::Node> (new AndNode (nodes));
case Token::Type_Keyword_Or: return boost::shared_ptr<CSMFilter::Node> (new OrNode (nodes));
default: error(); return boost::shared_ptr<Node>();
}
}
void CSMFilter::Parser::error()
{
mError = true;
@ -235,6 +314,9 @@ bool CSMFilter::Parser::parse (const std::string& filter)
if (mError)
return false;
if (getNextToken()!=Token (Token::Type_EOS))
return false;
if (node)
mFilter = node;
else

@ -28,6 +28,8 @@ namespace CSMFilter
boost::shared_ptr<Node> parseImp();
///< Will return a null-pointer, if there is nothing more to parse.
boost::shared_ptr<Node> parseNAry (const Token& keyword);
void error();
public:

@ -13,7 +13,7 @@ void CSVFilter::EditWidget::textChanged (const QString& text)
if (mParser.parse (text.toUtf8().constData()))
{
setPalette (mPalette);
emit filterChanged (mParser.getFilter(), "");
emit filterChanged (mParser.getFilter());
}
else
{

@ -24,8 +24,7 @@ namespace CSVFilter
signals:
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter,
const std::string& userValue);
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter);
private slots:

@ -19,6 +19,6 @@ CSVFilter::FilterBox::FilterBox (QWidget *parent)
setLayout (layout);
connect (recordFilterBox,
SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)),
this, SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)));
SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)),
this, SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)));
}

@ -17,8 +17,7 @@ namespace CSVFilter
signals:
void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter,
const std::string& userValue);
void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter);
};
}

@ -22,6 +22,6 @@ CSVFilter::RecordFilterBox::RecordFilterBox (QWidget *parent)
setLayout (layout);
connect (
editWidget, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)),
this, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)));
editWidget, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)),
this, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)));
}

@ -21,8 +21,7 @@ namespace CSVFilter
signals:
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter,
const std::string& userValue);
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter);
};
}

@ -52,8 +52,8 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
mTable, SLOT (requestFocus (const std::string&)));
connect (filterBox,
SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)),
mTable, SLOT (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)));
SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)),
mTable, SLOT (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)));
}
void CSVWorld::TableSubView::setEditLock (bool locked)

Loading…
Cancel
Save