forked from teamnwah/openmw-tes3coop
added and and or filter nodes
This commit is contained in:
parent
50041fc211
commit
806e9a2888
16 changed files with 218 additions and 17 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
|
node unarynode narynode leafnode booleannode parser andnode ornode
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/filter
|
opencs_hdrs_noqt (model/filter
|
||||||
|
|
20
apps/opencs/model/filter/andnode.cpp
Normal file
20
apps/opencs/model/filter/andnode.cpp
Normal file
|
@ -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;
|
||||||
|
}
|
23
apps/opencs/model/filter/andnode.hpp
Normal file
23
apps/opencs/model/filter/andnode.hpp
Normal file
|
@ -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"
|
#include "narynode.hpp"
|
||||||
|
|
||||||
CSMFilter::NAryNode::NAryNode (const std::vector<boost::shared_ptr<Node> >& nodes)
|
#include <sstream>
|
||||||
: mNodes (nodes)
|
|
||||||
|
CSMFilter::NAryNode::NAryNode (const std::vector<boost::shared_ptr<Node> >& nodes,
|
||||||
|
const std::string& name)
|
||||||
|
: mNodes (nodes), mName (name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int CSMFilter::NAryNode::getSize() const
|
int CSMFilter::NAryNode::getSize() const
|
||||||
|
@ -30,6 +33,30 @@ std::vector<int> CSMFilter::NAryNode::getReferencedColumns() const
|
||||||
return columns;
|
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
|
bool CSMFilter::NAryNode::isSimple() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CSM_FILTER_NARYNODE_H
|
#define CSM_FILTER_NARYNODE_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
@ -12,10 +13,11 @@ namespace CSMFilter
|
||||||
class NAryNode : public Node
|
class NAryNode : public Node
|
||||||
{
|
{
|
||||||
std::vector<boost::shared_ptr<Node> > mNodes;
|
std::vector<boost::shared_ptr<Node> > mNodes;
|
||||||
|
std::string mName;
|
||||||
|
|
||||||
public:
|
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;
|
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
|
///< 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.
|
/// 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;
|
virtual bool isSimple() const;
|
||||||
///< \return Can this filter be displayed in simple mode.
|
///< \return Can this filter be displayed in simple mode.
|
||||||
|
|
||||||
|
|
20
apps/opencs/model/filter/ornode.cpp
Normal file
20
apps/opencs/model/filter/ornode.cpp
Normal file
|
@ -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;
|
||||||
|
}
|
23
apps/opencs/model/filter/ornode.hpp
Normal file
23
apps/opencs/model/filter/ornode.hpp
Normal file
|
@ -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 <components/misc/stringops.hpp>
|
||||||
|
|
||||||
#include "booleannode.hpp"
|
#include "booleannode.hpp"
|
||||||
|
#include "ornode.hpp"
|
||||||
|
#include "andnode.hpp"
|
||||||
|
|
||||||
namespace CSMFilter
|
namespace CSMFilter
|
||||||
{
|
{
|
||||||
|
@ -209,12 +211,89 @@ CSMFilter::Token CSMFilter::Parser::getNextToken()
|
||||||
|
|
||||||
boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseImp()
|
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>();
|
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()
|
void CSMFilter::Parser::error()
|
||||||
{
|
{
|
||||||
mError = true;
|
mError = true;
|
||||||
|
@ -235,6 +314,9 @@ bool CSMFilter::Parser::parse (const std::string& filter)
|
||||||
if (mError)
|
if (mError)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (getNextToken()!=Token (Token::Type_EOS))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
mFilter = node;
|
mFilter = node;
|
||||||
else
|
else
|
||||||
|
|
|
@ -28,6 +28,8 @@ namespace CSMFilter
|
||||||
boost::shared_ptr<Node> parseImp();
|
boost::shared_ptr<Node> parseImp();
|
||||||
///< Will return a null-pointer, if there is nothing more to parse.
|
///< Will return a null-pointer, if there is nothing more to parse.
|
||||||
|
|
||||||
|
boost::shared_ptr<Node> parseNAry (const Token& keyword);
|
||||||
|
|
||||||
void error();
|
void error();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -13,7 +13,7 @@ void CSVFilter::EditWidget::textChanged (const QString& text)
|
||||||
if (mParser.parse (text.toUtf8().constData()))
|
if (mParser.parse (text.toUtf8().constData()))
|
||||||
{
|
{
|
||||||
setPalette (mPalette);
|
setPalette (mPalette);
|
||||||
emit filterChanged (mParser.getFilter(), "");
|
emit filterChanged (mParser.getFilter());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,8 +24,7 @@ namespace CSVFilter
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter,
|
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter);
|
||||||
const std::string& userValue);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,6 @@ CSVFilter::FilterBox::FilterBox (QWidget *parent)
|
||||||
setLayout (layout);
|
setLayout (layout);
|
||||||
|
|
||||||
connect (recordFilterBox,
|
connect (recordFilterBox,
|
||||||
SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)),
|
SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)),
|
||||||
this, SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)));
|
this, SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)));
|
||||||
}
|
}
|
|
@ -17,8 +17,7 @@ namespace CSVFilter
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter,
|
void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter);
|
||||||
const std::string& userValue);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,6 @@ CSVFilter::RecordFilterBox::RecordFilterBox (QWidget *parent)
|
||||||
setLayout (layout);
|
setLayout (layout);
|
||||||
|
|
||||||
connect (
|
connect (
|
||||||
editWidget, 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>, const std::string&)));
|
this, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,7 @@ namespace CSVFilter
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter,
|
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter);
|
||||||
const std::string& userValue);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
||||||
mTable, SLOT (requestFocus (const std::string&)));
|
mTable, SLOT (requestFocus (const std::string&)));
|
||||||
|
|
||||||
connect (filterBox,
|
connect (filterBox,
|
||||||
SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)),
|
SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)),
|
||||||
mTable, SLOT (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>, const std::string&)));
|
mTable, SLOT (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::TableSubView::setEditLock (bool locked)
|
void CSVWorld::TableSubView::setEditLock (bool locked)
|
||||||
|
|
Loading…
Reference in a new issue