From f6226e4859c0a089156a4d4c16e7335ff94c3b79 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Aug 2013 15:55:23 +0200 Subject: [PATCH 01/24] added Creator class for filters --- apps/opencs/CMakeLists.txt | 4 ++ apps/opencs/model/filter/filter.hpp | 12 ++--- apps/opencs/view/filter/filtercreator.cpp | 65 +++++++++++++++++++++++ apps/opencs/view/filter/filtercreator.hpp | 41 ++++++++++++++ apps/opencs/view/world/subviews.cpp | 8 ++- 5 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 apps/opencs/view/filter/filtercreator.cpp create mode 100644 apps/opencs/view/filter/filtercreator.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index f7b7daee4..9f33c862a 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -111,6 +111,10 @@ opencs_hdrs_noqt (model/filter filter ) +opencs_units (view/filter + filtercreator + ) + set (OPENCS_US ) diff --git a/apps/opencs/model/filter/filter.hpp b/apps/opencs/model/filter/filter.hpp index bddc9cc2d..7630ad410 100644 --- a/apps/opencs/model/filter/filter.hpp +++ b/apps/opencs/model/filter/filter.hpp @@ -11,15 +11,15 @@ namespace CSMFilter /// \brief Wrapper for Filter record struct Filter : public ESM::Filter { - enum scope + enum Scope { - Global = 0, - Local = 1, - Session = 2, - Content = 3 + Scope_Global = 0, // per user + Scope_Project = 1, // per project + Scope_Session = 2, // exists only for one editing session; not saved + Scope_Content = 3 // embedded in the edited content file }; - scope mScope; + Scope mScope; }; } diff --git a/apps/opencs/view/filter/filtercreator.cpp b/apps/opencs/view/filter/filtercreator.cpp new file mode 100644 index 000000000..476eacbe1 --- /dev/null +++ b/apps/opencs/view/filter/filtercreator.cpp @@ -0,0 +1,65 @@ + +#include "filtercreator.hpp" + +#include +#include + +#include "../../model/filter/filter.hpp" + +std::string CSVFilter::FilterCreator::getNamespace() const +{ + switch (mScope->currentIndex()) + { + case CSMFilter::Filter::Scope_Global: return "global::"; + case CSMFilter::Filter::Scope_Project: return "project::"; + case CSMFilter::Filter::Scope_Session: return "session::"; + } + + return ""; +} + +void CSVFilter::FilterCreator::update() +{ + mNamespace->setText (QString::fromUtf8 (getNamespace().c_str())); + GenericCreator::update(); +} + +std::string CSVFilter::FilterCreator::getId() const +{ + return getNamespace() + GenericCreator::getId(); +} + +CSVFilter::FilterCreator::FilterCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id) +: GenericCreator (data, undoStack, id) +{ + mNamespace = new QLabel ("::", this); + insertAtBeginning (mNamespace, false); + + mScope = new QComboBox (this); + + mScope->addItem ("Global"); + mScope->addItem ("Project"); + mScope->addItem ("Session"); + /// \ŧodo re-enable for OpenMW 1.1 + // mScope->addItem ("Content"); + + connect (mScope, SIGNAL (currentIndexChanged (int)), this, SLOT (setScope (int))); + + insertAtBeginning (mScope, false); + + QLabel *label = new QLabel ("Scope", this); + insertAtBeginning (label, false); + + mScope->setCurrentIndex (2); +} + +void CSVFilter::FilterCreator::reset() +{ + GenericCreator::reset(); +} + +void CSVFilter::FilterCreator::setScope (int index) +{ + update(); +} diff --git a/apps/opencs/view/filter/filtercreator.hpp b/apps/opencs/view/filter/filtercreator.hpp new file mode 100644 index 000000000..82d38d22c --- /dev/null +++ b/apps/opencs/view/filter/filtercreator.hpp @@ -0,0 +1,41 @@ +#ifndef CSV_FILTER_FILTERCREATOR_H +#define CSV_FILTER_FILTERCREATOR_H + +class QComboBox; +class QLabel; + +#include "../world/genericcreator.hpp" + +namespace CSVFilter +{ + class FilterCreator : public CSVWorld::GenericCreator + { + Q_OBJECT + + QComboBox *mScope; + QLabel *mNamespace; + + private: + + std::string getNamespace() const; + + protected: + + void update(); + + virtual std::string getId() const; + + public: + + FilterCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id); + + virtual void reset(); + + private slots: + + void setScope (int index); + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 2ca711a59..d22e07d89 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -3,6 +3,8 @@ #include "../doc/subviewfactoryimp.hpp" +#include "../filter/filtercreator.hpp" + #include "tablesubview.hpp" #include "dialoguesubview.hpp" #include "scriptsubview.hpp" @@ -33,7 +35,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, - CSMWorld::UniversalId::Type_Filters, CSMWorld::UniversalId::Type_None // end marker }; @@ -56,4 +57,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) // Other stuff (combined record tables) manager.add (CSMWorld::UniversalId::Type_RegionMap, new CSVDoc::SubViewFactory); + + manager.add (CSMWorld::UniversalId::Type_Filters, + new CSVDoc::SubViewFactoryWithCreator >); + } \ No newline at end of file From a95715b61dbd52237fc21454e1f639bf2b5d3e47 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Aug 2013 13:45:50 +0200 Subject: [PATCH 02/24] added description field to filter record --- apps/opencs/model/world/data.cpp | 1 + components/esm/filter.cpp | 3 +++ components/esm/filter.hpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 9c5e13562..4a5dcb38f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -150,6 +150,7 @@ CSMWorld::Data::Data() : mRefs (mCells) mFilters.addColumn (new StringIdColumn); mFilters.addColumn (new RecordStateColumn); + mFilters.addColumn (new DescriptionColumn); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); diff --git a/components/esm/filter.cpp b/components/esm/filter.cpp index 205332f6b..7d4851a5f 100644 --- a/components/esm/filter.cpp +++ b/components/esm/filter.cpp @@ -7,14 +7,17 @@ void ESM::Filter::load (ESMReader& esm) { mFilter = esm.getHNString ("FILT"); + mDescription = esm.getHNString ("DESC"); } void ESM::Filter::save (ESMWriter& esm) { esm.writeHNCString ("FILT", mFilter); + esm.writeHNCString ("DESC", mDescription); } void ESM::Filter::blank() { mFilter.clear(); + mDescription.clear(); } diff --git a/components/esm/filter.hpp b/components/esm/filter.hpp index 2dde92fb0..0fd564361 100644 --- a/components/esm/filter.hpp +++ b/components/esm/filter.hpp @@ -12,6 +12,8 @@ namespace ESM { std::string mId; + std::string mDescription; + std::string mFilter; void load (ESMReader& esm); From f5b06d5d520573dd612e663131a28f7b6cc3eed5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Aug 2013 14:49:05 +0200 Subject: [PATCH 03/24] basic filter tree structure --- apps/opencs/CMakeLists.txt | 4 ++ apps/opencs/model/filter/binarynode.cpp | 58 ++++++++++++++++++++++++ apps/opencs/model/filter/binarynode.hpp | 42 +++++++++++++++++ apps/opencs/model/filter/booleannode.cpp | 17 +++++++ apps/opencs/model/filter/booleannode.hpp | 31 +++++++++++++ apps/opencs/model/filter/leafnode.cpp | 22 +++++++++ apps/opencs/model/filter/leafnode.hpp | 29 ++++++++++++ apps/opencs/model/filter/node.cpp | 6 +++ apps/opencs/model/filter/node.hpp | 58 ++++++++++++++++++++++++ apps/opencs/model/filter/unarynode.cpp | 34 ++++++++++++++ apps/opencs/model/filter/unarynode.hpp | 37 +++++++++++++++ 11 files changed, 338 insertions(+) create mode 100644 apps/opencs/model/filter/binarynode.cpp create mode 100644 apps/opencs/model/filter/binarynode.hpp create mode 100644 apps/opencs/model/filter/booleannode.cpp create mode 100644 apps/opencs/model/filter/booleannode.hpp create mode 100644 apps/opencs/model/filter/leafnode.cpp create mode 100644 apps/opencs/model/filter/leafnode.hpp create mode 100644 apps/opencs/model/filter/node.cpp create mode 100644 apps/opencs/model/filter/node.hpp create mode 100644 apps/opencs/model/filter/unarynode.cpp create mode 100644 apps/opencs/model/filter/unarynode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 9f33c862a..8e0024ad9 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -107,6 +107,10 @@ opencs_units_noqt (model/settings settingsitem ) +opencs_units_noqt (model/filter + node unarynode binarynode leafnode booleannode + ) + opencs_hdrs_noqt (model/filter filter ) diff --git a/apps/opencs/model/filter/binarynode.cpp b/apps/opencs/model/filter/binarynode.cpp new file mode 100644 index 000000000..0e86930db --- /dev/null +++ b/apps/opencs/model/filter/binarynode.cpp @@ -0,0 +1,58 @@ + +#include "binarynode.hpp" + +CSMFilter::BinaryNode::BinaryNode (std::auto_ptr left, std::auto_ptr right) +: mLeft (left), mRight (right) +{} + +const CSMFilter::Node& CSMFilter::BinaryNode::getLeft() const +{ + return *mLeft; +} + +CSMFilter::Node& CSMFilter::BinaryNode::getLeft() +{ + return *mLeft; +} + +const CSMFilter::Node& CSMFilter::BinaryNode::getRight() const +{ + return *mRight; +} + +CSMFilter::Node& CSMFilter::BinaryNode::getRight() +{ + return *mRight; +} + +std::vector CSMFilter::BinaryNode::getReferencedFilters() const +{ + std::vector left = mLeft->getReferencedFilters(); + + std::vector right = mRight->getReferencedFilters(); + + left.insert (left.end(), right.begin(), right.end()); + + return left; +} + +std::vector CSMFilter::BinaryNode::getReferencedColumns() const +{ + std::vector left = mLeft->getReferencedColumns(); + + std::vector right = mRight->getReferencedColumns(); + + left.insert (left.end(), right.begin(), right.end()); + + return left; +} + +bool CSMFilter::BinaryNode::isSimple() const +{ + return false; +} + +bool CSMFilter::BinaryNode::hasUserValue() const +{ + return mLeft->hasUserValue() || mRight->hasUserValue(); +} diff --git a/apps/opencs/model/filter/binarynode.hpp b/apps/opencs/model/filter/binarynode.hpp new file mode 100644 index 000000000..18cdad2a9 --- /dev/null +++ b/apps/opencs/model/filter/binarynode.hpp @@ -0,0 +1,42 @@ +#ifndef CSM_FILTER_BINARYNODE_H +#define CSM_FILTER_BINARYNODE_H + +#include + +#include "node.hpp" + +namespace CSMFilter +{ + class BinaryNode : public Node + { + std::auto_ptr mLeft; + std::auto_ptr mRight; + + public: + + BinaryNode (std::auto_ptr left, std::auto_ptr right); + + const Node& getLeft() const; + + Node& getLeft(); + + const Node& getRight() const; + + Node& getRight(); + + virtual std::vector getReferencedFilters() const; + ///< Return a list of filters that are used by this node (and must be passed as + /// otherFilters when calling test). + + virtual std::vector 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 bool isSimple() const; + ///< \return Can this filter be displayed in simple mode. + + virtual bool hasUserValue() const; + }; +} + +#endif diff --git a/apps/opencs/model/filter/booleannode.cpp b/apps/opencs/model/filter/booleannode.cpp new file mode 100644 index 000000000..cea130d24 --- /dev/null +++ b/apps/opencs/model/filter/booleannode.cpp @@ -0,0 +1,17 @@ + +#include "booleannode.hpp" + +CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true) {} + +bool CSMFilter::BooleanNode::test (const CSMWorld::IdTable& table, int row, + const std::map& otherFilters, + const std::map& columns, + const std::string& userValue) const +{ + return mTrue; +} + +std::string CSMFilter::BooleanNode::toString (bool numericColumns) const +{ + return mTrue ? "true" : "false"; +} \ No newline at end of file diff --git a/apps/opencs/model/filter/booleannode.hpp b/apps/opencs/model/filter/booleannode.hpp new file mode 100644 index 000000000..3578c7f3f --- /dev/null +++ b/apps/opencs/model/filter/booleannode.hpp @@ -0,0 +1,31 @@ +#ifndef CSM_FILTER_BOOLEANNODE_H +#define CSM_FILTER_BOOLEANNODE_H + +#include "leafnode.hpp" + +namespace CSMFilter +{ + class BooleanNode : public LeafNode + { + bool mTrue; + + public: + + BooleanNode (bool true_); + + virtual bool test (const CSMWorld::IdTable& table, int row, + const std::map& otherFilters, + const std::map& columns, + const std::string& userValue) const; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + + 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 \ No newline at end of file diff --git a/apps/opencs/model/filter/leafnode.cpp b/apps/opencs/model/filter/leafnode.cpp new file mode 100644 index 000000000..5c6d4b042 --- /dev/null +++ b/apps/opencs/model/filter/leafnode.cpp @@ -0,0 +1,22 @@ + +#include "leafnode.hpp" + +std::vector CSMFilter::LeafNode::getReferencedFilters() const +{ + return std::vector(); +} + +std::vector CSMFilter::LeafNode::getReferencedColumns() const +{ + return std::vector(); +} + +bool CSMFilter::LeafNode::isSimple() const +{ + return true; +} + +bool CSMFilter::LeafNode::hasUserValue() const +{ + return false; +} \ No newline at end of file diff --git a/apps/opencs/model/filter/leafnode.hpp b/apps/opencs/model/filter/leafnode.hpp new file mode 100644 index 000000000..663083ff9 --- /dev/null +++ b/apps/opencs/model/filter/leafnode.hpp @@ -0,0 +1,29 @@ +#ifndef CSM_FILTER_UNARIYNODE_H +#define CSM_FILTER_UNARIYNODE_H + +#include + +#include "node.hpp" + +namespace CSMFilter +{ + class LeafNode : public Node + { + public: + + virtual std::vector getReferencedFilters() const; + ///< Return a list of filters that are used by this node (and must be passed as + /// otherFilters when calling test). + + virtual std::vector 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 bool isSimple() const; + ///< \return Can this filter be displayed in simple mode. + + virtual bool hasUserValue() const; + }; +} + +#endif diff --git a/apps/opencs/model/filter/node.cpp b/apps/opencs/model/filter/node.cpp new file mode 100644 index 000000000..276861cdc --- /dev/null +++ b/apps/opencs/model/filter/node.cpp @@ -0,0 +1,6 @@ + +#include "node.hpp" + +CSMFilter::Node::Node() {} + +CSMFilter::Node::~Node() {} \ No newline at end of file diff --git a/apps/opencs/model/filter/node.hpp b/apps/opencs/model/filter/node.hpp new file mode 100644 index 000000000..09bc3cd42 --- /dev/null +++ b/apps/opencs/model/filter/node.hpp @@ -0,0 +1,58 @@ +#ifndef CSM_FILTER_NODE_H +#define CSM_FILTER_NODE_H + +#include +#include +#include + +namespace CSMWorld +{ + class IdTable; +} + +namespace CSMFilter +{ + /// \brief Root class for the filter node hierarchy + /// + /// \note When the function documentation for this class mentions "this node", this should be + /// interpreted as "the node and all its children". + class Node + { + // not implemented + Node (const Node&); + Node& operator= (const Node&); + + public: + + Node(); + + virtual ~Node(); + + virtual bool test (const CSMWorld::IdTable& table, int row, + const std::map& otherFilters, + const std::map& columns, + const std::string& userValue) const = 0; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + + virtual std::vector getReferencedFilters() const = 0; + ///< Return a list of filters that are used by this node (and must be passed as + /// otherFilters when calling test). + + virtual std::vector getReferencedColumns() const = 0; + ///< 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 bool isSimple() const = 0; + ///< \return Can this filter be displayed in simple mode. + + virtual bool hasUserValue() const = 0; + + virtual std::string toString (bool numericColumns) const = 0; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. + }; +} + +#endif diff --git a/apps/opencs/model/filter/unarynode.cpp b/apps/opencs/model/filter/unarynode.cpp new file mode 100644 index 000000000..f9cc3fdc8 --- /dev/null +++ b/apps/opencs/model/filter/unarynode.cpp @@ -0,0 +1,34 @@ + +#include "unarynode.hpp" + +CSMFilter::UnaryNode::UnaryNode (std::auto_ptr child) : mChild (child) {} + +const CSMFilter::Node& CSMFilter::UnaryNode::getChild() const +{ + return *mChild; +} + +CSMFilter::Node& CSMFilter::UnaryNode::getChild() +{ + return *mChild; +} + +std::vector CSMFilter::UnaryNode::getReferencedFilters() const +{ + return mChild->getReferencedFilters(); +} + +std::vector CSMFilter::UnaryNode::getReferencedColumns() const +{ + return mChild->getReferencedColumns(); +} + +bool CSMFilter::UnaryNode::isSimple() const +{ + return false; +} + +bool CSMFilter::UnaryNode::hasUserValue() const +{ + return mChild->hasUserValue(); +} diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp new file mode 100644 index 000000000..6ecad1192 --- /dev/null +++ b/apps/opencs/model/filter/unarynode.hpp @@ -0,0 +1,37 @@ +#ifndef CSM_FILTER_UNARIYNODE_H +#define CSM_FILTER_UNARIYNODE_H + +#include + +#include "node.hpp" + +namespace CSMFilter +{ + class UnaryNode : public Node + { + std::auto_ptr mChild; + + public: + + UnaryNode (std::auto_ptr child); + + const Node& getChild() const; + + Node& getChild(); + + virtual std::vector getReferencedFilters() const; + ///< Return a list of filters that are used by this node (and must be passed as + /// otherFilters when calling test). + + virtual std::vector 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 bool isSimple() const; + ///< \return Can this filter be displayed in simple mode. + + virtual bool hasUserValue() const; + }; +} + +#endif From 789a66eaa7e0894e458c39bae8afa993fc392c0e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 11 Aug 2013 20:39:21 +0200 Subject: [PATCH 04/24] added filter box and basic record filter UI (not functional yet; only supporting on-the-fly filters for now) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/filter/filterbox.cpp | 18 ++++++++++++++++++ apps/opencs/view/filter/filterbox.hpp | 19 +++++++++++++++++++ apps/opencs/view/filter/recordfilterbox.cpp | 20 ++++++++++++++++++++ apps/opencs/view/filter/recordfilterbox.hpp | 21 +++++++++++++++++++++ apps/opencs/view/world/tablesubview.cpp | 4 ++++ 6 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/view/filter/filterbox.cpp create mode 100644 apps/opencs/view/filter/filterbox.hpp create mode 100644 apps/opencs/view/filter/recordfilterbox.cpp create mode 100644 apps/opencs/view/filter/recordfilterbox.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8e0024ad9..d363eeedc 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -116,7 +116,7 @@ opencs_hdrs_noqt (model/filter ) opencs_units (view/filter - filtercreator + filtercreator filterbox recordfilterbox ) set (OPENCS_US diff --git a/apps/opencs/view/filter/filterbox.cpp b/apps/opencs/view/filter/filterbox.cpp new file mode 100644 index 000000000..f3f17706b --- /dev/null +++ b/apps/opencs/view/filter/filterbox.cpp @@ -0,0 +1,18 @@ + +#include "filterbox.hpp" + +#include + +#include "recordfilterbox.hpp" + +CSVFilter::FilterBox::FilterBox (QWidget *parent) +: QWidget (parent) +{ + QHBoxLayout *layout = new QHBoxLayout (this); + + layout->setContentsMargins (0, 0, 0, 0); + + layout->addWidget (new RecordFilterBox (this)); + + setLayout (layout); +} \ No newline at end of file diff --git a/apps/opencs/view/filter/filterbox.hpp b/apps/opencs/view/filter/filterbox.hpp new file mode 100644 index 000000000..969a43cd7 --- /dev/null +++ b/apps/opencs/view/filter/filterbox.hpp @@ -0,0 +1,19 @@ +#ifndef CSV_FILTER_FILTERBOX_H +#define CSV_FILTER_FILTERBOX_H + +#include + +namespace CSVFilter +{ + class FilterBox : public QWidget + { + Q_OBJECT + + public: + + FilterBox (QWidget *parent = 0); + }; + +} + +#endif diff --git a/apps/opencs/view/filter/recordfilterbox.cpp b/apps/opencs/view/filter/recordfilterbox.cpp new file mode 100644 index 000000000..b0c195664 --- /dev/null +++ b/apps/opencs/view/filter/recordfilterbox.cpp @@ -0,0 +1,20 @@ + +#include "recordfilterbox.hpp" + +#include +#include +#include + +CSVFilter::RecordFilterBox::RecordFilterBox (QWidget *parent) +: QWidget (parent) +{ + QHBoxLayout *layout = new QHBoxLayout (this); + + layout->setContentsMargins (0, 0, 0, 0); + + layout->addWidget (new QLabel ("Record Filter", this)); + + layout->addWidget (new QLineEdit (this)); + + setLayout (layout); +} \ No newline at end of file diff --git a/apps/opencs/view/filter/recordfilterbox.hpp b/apps/opencs/view/filter/recordfilterbox.hpp new file mode 100644 index 000000000..3a411f808 --- /dev/null +++ b/apps/opencs/view/filter/recordfilterbox.hpp @@ -0,0 +1,21 @@ +#ifndef CSV_FILTER_RECORDFILTERBOX_H +#define CSV_FILTER_RECORDFILTERBOX_H + +#include + +#include + +namespace CSVFilter +{ + class RecordFilterBox : public QWidget + { + Q_OBJECT + + public: + + RecordFilterBox (QWidget *parent = 0); + }; + +} + +#endif \ No newline at end of file diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index af3d186e8..df95940c9 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -5,6 +5,8 @@ #include "../../model/doc/document.hpp" +#include "../filter/filterbox.hpp" + #include "table.hpp" #include "tablebottombox.hpp" #include "creator.hpp" @@ -23,6 +25,8 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout->insertWidget (0, mTable = new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete()), 2); + layout->insertWidget (0, new CSVFilter::FilterBox (this)); + QWidget *widget = new QWidget; widget->setLayout (layout); From 528e047fd53d89b3c28a6074c60f272ec954545a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 16 Aug 2013 13:57:54 +0200 Subject: [PATCH 05/24] repalced std::auto_ptr with boost::shared_ptr in filter nodes --- apps/opencs/model/filter/binarynode.cpp | 2 +- apps/opencs/model/filter/binarynode.hpp | 8 ++++---- apps/opencs/model/filter/unarynode.cpp | 2 +- apps/opencs/model/filter/unarynode.hpp | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/opencs/model/filter/binarynode.cpp b/apps/opencs/model/filter/binarynode.cpp index 0e86930db..c0c7fde37 100644 --- a/apps/opencs/model/filter/binarynode.cpp +++ b/apps/opencs/model/filter/binarynode.cpp @@ -1,7 +1,7 @@ #include "binarynode.hpp" -CSMFilter::BinaryNode::BinaryNode (std::auto_ptr left, std::auto_ptr right) +CSMFilter::BinaryNode::BinaryNode (boost::shared_ptr left, boost::shared_ptr right) : mLeft (left), mRight (right) {} diff --git a/apps/opencs/model/filter/binarynode.hpp b/apps/opencs/model/filter/binarynode.hpp index 18cdad2a9..c2b4041d2 100644 --- a/apps/opencs/model/filter/binarynode.hpp +++ b/apps/opencs/model/filter/binarynode.hpp @@ -1,7 +1,7 @@ #ifndef CSM_FILTER_BINARYNODE_H #define CSM_FILTER_BINARYNODE_H -#include +#include #include "node.hpp" @@ -9,12 +9,12 @@ namespace CSMFilter { class BinaryNode : public Node { - std::auto_ptr mLeft; - std::auto_ptr mRight; + boost::shared_ptr mLeft; + boost::shared_ptr mRight; public: - BinaryNode (std::auto_ptr left, std::auto_ptr right); + BinaryNode (boost::shared_ptr left, boost::shared_ptr right); const Node& getLeft() const; diff --git a/apps/opencs/model/filter/unarynode.cpp b/apps/opencs/model/filter/unarynode.cpp index f9cc3fdc8..490d95376 100644 --- a/apps/opencs/model/filter/unarynode.cpp +++ b/apps/opencs/model/filter/unarynode.cpp @@ -1,7 +1,7 @@ #include "unarynode.hpp" -CSMFilter::UnaryNode::UnaryNode (std::auto_ptr child) : mChild (child) {} +CSMFilter::UnaryNode::UnaryNode (boost::shared_ptr child) : mChild (child) {} const CSMFilter::Node& CSMFilter::UnaryNode::getChild() const { diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp index 6ecad1192..4e1fb0cc2 100644 --- a/apps/opencs/model/filter/unarynode.hpp +++ b/apps/opencs/model/filter/unarynode.hpp @@ -1,7 +1,7 @@ #ifndef CSM_FILTER_UNARIYNODE_H #define CSM_FILTER_UNARIYNODE_H -#include +#include #include "node.hpp" @@ -9,11 +9,11 @@ namespace CSMFilter { class UnaryNode : public Node { - std::auto_ptr mChild; + boost::shared_ptr mChild; public: - UnaryNode (std::auto_ptr child); + UnaryNode (boost::shared_ptr child); const Node& getChild() const; From 236dc9fc43ceec38bed853e8326f828de2dbf87c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 16 Aug 2013 14:18:31 +0200 Subject: [PATCH 06/24] replaced binary filter node with a n-ary node --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/filter/binarynode.cpp | 58 ------------------ apps/opencs/model/filter/narynode.cpp | 61 +++++++++++++++++++ .../filter/{binarynode.hpp => narynode.hpp} | 21 +++---- 4 files changed, 71 insertions(+), 71 deletions(-) delete mode 100644 apps/opencs/model/filter/binarynode.cpp create mode 100644 apps/opencs/model/filter/narynode.cpp rename apps/opencs/model/filter/{binarynode.hpp => narynode.hpp} (64%) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index d363eeedc..8a1949e51 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -108,7 +108,7 @@ opencs_units_noqt (model/settings ) opencs_units_noqt (model/filter - node unarynode binarynode leafnode booleannode + node unarynode narynode leafnode booleannode ) opencs_hdrs_noqt (model/filter diff --git a/apps/opencs/model/filter/binarynode.cpp b/apps/opencs/model/filter/binarynode.cpp deleted file mode 100644 index c0c7fde37..000000000 --- a/apps/opencs/model/filter/binarynode.cpp +++ /dev/null @@ -1,58 +0,0 @@ - -#include "binarynode.hpp" - -CSMFilter::BinaryNode::BinaryNode (boost::shared_ptr left, boost::shared_ptr right) -: mLeft (left), mRight (right) -{} - -const CSMFilter::Node& CSMFilter::BinaryNode::getLeft() const -{ - return *mLeft; -} - -CSMFilter::Node& CSMFilter::BinaryNode::getLeft() -{ - return *mLeft; -} - -const CSMFilter::Node& CSMFilter::BinaryNode::getRight() const -{ - return *mRight; -} - -CSMFilter::Node& CSMFilter::BinaryNode::getRight() -{ - return *mRight; -} - -std::vector CSMFilter::BinaryNode::getReferencedFilters() const -{ - std::vector left = mLeft->getReferencedFilters(); - - std::vector right = mRight->getReferencedFilters(); - - left.insert (left.end(), right.begin(), right.end()); - - return left; -} - -std::vector CSMFilter::BinaryNode::getReferencedColumns() const -{ - std::vector left = mLeft->getReferencedColumns(); - - std::vector right = mRight->getReferencedColumns(); - - left.insert (left.end(), right.begin(), right.end()); - - return left; -} - -bool CSMFilter::BinaryNode::isSimple() const -{ - return false; -} - -bool CSMFilter::BinaryNode::hasUserValue() const -{ - return mLeft->hasUserValue() || mRight->hasUserValue(); -} diff --git a/apps/opencs/model/filter/narynode.cpp b/apps/opencs/model/filter/narynode.cpp new file mode 100644 index 000000000..0756f6707 --- /dev/null +++ b/apps/opencs/model/filter/narynode.cpp @@ -0,0 +1,61 @@ + +#include "narynode.hpp" + +CSMFilter::NAryNode::NAryNode (const std::vector >& nodes) +: mNodes (nodes) +{} + +int CSMFilter::NAryNode::getSize() const +{ + return mNodes.size(); +} + +const CSMFilter::Node& CSMFilter::NAryNode::operator[] (int index) const +{ + return *mNodes.at (index); +} + +std::vector CSMFilter::NAryNode::getReferencedFilters() const +{ + std::vector filters; + + for (std::vector >::const_iterator iter (mNodes.begin()); + iter!=mNodes.end(); ++iter) + { + std::vector filters2 = (*iter)->getReferencedFilters(); + + filters.insert (filters.end(), filters2.begin(), filters2.end()); + } + + return filters; +} + +std::vector CSMFilter::NAryNode::getReferencedColumns() const +{ + std::vector columns; + + for (std::vector >::const_iterator iter (mNodes.begin()); + iter!=mNodes.end(); ++iter) + { + std::vector columns2 = (*iter)->getReferencedColumns(); + + columns.insert (columns.end(), columns2.begin(), columns2.end()); + } + + return columns; +} + +bool CSMFilter::NAryNode::isSimple() const +{ + return false; +} + +bool CSMFilter::NAryNode::hasUserValue() const +{ + for (std::vector >::const_iterator iter (mNodes.begin()); + iter!=mNodes.end(); ++iter) + if ((*iter)->hasUserValue()) + return true; + + return false; +} diff --git a/apps/opencs/model/filter/binarynode.hpp b/apps/opencs/model/filter/narynode.hpp similarity index 64% rename from apps/opencs/model/filter/binarynode.hpp rename to apps/opencs/model/filter/narynode.hpp index c2b4041d2..65e12d1ed 100644 --- a/apps/opencs/model/filter/binarynode.hpp +++ b/apps/opencs/model/filter/narynode.hpp @@ -1,5 +1,7 @@ -#ifndef CSM_FILTER_BINARYNODE_H -#define CSM_FILTER_BINARYNODE_H +#ifndef CSM_FILTER_NARYNODE_H +#define CSM_FILTER_NARYNODE_H + +#include #include @@ -7,22 +9,17 @@ namespace CSMFilter { - class BinaryNode : public Node + class NAryNode : public Node { - boost::shared_ptr mLeft; - boost::shared_ptr mRight; + std::vector > mNodes; public: - BinaryNode (boost::shared_ptr left, boost::shared_ptr right); - - const Node& getLeft() const; - - Node& getLeft(); + NAryNode (const std::vector >& nodes); - const Node& getRight() const; + int getSize() const; - Node& getRight(); + const Node& operator[] (int index) const; virtual std::vector getReferencedFilters() const; ///< Return a list of filters that are used by this node (and must be passed as From c38860fa72936ea956a07d729c29e0ff6c392552 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 18 Aug 2013 14:17:18 +0200 Subject: [PATCH 07/24] added parser and custom filter edit widget (parser not functional yet; always returns a false boolean node) --- apps/opencs/CMakeLists.txt | 4 +-- apps/opencs/model/filter/parser.cpp | 33 +++++++++++++++++ apps/opencs/model/filter/parser.hpp | 39 +++++++++++++++++++++ apps/opencs/view/filter/editwidget.cpp | 20 +++++++++++ apps/opencs/view/filter/editwidget.hpp | 30 ++++++++++++++++ apps/opencs/view/filter/recordfilterbox.cpp | 5 +-- 6 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 apps/opencs/model/filter/parser.cpp create mode 100644 apps/opencs/model/filter/parser.hpp create mode 100644 apps/opencs/view/filter/editwidget.cpp create mode 100644 apps/opencs/view/filter/editwidget.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8a1949e51..031c650df 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -108,7 +108,7 @@ opencs_units_noqt (model/settings ) opencs_units_noqt (model/filter - node unarynode narynode leafnode booleannode + node unarynode narynode leafnode booleannode parser ) opencs_hdrs_noqt (model/filter @@ -116,7 +116,7 @@ opencs_hdrs_noqt (model/filter ) opencs_units (view/filter - filtercreator filterbox recordfilterbox + filtercreator filterbox recordfilterbox editwidget ) set (OPENCS_US diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp new file mode 100644 index 000000000..46052cec6 --- /dev/null +++ b/apps/opencs/model/filter/parser.cpp @@ -0,0 +1,33 @@ + +#include "parser.hpp" + +#include + +#include "booleannode.hpp" + +CSMFilter::Parser::Parser() : mState (State_Begin) {} + +void CSMFilter::Parser::parse (const std::string& filter) +{ + // reset + mState = State_Begin; + mFilter.reset(); + + + // for now we ignore the filter string + mFilter.reset (new BooleanNode (false)); + mState = State_End; +} + +CSMFilter::Parser::State CSMFilter::Parser::getState() const +{ + return mState; +} + +boost::shared_ptr CSMFilter::Parser::getFilter() const +{ + if (mState!=State_End) + throw std::logic_error ("No filter available"); + + return mFilter; +} \ No newline at end of file diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp new file mode 100644 index 000000000..72dc7d507 --- /dev/null +++ b/apps/opencs/model/filter/parser.hpp @@ -0,0 +1,39 @@ +#ifndef CSM_FILTER_PARSER_H +#define CSM_FILTER_PARSER_H + +#include + +#include "node.hpp" + +namespace CSMFilter +{ + class Parser + { + public: + + enum State + { + State_Begin, + State_End + }; + + private: + + State mState; + boost::shared_ptr mFilter; + + public: + + Parser(); + + void parse (const std::string& filter); + ///< Discards any previous calls to parse + + State getState() const; + + boost::shared_ptr getFilter() const; + ///< Throws an exception if getState()!=State_End + }; +} + +#endif diff --git a/apps/opencs/view/filter/editwidget.cpp b/apps/opencs/view/filter/editwidget.cpp new file mode 100644 index 000000000..8fc4a88ae --- /dev/null +++ b/apps/opencs/view/filter/editwidget.cpp @@ -0,0 +1,20 @@ + +#include "editwidget.hpp" + +CSVFilter::EditWidget::EditWidget (QWidget *parent) +: QLineEdit (parent) +{ + connect (this, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&))); +} + +void CSVFilter::EditWidget::textChanged (const QString& text) +{ + mParser.parse (text.toUtf8().constData()); + + if (mParser.getState()==CSMFilter::Parser::State_End) + emit filterChanged(); + else + { + /// \todo error handling + } +} \ No newline at end of file diff --git a/apps/opencs/view/filter/editwidget.hpp b/apps/opencs/view/filter/editwidget.hpp new file mode 100644 index 000000000..5959a8b16 --- /dev/null +++ b/apps/opencs/view/filter/editwidget.hpp @@ -0,0 +1,30 @@ +#ifndef CSV_FILTER_EDITWIDGET_H +#define CSV_FILTER_EDITWIDGET_H + +#include + +#include "../../model/filter/parser.hpp" + +namespace CSVFilter +{ + class EditWidget : public QLineEdit + { + Q_OBJECT + + CSMFilter::Parser mParser; + + public: + + EditWidget (QWidget *parent = 0); + + signals: + + void filterChanged(); + + private slots: + + void textChanged (const QString& text); + }; +} + +#endif diff --git a/apps/opencs/view/filter/recordfilterbox.cpp b/apps/opencs/view/filter/recordfilterbox.cpp index b0c195664..5e297ec38 100644 --- a/apps/opencs/view/filter/recordfilterbox.cpp +++ b/apps/opencs/view/filter/recordfilterbox.cpp @@ -2,9 +2,10 @@ #include "recordfilterbox.hpp" #include -#include #include +#include "editwidget.hpp" + CSVFilter::RecordFilterBox::RecordFilterBox (QWidget *parent) : QWidget (parent) { @@ -14,7 +15,7 @@ CSVFilter::RecordFilterBox::RecordFilterBox (QWidget *parent) layout->addWidget (new QLabel ("Record Filter", this)); - layout->addWidget (new QLineEdit (this)); + layout->addWidget (new EditWidget (this)); setLayout (layout); } \ No newline at end of file From 470f890a9add6916ef6b26160c7063de083c24da Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 18 Aug 2013 16:52:51 +0200 Subject: [PATCH 08/24] fixed BooleanNode constructor --- apps/opencs/model/filter/booleannode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/booleannode.cpp b/apps/opencs/model/filter/booleannode.cpp index cea130d24..2f521ed06 100644 --- a/apps/opencs/model/filter/booleannode.cpp +++ b/apps/opencs/model/filter/booleannode.cpp @@ -1,7 +1,7 @@ #include "booleannode.hpp" -CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true) {} +CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {} bool CSMFilter::BooleanNode::test (const CSMWorld::IdTable& table, int row, const std::map& otherFilters, From ea8b9ce45b76923a4c52a66fe3f1c3b3d9d3d114 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 18 Aug 2013 16:53:28 +0200 Subject: [PATCH 09/24] apply filter to table after filter text change --- apps/opencs/model/filter/node.hpp | 6 +++++ apps/opencs/model/world/idtableproxymodel.cpp | 23 +++++++++++++++++++ apps/opencs/model/world/idtableproxymodel.hpp | 16 ++++++++++++- apps/opencs/view/filter/editwidget.cpp | 2 +- apps/opencs/view/filter/editwidget.hpp | 6 ++++- apps/opencs/view/filter/filterbox.cpp | 8 ++++++- apps/opencs/view/filter/filterbox.hpp | 7 ++++++ apps/opencs/view/filter/recordfilterbox.cpp | 10 ++++++-- apps/opencs/view/filter/recordfilterbox.hpp | 9 ++++++++ apps/opencs/view/world/table.cpp | 6 +++++ apps/opencs/view/world/table.hpp | 4 ++++ apps/opencs/view/world/tablesubview.cpp | 8 ++++++- 12 files changed, 98 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/filter/node.hpp b/apps/opencs/model/filter/node.hpp index 09bc3cd42..9743034ba 100644 --- a/apps/opencs/model/filter/node.hpp +++ b/apps/opencs/model/filter/node.hpp @@ -5,6 +5,10 @@ #include #include +#include + +#include + namespace CSMWorld { class IdTable; @@ -55,4 +59,6 @@ namespace CSMFilter }; } +Q_DECLARE_METATYPE (boost::shared_ptr) + #endif diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index e99e1575c..e2c862270 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -1,8 +1,23 @@ #include "idtableproxymodel.hpp" +#include +#include + #include "idtable.hpp" +bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) + const +{ + if (!mFilter) + return true; + + std::map otherFilters; /// \todo get other filters; + std::map columns; /// \todo get columns + + return mFilter->test (dynamic_cast (*sourceModel()), sourceRow, otherFilters, columns, mUserValue); +} + CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) : QSortFilterProxyModel (parent) {} @@ -10,4 +25,12 @@ CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const { return mapFromSource (dynamic_cast (*sourceModel()).getModelIndex (id, column)); +} + +void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr& filter, + const std::string& userValue) +{ + mFilter = filter; + mUserValue = userValue; + invalidateFilter(); } \ No newline at end of file diff --git a/apps/opencs/model/world/idtableproxymodel.hpp b/apps/opencs/model/world/idtableproxymodel.hpp index 200b99fe2..c7dcd345a 100644 --- a/apps/opencs/model/world/idtableproxymodel.hpp +++ b/apps/opencs/model/world/idtableproxymodel.hpp @@ -1,9 +1,13 @@ #ifndef CSM_WOLRD_IDTABLEPROXYMODEL_H #define CSM_WOLRD_IDTABLEPROXYMODEL_H +#include + +#include + #include -#include +#include "../filter/node.hpp" namespace CSMWorld { @@ -11,11 +15,21 @@ namespace CSMWorld { Q_OBJECT + boost::shared_ptr mFilter; + std::string mUserValue; + + private: + + bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const; + public: IdTableProxyModel (QObject *parent = 0); virtual QModelIndex getModelIndex (const std::string& id, int column) const; + + void setFilter (const boost::shared_ptr& filter, + const std::string& userValue); }; } diff --git a/apps/opencs/view/filter/editwidget.cpp b/apps/opencs/view/filter/editwidget.cpp index 8fc4a88ae..b8853ffa3 100644 --- a/apps/opencs/view/filter/editwidget.cpp +++ b/apps/opencs/view/filter/editwidget.cpp @@ -12,7 +12,7 @@ void CSVFilter::EditWidget::textChanged (const QString& text) mParser.parse (text.toUtf8().constData()); if (mParser.getState()==CSMFilter::Parser::State_End) - emit filterChanged(); + emit filterChanged (mParser.getFilter(), ""); else { /// \todo error handling diff --git a/apps/opencs/view/filter/editwidget.hpp b/apps/opencs/view/filter/editwidget.hpp index 5959a8b16..9c4b1fa16 100644 --- a/apps/opencs/view/filter/editwidget.hpp +++ b/apps/opencs/view/filter/editwidget.hpp @@ -1,9 +1,12 @@ #ifndef CSV_FILTER_EDITWIDGET_H #define CSV_FILTER_EDITWIDGET_H +#include + #include #include "../../model/filter/parser.hpp" +#include "../../model/filter/node.hpp" namespace CSVFilter { @@ -19,7 +22,8 @@ namespace CSVFilter signals: - void filterChanged(); + void filterChanged (boost::shared_ptr filter, + const std::string& userValue); private slots: diff --git a/apps/opencs/view/filter/filterbox.cpp b/apps/opencs/view/filter/filterbox.cpp index f3f17706b..9da08d3ba 100644 --- a/apps/opencs/view/filter/filterbox.cpp +++ b/apps/opencs/view/filter/filterbox.cpp @@ -12,7 +12,13 @@ CSVFilter::FilterBox::FilterBox (QWidget *parent) layout->setContentsMargins (0, 0, 0, 0); - layout->addWidget (new RecordFilterBox (this)); + RecordFilterBox *recordFilterBox = new RecordFilterBox (this); + + layout->addWidget (recordFilterBox); setLayout (layout); + + connect (recordFilterBox, + SIGNAL (filterChanged (boost::shared_ptr, const std::string&)), + this, SIGNAL (recordFilterChanged (boost::shared_ptr, const std::string&))); } \ No newline at end of file diff --git a/apps/opencs/view/filter/filterbox.hpp b/apps/opencs/view/filter/filterbox.hpp index 969a43cd7..5f260003a 100644 --- a/apps/opencs/view/filter/filterbox.hpp +++ b/apps/opencs/view/filter/filterbox.hpp @@ -3,6 +3,8 @@ #include +#include "../../model/filter/node.hpp" + namespace CSVFilter { class FilterBox : public QWidget @@ -12,6 +14,11 @@ namespace CSVFilter public: FilterBox (QWidget *parent = 0); + + signals: + + void recordFilterChanged (boost::shared_ptr filter, + const std::string& userValue); }; } diff --git a/apps/opencs/view/filter/recordfilterbox.cpp b/apps/opencs/view/filter/recordfilterbox.cpp index 5e297ec38..c4b516f03 100644 --- a/apps/opencs/view/filter/recordfilterbox.cpp +++ b/apps/opencs/view/filter/recordfilterbox.cpp @@ -15,7 +15,13 @@ CSVFilter::RecordFilterBox::RecordFilterBox (QWidget *parent) layout->addWidget (new QLabel ("Record Filter", this)); - layout->addWidget (new EditWidget (this)); + EditWidget *editWidget = new EditWidget (this); + + layout->addWidget (editWidget); setLayout (layout); -} \ No newline at end of file + + connect ( + editWidget, SIGNAL (filterChanged (boost::shared_ptr, const std::string&)), + this, SIGNAL (filterChanged (boost::shared_ptr, const std::string&))); +} diff --git a/apps/opencs/view/filter/recordfilterbox.hpp b/apps/opencs/view/filter/recordfilterbox.hpp index 3a411f808..8fc1e263b 100644 --- a/apps/opencs/view/filter/recordfilterbox.hpp +++ b/apps/opencs/view/filter/recordfilterbox.hpp @@ -1,10 +1,14 @@ #ifndef CSV_FILTER_RECORDFILTERBOX_H #define CSV_FILTER_RECORDFILTERBOX_H +#include + #include #include +#include "../../model/filter/node.hpp" + namespace CSVFilter { class RecordFilterBox : public QWidget @@ -14,6 +18,11 @@ namespace CSVFilter public: RecordFilterBox (QWidget *parent = 0); + + signals: + + void filterChanged (boost::shared_ptr filter, + const std::string& userValue); }; } diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 4ae25d10b..cc84e612d 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -292,4 +292,10 @@ void CSVWorld::Table::requestFocus (const std::string& id) if (index.isValid()) scrollTo (index, QAbstractItemView::PositionAtTop); +} + +void CSVWorld::Table::recordFilterChanged (boost::shared_ptr filter, + const std::string& userValue) +{ + mProxyModel->setFilter (filter, userValue); } \ No newline at end of file diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 0c24e7b54..2e24e46a5 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -6,6 +6,8 @@ #include +#include "../../model/filter/node.hpp" + class QUndoStack; class QAction; @@ -85,6 +87,8 @@ namespace CSVWorld void requestFocus (const std::string& id); + void recordFilterChanged (boost::shared_ptr filter, + const std::string& userValue); }; } diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index df95940c9..cb6f430c1 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -25,7 +25,9 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout->insertWidget (0, mTable = new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete()), 2); - layout->insertWidget (0, new CSVFilter::FilterBox (this)); + CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (this); + + layout->insertWidget (0, filterBox); QWidget *widget = new QWidget; @@ -48,6 +50,10 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D connect (mBottom, SIGNAL (requestFocus (const std::string&)), mTable, SLOT (requestFocus (const std::string&))); + + connect (filterBox, + SIGNAL (recordFilterChanged (boost::shared_ptr, const std::string&)), + mTable, SLOT (recordFilterChanged (boost::shared_ptr, const std::string&))); } void CSVWorld::TableSubView::setEditLock (bool locked) From c7e97a83e195891c758fd8175f80986d9b4f42a5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 18 Aug 2013 17:28:04 +0200 Subject: [PATCH 10/24] automatically build column map on filter change --- apps/opencs/model/world/idtableproxymodel.cpp | 22 ++++++++++++++++--- apps/opencs/model/world/idtableproxymodel.hpp | 5 +++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index e2c862270..4bb440ce7 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -1,11 +1,26 @@ #include "idtableproxymodel.hpp" -#include #include #include "idtable.hpp" +void CSMWorld::IdTableProxyModel::updateColumnMap() +{ + mColumnMap.clear(); + + if (mFilter) + { + std::vector columns = mFilter->getReferencedColumns(); + + const IdTable& table = dynamic_cast (*sourceModel()); + + for (std::vector::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter) + mColumnMap.insert (std::make_pair (*iter, + table.searchColumnIndex (static_cast (*iter)))); + } +} + bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const { @@ -13,9 +28,9 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI return true; std::map otherFilters; /// \todo get other filters; - std::map columns; /// \todo get columns - return mFilter->test (dynamic_cast (*sourceModel()), sourceRow, otherFilters, columns, mUserValue); + return mFilter->test ( + dynamic_cast (*sourceModel()), sourceRow, otherFilters, mColumnMap, mUserValue); } CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) @@ -32,5 +47,6 @@ void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr +#include + #include #include "../filter/node.hpp" @@ -17,9 +19,12 @@ namespace CSMWorld boost::shared_ptr mFilter; std::string mUserValue; + std::map mColumnMap; // column ID, column index in this model (or -1) private: + void updateColumnMap(); + bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const; public: From c87a2794449b69eec4489b5f291188938e8e3d3c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 18 Aug 2013 17:54:18 +0200 Subject: [PATCH 11/24] added error reporting in the filter edit widget (change the text colour for now) --- apps/opencs/model/filter/parser.cpp | 50 ++++++++++++++++++++++++-- apps/opencs/model/filter/parser.hpp | 8 +++++ apps/opencs/view/filter/editwidget.cpp | 10 +++++- apps/opencs/view/filter/editwidget.hpp | 2 ++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index 46052cec6..06a974bbe 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -5,6 +5,37 @@ #include "booleannode.hpp" +namespace CSMFilter +{ + struct Token + { + enum Type + { + Type_EOS, + Type_None + }; + + Type mType; + + Token (Type type); + }; + + Token::Token (Type type) : mType (type) {} +} + +CSMFilter::Token CSMFilter::Parser::getNextToken (const std::string& filter, int& index) const +{ + if (index>=static_cast (filter.size())) + return Token (Token::Type_EOS); + + return Token (Token::Type_None); +} + +bool CSMFilter::Parser::isEndState() const +{ + return mState==State_End || mState==State_UnexpectedCharacter; +} + CSMFilter::Parser::Parser() : mState (State_Begin) {} void CSMFilter::Parser::parse (const std::string& filter) @@ -12,11 +43,24 @@ void CSMFilter::Parser::parse (const std::string& filter) // reset mState = State_Begin; mFilter.reset(); + int index = 0; + + while (!isEndState()) + { + Token token = getNextToken (filter, index); + switch (token.mType) + { + case Token::Type_None: mState = State_UnexpectedCharacter; break; + case Token::Type_EOS: mState = State_End; break; + } + } - // for now we ignore the filter string - mFilter.reset (new BooleanNode (false)); - mState = State_End; + if (mState==State_End && !mFilter) + { + // Empty filter string equals to filter "true". + mFilter.reset (new BooleanNode (true)); + } } CSMFilter::Parser::State CSMFilter::Parser::getState() const diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index 72dc7d507..2d616b9e1 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -7,6 +7,8 @@ namespace CSMFilter { + struct Token; + class Parser { public: @@ -14,6 +16,7 @@ namespace CSMFilter enum State { State_Begin, + State_UnexpectedCharacter, State_End }; @@ -22,6 +25,11 @@ namespace CSMFilter State mState; boost::shared_ptr mFilter; + Token getNextToken (const std::string& filter, int& index) const; + + bool isEndState() const; + ///< This includes error states. + public: Parser(); diff --git a/apps/opencs/view/filter/editwidget.cpp b/apps/opencs/view/filter/editwidget.cpp index b8853ffa3..79cbc1dce 100644 --- a/apps/opencs/view/filter/editwidget.cpp +++ b/apps/opencs/view/filter/editwidget.cpp @@ -4,6 +4,7 @@ CSVFilter::EditWidget::EditWidget (QWidget *parent) : QLineEdit (parent) { + mPalette = palette(); connect (this, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&))); } @@ -12,9 +13,16 @@ void CSVFilter::EditWidget::textChanged (const QString& text) mParser.parse (text.toUtf8().constData()); if (mParser.getState()==CSMFilter::Parser::State_End) + { + setPalette (mPalette); emit filterChanged (mParser.getFilter(), ""); + } else { - /// \todo error handling + QPalette palette (mPalette); + palette.setColor (QPalette::Text, Qt::red); + setPalette (palette); + + /// \todo improve error reporting; mark only the faulty part } } \ No newline at end of file diff --git a/apps/opencs/view/filter/editwidget.hpp b/apps/opencs/view/filter/editwidget.hpp index 9c4b1fa16..4e692fc4d 100644 --- a/apps/opencs/view/filter/editwidget.hpp +++ b/apps/opencs/view/filter/editwidget.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "../../model/filter/parser.hpp" #include "../../model/filter/node.hpp" @@ -15,6 +16,7 @@ namespace CSVFilter Q_OBJECT CSMFilter::Parser mParser; + QPalette mPalette; public: From a61215dab1c6b486feec67d420a8fe199287e8aa Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 20 Aug 2013 16:04:06 +0200 Subject: [PATCH 12/24] some general filter parser cleanup --- apps/opencs/model/filter/parser.cpp | 226 ++++++++++++++++++++++--- apps/opencs/model/filter/parser.hpp | 34 ++-- apps/opencs/view/filter/editwidget.cpp | 4 +- 3 files changed, 220 insertions(+), 44 deletions(-) diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index 06a974bbe..305bf7a7d 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -1,7 +1,11 @@ #include "parser.hpp" +#include #include +#include + +#include #include "booleannode.hpp" @@ -12,65 +16,239 @@ namespace CSMFilter enum Type { Type_EOS, - Type_None + Type_None, + Type_String, + Type_Number, + Type_Open, + Type_Close, + Type_OpenSquare, + Type_CloseSquare, + Type_Comma, + Type_Keyword_True, ///< \attention Keyword enums must be arranged continuously. + Type_Keyword_False, + Type_Keyword_And, + Type_Keyword_Or, + Type_Keyword_Not }; Type mType; + std::string mString; + double mNumber; Token (Type type); + + Token (const std::string& string); + + Token (double number); + + operator bool() const; }; Token::Token (Type type) : mType (type) {} + + Token::Token (const std::string& string) : mType (Type_String), mString (string) {} + + Token::Token (double number) : mType (Type_Number), mNumber (number) {} + + Token::operator bool() const + { + return mType!=Type_None; + } + + bool operator== (const Token& left, const Token& right) + { + if (left.mType!=right.mType) + return false; + + switch (left.mType) + { + case Token::Type_String: return left.mString==right.mString; + case Token::Type_Number: return left.mNumber==right.mNumber; + + default: return true; + } + } } -CSMFilter::Token CSMFilter::Parser::getNextToken (const std::string& filter, int& index) const +CSMFilter::Token CSMFilter::Parser::getStringToken() { - if (index>=static_cast (filter.size())) + std::string string; + + int size = static_cast (mInput.size()); + + for (; mIndex1) + { + ++mIndex; + break; + } + }; + + if (!string.empty()) + { + if (string[0]=='"' && (string[string.size()-1]!='"' || string.size()<2) ) + { + error(); + return Token (Token::Type_None); + } + + if (string[0]!='"' && string[string.size()-1]=='"') + { + error(); + return Token (Token::Type_None); + } + } + + return checkKeywords (string); +} + +CSMFilter::Token CSMFilter::Parser::getNumberToken() +{ + std::string string; + + int size = static_cast (mInput.size()); + + bool hasDecimalPoint = false; + bool hasDigit = false; + + for (; mIndex> value; + + return value; +} + +CSMFilter::Token CSMFilter::Parser::checkKeywords (const Token& token) +{ + static const char *sKeywords[] = + { + "true", "false", + "and", "or", "not", + 0 + }; + + std::string string = Misc::StringUtils::lowerCase (token.mString); + + for (int i=0; sKeywords[i]; ++i) + if (sKeywords[i]==string) + return Token (static_cast (i+Token::Type_Keyword_True)); + + return token; +} + +CSMFilter::Token CSMFilter::Parser::getNextToken() +{ + int size = static_cast (mInput.size()); + + char c = 0; + + for (; mIndex=size) return Token (Token::Type_EOS); + switch (c) + { + case '(': ++mIndex; return Token (Token::Type_Open); + case ')': ++mIndex; return Token (Token::Type_Close); + case '[': ++mIndex; return Token (Token::Type_OpenSquare); + case ']': ++mIndex; return Token (Token::Type_CloseSquare); + case ',': ++mIndex; return Token (Token::Type_Comma); + } + + if (c=='"' || c=='_' || std::isalpha (c)) + return getStringToken(); + + if (c=='-' || c=='.' || std::isdigit (c)) + return getNumberToken(); + + error(); return Token (Token::Type_None); } -bool CSMFilter::Parser::isEndState() const +boost::shared_ptr CSMFilter::Parser::parseImp() { - return mState==State_End || mState==State_UnexpectedCharacter; + + + + return boost::shared_ptr(); } -CSMFilter::Parser::Parser() : mState (State_Begin) {} +void CSMFilter::Parser::error() +{ + mError = true; +} -void CSMFilter::Parser::parse (const std::string& filter) +CSMFilter::Parser::Parser() : mIndex (0), mError (false) {} + +bool CSMFilter::Parser::parse (const std::string& filter) { // reset - mState = State_Begin; mFilter.reset(); - int index = 0; + mError = false; + mInput = filter; + mIndex = 0; - while (!isEndState()) - { - Token token = getNextToken (filter, index); + boost::shared_ptr node = parseImp(); - switch (token.mType) - { - case Token::Type_None: mState = State_UnexpectedCharacter; break; - case Token::Type_EOS: mState = State_End; break; - } - } + if (mError) + return false; - if (mState==State_End && !mFilter) + if (node) + mFilter = node; + else { // Empty filter string equals to filter "true". mFilter.reset (new BooleanNode (true)); } -} -CSMFilter::Parser::State CSMFilter::Parser::getState() const -{ - return mState; + return true; } boost::shared_ptr CSMFilter::Parser::getFilter() const { - if (mState!=State_End) + if (mError) throw std::logic_error ("No filter available"); return mFilter; diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index 2d616b9e1..4341fae9f 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -11,36 +11,36 @@ namespace CSMFilter class Parser { - public: + boost::shared_ptr mFilter; + std::string mInput; + int mIndex; + bool mError; - enum State - { - State_Begin, - State_UnexpectedCharacter, - State_End - }; + Token getStringToken(); - private: + Token getNumberToken(); - State mState; - boost::shared_ptr mFilter; + Token getNextToken(); - Token getNextToken (const std::string& filter, int& index) const; + Token checkKeywords (const Token& token); + ///< Turn string token into keyword token, if possible. - bool isEndState() const; - ///< This includes error states. + boost::shared_ptr parseImp(); + ///< Will return a null-pointer, if there is nothing more to parse. + + void error(); public: Parser(); - void parse (const std::string& filter); + bool parse (const std::string& filter); ///< Discards any previous calls to parse - - State getState() const; + /// + /// \return Success? boost::shared_ptr getFilter() const; - ///< Throws an exception if getState()!=State_End + ///< Throws an exception if the last call to parse did not return true. }; } diff --git a/apps/opencs/view/filter/editwidget.cpp b/apps/opencs/view/filter/editwidget.cpp index 79cbc1dce..793e0504e 100644 --- a/apps/opencs/view/filter/editwidget.cpp +++ b/apps/opencs/view/filter/editwidget.cpp @@ -10,9 +10,7 @@ CSVFilter::EditWidget::EditWidget (QWidget *parent) void CSVFilter::EditWidget::textChanged (const QString& text) { - mParser.parse (text.toUtf8().constData()); - - if (mParser.getState()==CSMFilter::Parser::State_End) + if (mParser.parse (text.toUtf8().constData())) { setPalette (mPalette); emit filterChanged (mParser.getFilter(), ""); From 50041fc2112f4bc12e17ffdcda2d36cd236ad61c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 09:17:57 +0200 Subject: [PATCH 13/24] simplified filter system by taking out filter references and user values for now (these are post-1.0 features anyway) --- apps/opencs/model/filter/booleannode.cpp | 4 +--- apps/opencs/model/filter/booleannode.hpp | 4 +--- apps/opencs/model/filter/leafnode.cpp | 10 -------- apps/opencs/model/filter/leafnode.hpp | 6 ----- apps/opencs/model/filter/narynode.cpp | 24 ------------------- apps/opencs/model/filter/narynode.hpp | 5 ---- apps/opencs/model/filter/node.hpp | 10 +------- apps/opencs/model/filter/unarynode.cpp | 9 ------- apps/opencs/model/filter/unarynode.hpp | 5 ---- apps/opencs/model/world/idtableproxymodel.cpp | 8 ++----- apps/opencs/model/world/idtableproxymodel.hpp | 4 +--- apps/opencs/view/world/table.cpp | 5 ++-- apps/opencs/view/world/table.hpp | 3 +-- 13 files changed, 9 insertions(+), 88 deletions(-) diff --git a/apps/opencs/model/filter/booleannode.cpp b/apps/opencs/model/filter/booleannode.cpp index 2f521ed06..267e06a64 100644 --- a/apps/opencs/model/filter/booleannode.cpp +++ b/apps/opencs/model/filter/booleannode.cpp @@ -4,9 +4,7 @@ CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {} bool CSMFilter::BooleanNode::test (const CSMWorld::IdTable& table, int row, - const std::map& otherFilters, - const std::map& columns, - const std::string& userValue) const + const std::map& columns) const { return mTrue; } diff --git a/apps/opencs/model/filter/booleannode.hpp b/apps/opencs/model/filter/booleannode.hpp index 3578c7f3f..d19219e35 100644 --- a/apps/opencs/model/filter/booleannode.hpp +++ b/apps/opencs/model/filter/booleannode.hpp @@ -14,9 +14,7 @@ namespace CSMFilter BooleanNode (bool true_); virtual bool test (const CSMWorld::IdTable& table, int row, - const std::map& otherFilters, - const std::map& columns, - const std::string& userValue) const; + const std::map& columns) const; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/filter/leafnode.cpp b/apps/opencs/model/filter/leafnode.cpp index 5c6d4b042..a1330f9dc 100644 --- a/apps/opencs/model/filter/leafnode.cpp +++ b/apps/opencs/model/filter/leafnode.cpp @@ -1,11 +1,6 @@ #include "leafnode.hpp" -std::vector CSMFilter::LeafNode::getReferencedFilters() const -{ - return std::vector(); -} - std::vector CSMFilter::LeafNode::getReferencedColumns() const { return std::vector(); @@ -15,8 +10,3 @@ bool CSMFilter::LeafNode::isSimple() const { return true; } - -bool CSMFilter::LeafNode::hasUserValue() const -{ - return false; -} \ No newline at end of file diff --git a/apps/opencs/model/filter/leafnode.hpp b/apps/opencs/model/filter/leafnode.hpp index 663083ff9..2b0163065 100644 --- a/apps/opencs/model/filter/leafnode.hpp +++ b/apps/opencs/model/filter/leafnode.hpp @@ -11,18 +11,12 @@ namespace CSMFilter { public: - virtual std::vector getReferencedFilters() const; - ///< Return a list of filters that are used by this node (and must be passed as - /// otherFilters when calling test). - virtual std::vector 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 bool isSimple() const; ///< \return Can this filter be displayed in simple mode. - - virtual bool hasUserValue() const; }; } diff --git a/apps/opencs/model/filter/narynode.cpp b/apps/opencs/model/filter/narynode.cpp index 0756f6707..cc131d8ac 100644 --- a/apps/opencs/model/filter/narynode.cpp +++ b/apps/opencs/model/filter/narynode.cpp @@ -15,21 +15,6 @@ const CSMFilter::Node& CSMFilter::NAryNode::operator[] (int index) const return *mNodes.at (index); } -std::vector CSMFilter::NAryNode::getReferencedFilters() const -{ - std::vector filters; - - for (std::vector >::const_iterator iter (mNodes.begin()); - iter!=mNodes.end(); ++iter) - { - std::vector filters2 = (*iter)->getReferencedFilters(); - - filters.insert (filters.end(), filters2.begin(), filters2.end()); - } - - return filters; -} - std::vector CSMFilter::NAryNode::getReferencedColumns() const { std::vector columns; @@ -50,12 +35,3 @@ bool CSMFilter::NAryNode::isSimple() const return false; } -bool CSMFilter::NAryNode::hasUserValue() const -{ - for (std::vector >::const_iterator iter (mNodes.begin()); - iter!=mNodes.end(); ++iter) - if ((*iter)->hasUserValue()) - return true; - - return false; -} diff --git a/apps/opencs/model/filter/narynode.hpp b/apps/opencs/model/filter/narynode.hpp index 65e12d1ed..5d8d5653b 100644 --- a/apps/opencs/model/filter/narynode.hpp +++ b/apps/opencs/model/filter/narynode.hpp @@ -21,10 +21,6 @@ namespace CSMFilter const Node& operator[] (int index) const; - virtual std::vector getReferencedFilters() const; - ///< Return a list of filters that are used by this node (and must be passed as - /// otherFilters when calling test). - virtual std::vector 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. @@ -32,7 +28,6 @@ namespace CSMFilter virtual bool isSimple() const; ///< \return Can this filter be displayed in simple mode. - virtual bool hasUserValue() const; }; } diff --git a/apps/opencs/model/filter/node.hpp b/apps/opencs/model/filter/node.hpp index 9743034ba..6783c3b5e 100644 --- a/apps/opencs/model/filter/node.hpp +++ b/apps/opencs/model/filter/node.hpp @@ -33,16 +33,10 @@ namespace CSMFilter virtual ~Node(); virtual bool test (const CSMWorld::IdTable& table, int row, - const std::map& otherFilters, - const std::map& columns, - const std::string& userValue) const = 0; + const std::map& columns) const = 0; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping - virtual std::vector getReferencedFilters() const = 0; - ///< Return a list of filters that are used by this node (and must be passed as - /// otherFilters when calling test). - virtual std::vector getReferencedColumns() const = 0; ///< 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. @@ -50,8 +44,6 @@ namespace CSMFilter virtual bool isSimple() const = 0; ///< \return Can this filter be displayed in simple mode. - virtual bool hasUserValue() const = 0; - virtual std::string toString (bool numericColumns) const = 0; ///< Return a string that represents this node. /// diff --git a/apps/opencs/model/filter/unarynode.cpp b/apps/opencs/model/filter/unarynode.cpp index 490d95376..d687b6468 100644 --- a/apps/opencs/model/filter/unarynode.cpp +++ b/apps/opencs/model/filter/unarynode.cpp @@ -13,11 +13,6 @@ CSMFilter::Node& CSMFilter::UnaryNode::getChild() return *mChild; } -std::vector CSMFilter::UnaryNode::getReferencedFilters() const -{ - return mChild->getReferencedFilters(); -} - std::vector CSMFilter::UnaryNode::getReferencedColumns() const { return mChild->getReferencedColumns(); @@ -28,7 +23,3 @@ bool CSMFilter::UnaryNode::isSimple() const return false; } -bool CSMFilter::UnaryNode::hasUserValue() const -{ - return mChild->hasUserValue(); -} diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp index 4e1fb0cc2..6483a730f 100644 --- a/apps/opencs/model/filter/unarynode.hpp +++ b/apps/opencs/model/filter/unarynode.hpp @@ -19,10 +19,6 @@ namespace CSMFilter Node& getChild(); - virtual std::vector getReferencedFilters() const; - ///< Return a list of filters that are used by this node (and must be passed as - /// otherFilters when calling test). - virtual std::vector 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. @@ -30,7 +26,6 @@ namespace CSMFilter virtual bool isSimple() const; ///< \return Can this filter be displayed in simple mode. - virtual bool hasUserValue() const; }; } diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index 4bb440ce7..2b757adfe 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -27,10 +27,8 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI if (!mFilter) return true; - std::map otherFilters; /// \todo get other filters; - return mFilter->test ( - dynamic_cast (*sourceModel()), sourceRow, otherFilters, mColumnMap, mUserValue); + dynamic_cast (*sourceModel()), sourceRow, mColumnMap); } CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) @@ -42,11 +40,9 @@ QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, i return mapFromSource (dynamic_cast (*sourceModel()).getModelIndex (id, column)); } -void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr& filter, - const std::string& userValue) +void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr& filter) { mFilter = filter; - mUserValue = userValue; updateColumnMap(); invalidateFilter(); } \ No newline at end of file diff --git a/apps/opencs/model/world/idtableproxymodel.hpp b/apps/opencs/model/world/idtableproxymodel.hpp index 40bf6d4d9..b63dccd5e 100644 --- a/apps/opencs/model/world/idtableproxymodel.hpp +++ b/apps/opencs/model/world/idtableproxymodel.hpp @@ -18,7 +18,6 @@ namespace CSMWorld Q_OBJECT boost::shared_ptr mFilter; - std::string mUserValue; std::map mColumnMap; // column ID, column index in this model (or -1) private: @@ -33,8 +32,7 @@ namespace CSMWorld virtual QModelIndex getModelIndex (const std::string& id, int column) const; - void setFilter (const boost::shared_ptr& filter, - const std::string& userValue); + void setFilter (const boost::shared_ptr& filter); }; } diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index cc84e612d..75cbddc2a 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -294,8 +294,7 @@ void CSVWorld::Table::requestFocus (const std::string& id) scrollTo (index, QAbstractItemView::PositionAtTop); } -void CSVWorld::Table::recordFilterChanged (boost::shared_ptr filter, - const std::string& userValue) +void CSVWorld::Table::recordFilterChanged (boost::shared_ptr filter) { - mProxyModel->setFilter (filter, userValue); + mProxyModel->setFilter (filter); } \ No newline at end of file diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 2e24e46a5..d93109056 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -87,8 +87,7 @@ namespace CSVWorld void requestFocus (const std::string& id); - void recordFilterChanged (boost::shared_ptr filter, - const std::string& userValue); + void recordFilterChanged (boost::shared_ptr filter); }; } From 806e9a28880a9379c5bcc4c3a906dbc1538b6a4b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 13:14:35 +0200 Subject: [PATCH 14/24] added and and or filter nodes --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/filter/andnode.cpp | 20 +++++ apps/opencs/model/filter/andnode.hpp | 23 ++++++ apps/opencs/model/filter/narynode.cpp | 31 +++++++- apps/opencs/model/filter/narynode.hpp | 9 ++- apps/opencs/model/filter/ornode.cpp | 20 +++++ apps/opencs/model/filter/ornode.hpp | 23 ++++++ apps/opencs/model/filter/parser.cpp | 82 +++++++++++++++++++++ apps/opencs/model/filter/parser.hpp | 2 + apps/opencs/view/filter/editwidget.cpp | 2 +- apps/opencs/view/filter/editwidget.hpp | 3 +- apps/opencs/view/filter/filterbox.cpp | 4 +- apps/opencs/view/filter/filterbox.hpp | 3 +- apps/opencs/view/filter/recordfilterbox.cpp | 4 +- apps/opencs/view/filter/recordfilterbox.hpp | 3 +- apps/opencs/view/world/tablesubview.cpp | 4 +- 16 files changed, 218 insertions(+), 17 deletions(-) create mode 100644 apps/opencs/model/filter/andnode.cpp create mode 100644 apps/opencs/model/filter/andnode.hpp create mode 100644 apps/opencs/model/filter/ornode.cpp create mode 100644 apps/opencs/model/filter/ornode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 031c650df..9fb6c1be3 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -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 diff --git a/apps/opencs/model/filter/andnode.cpp b/apps/opencs/model/filter/andnode.cpp new file mode 100644 index 000000000..dfaa56e78 --- /dev/null +++ b/apps/opencs/model/filter/andnode.cpp @@ -0,0 +1,20 @@ + +#include "andnode.hpp" + +#include + +CSMFilter::AndNode::AndNode (const std::vector >& nodes) +: NAryNode (nodes, "and") +{} + +bool CSMFilter::AndNode::test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const +{ + int size = getSize(); + + for (int i=0; i >& nodes); + + virtual bool test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + }; +} + +#endif diff --git a/apps/opencs/model/filter/narynode.cpp b/apps/opencs/model/filter/narynode.cpp index cc131d8ac..b96e7d4b2 100644 --- a/apps/opencs/model/filter/narynode.cpp +++ b/apps/opencs/model/filter/narynode.cpp @@ -1,8 +1,11 @@ #include "narynode.hpp" -CSMFilter::NAryNode::NAryNode (const std::vector >& nodes) -: mNodes (nodes) +#include + +CSMFilter::NAryNode::NAryNode (const std::vector >& nodes, + const std::string& name) +: mNodes (nodes), mName (name) {} int CSMFilter::NAryNode::getSize() const @@ -30,6 +33,30 @@ std::vector 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 +#include #include @@ -12,10 +13,11 @@ namespace CSMFilter class NAryNode : public Node { std::vector > mNodes; + std::string mName; public: - NAryNode (const std::vector >& nodes); + NAryNode (const std::vector >& 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. diff --git a/apps/opencs/model/filter/ornode.cpp b/apps/opencs/model/filter/ornode.cpp new file mode 100644 index 000000000..4fc34e1d5 --- /dev/null +++ b/apps/opencs/model/filter/ornode.cpp @@ -0,0 +1,20 @@ + +#include "ornode.hpp" + +#include + +CSMFilter::OrNode::OrNode (const std::vector >& nodes) +: NAryNode (nodes, "or") +{} + +bool CSMFilter::OrNode::test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const +{ + int size = getSize(); + + for (int i=0; i >& nodes); + + virtual bool test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + }; +} + +#endif diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index 305bf7a7d..a35c4bdfd 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -8,6 +8,8 @@ #include #include "booleannode.hpp" +#include "ornode.hpp" +#include "andnode.hpp" namespace CSMFilter { @@ -209,12 +211,89 @@ CSMFilter::Token CSMFilter::Parser::getNextToken() boost::shared_ptr CSMFilter::Parser::parseImp() { + if (Token token = getNextToken()) + { + switch (token.mType) + { + case Token::Type_Keyword_True: + + return boost::shared_ptr (new BooleanNode (true)); + + case Token::Type_Keyword_False: + + return boost::shared_ptr (new BooleanNode (false)); + + case Token::Type_Keyword_And: + case Token::Type_Keyword_Or: + return parseNAry (token); + case Token::Type_EOS: + + return boost::shared_ptr(); + + default: + + error(); + } + } return boost::shared_ptr(); } +boost::shared_ptr CSMFilter::Parser::parseNAry (const Token& keyword) +{ + std::vector > nodes; + + Token token = getNextToken(); + + if (!token || token.mType!=Token::Type_Open) + { + error(); + return boost::shared_ptr(); + } + + for (;;) + { + boost::shared_ptr node = parseImp(); + + if (mError) + return boost::shared_ptr(); + + if (!node.get()) + { + error(); + return boost::shared_ptr(); + } + + nodes.push_back (node); + + Token token = getNextToken(); + + if (!token || (token.mType!=Token::Type_Close && token.mType!=Token::Type_Comma)) + { + error(); + return boost::shared_ptr(); + } + + if (token.mType==Token::Type_Close) + break; + } + + if (nodes.empty()) + { + error(); + return boost::shared_ptr(); + } + + switch (keyword.mType) + { + case Token::Type_Keyword_And: return boost::shared_ptr (new AndNode (nodes)); + case Token::Type_Keyword_Or: return boost::shared_ptr (new OrNode (nodes)); + default: error(); return boost::shared_ptr(); + } +} + 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 diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index 4341fae9f..d9f14b5d9 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -28,6 +28,8 @@ namespace CSMFilter boost::shared_ptr parseImp(); ///< Will return a null-pointer, if there is nothing more to parse. + boost::shared_ptr parseNAry (const Token& keyword); + void error(); public: diff --git a/apps/opencs/view/filter/editwidget.cpp b/apps/opencs/view/filter/editwidget.cpp index 793e0504e..b691a5e16 100644 --- a/apps/opencs/view/filter/editwidget.cpp +++ b/apps/opencs/view/filter/editwidget.cpp @@ -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 { diff --git a/apps/opencs/view/filter/editwidget.hpp b/apps/opencs/view/filter/editwidget.hpp index 4e692fc4d..76b484de9 100644 --- a/apps/opencs/view/filter/editwidget.hpp +++ b/apps/opencs/view/filter/editwidget.hpp @@ -24,8 +24,7 @@ namespace CSVFilter signals: - void filterChanged (boost::shared_ptr filter, - const std::string& userValue); + void filterChanged (boost::shared_ptr filter); private slots: diff --git a/apps/opencs/view/filter/filterbox.cpp b/apps/opencs/view/filter/filterbox.cpp index 9da08d3ba..495abf871 100644 --- a/apps/opencs/view/filter/filterbox.cpp +++ b/apps/opencs/view/filter/filterbox.cpp @@ -19,6 +19,6 @@ CSVFilter::FilterBox::FilterBox (QWidget *parent) setLayout (layout); connect (recordFilterBox, - SIGNAL (filterChanged (boost::shared_ptr, const std::string&)), - this, SIGNAL (recordFilterChanged (boost::shared_ptr, const std::string&))); + SIGNAL (filterChanged (boost::shared_ptr)), + this, SIGNAL (recordFilterChanged (boost::shared_ptr))); } \ No newline at end of file diff --git a/apps/opencs/view/filter/filterbox.hpp b/apps/opencs/view/filter/filterbox.hpp index 5f260003a..d3806876d 100644 --- a/apps/opencs/view/filter/filterbox.hpp +++ b/apps/opencs/view/filter/filterbox.hpp @@ -17,8 +17,7 @@ namespace CSVFilter signals: - void recordFilterChanged (boost::shared_ptr filter, - const std::string& userValue); + void recordFilterChanged (boost::shared_ptr filter); }; } diff --git a/apps/opencs/view/filter/recordfilterbox.cpp b/apps/opencs/view/filter/recordfilterbox.cpp index c4b516f03..3b5f73f47 100644 --- a/apps/opencs/view/filter/recordfilterbox.cpp +++ b/apps/opencs/view/filter/recordfilterbox.cpp @@ -22,6 +22,6 @@ CSVFilter::RecordFilterBox::RecordFilterBox (QWidget *parent) setLayout (layout); connect ( - editWidget, SIGNAL (filterChanged (boost::shared_ptr, const std::string&)), - this, SIGNAL (filterChanged (boost::shared_ptr, const std::string&))); + editWidget, SIGNAL (filterChanged (boost::shared_ptr)), + this, SIGNAL (filterChanged (boost::shared_ptr))); } diff --git a/apps/opencs/view/filter/recordfilterbox.hpp b/apps/opencs/view/filter/recordfilterbox.hpp index 8fc1e263b..64c1848a8 100644 --- a/apps/opencs/view/filter/recordfilterbox.hpp +++ b/apps/opencs/view/filter/recordfilterbox.hpp @@ -21,8 +21,7 @@ namespace CSVFilter signals: - void filterChanged (boost::shared_ptr filter, - const std::string& userValue); + void filterChanged (boost::shared_ptr filter); }; } diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index cb6f430c1..a43ae2dac 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -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, const std::string&)), - mTable, SLOT (recordFilterChanged (boost::shared_ptr, const std::string&))); + SIGNAL (recordFilterChanged (boost::shared_ptr)), + mTable, SLOT (recordFilterChanged (boost::shared_ptr))); } void CSVWorld::TableSubView::setEditLock (bool locked) From ba6edc55d457f62c9f85850f48278ee49d787187 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 13:45:50 +0200 Subject: [PATCH 15/24] added not filter node --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/filter/notnode.cpp | 10 ++++++++++ apps/opencs/model/filter/notnode.hpp | 21 +++++++++++++++++++++ apps/opencs/model/filter/parser.cpp | 24 ++++++++++++++++-------- apps/opencs/model/filter/parser.hpp | 2 +- apps/opencs/model/filter/unarynode.cpp | 8 +++++++- apps/opencs/model/filter/unarynode.hpp | 11 ++++++++--- 7 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 apps/opencs/model/filter/notnode.cpp create mode 100644 apps/opencs/model/filter/notnode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 9fb6c1be3..c74f0db22 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -108,7 +108,7 @@ opencs_units_noqt (model/settings ) opencs_units_noqt (model/filter - node unarynode narynode leafnode booleannode parser andnode ornode + node unarynode narynode leafnode booleannode parser andnode ornode notnode ) opencs_hdrs_noqt (model/filter diff --git a/apps/opencs/model/filter/notnode.cpp b/apps/opencs/model/filter/notnode.cpp new file mode 100644 index 000000000..1b22ea7a6 --- /dev/null +++ b/apps/opencs/model/filter/notnode.cpp @@ -0,0 +1,10 @@ + +#include "notnode.hpp" + +CSMFilter::NotNode::NotNode (boost::shared_ptr child) : UnaryNode (child, "not") {} + +bool CSMFilter::NotNode::test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const +{ + return !getChild().test (table, row, columns); +} \ No newline at end of file diff --git a/apps/opencs/model/filter/notnode.hpp b/apps/opencs/model/filter/notnode.hpp new file mode 100644 index 000000000..b9e80b8c6 --- /dev/null +++ b/apps/opencs/model/filter/notnode.hpp @@ -0,0 +1,21 @@ +#ifndef CSM_FILTER_NOTNODE_H +#define CSM_FILTER_NOTNODE_H + +#include "unarynode.hpp" + +namespace CSMFilter +{ + class NotNode : public UnaryNode + { + public: + + NotNode (boost::shared_ptr child); + + virtual bool test (const CSMWorld::IdTable& table, int row, + const std::map& columns) const; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + }; +} + +#endif diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index a35c4bdfd..5dd0392e8 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -10,6 +10,7 @@ #include "booleannode.hpp" #include "ornode.hpp" #include "andnode.hpp" +#include "notnode.hpp" namespace CSMFilter { @@ -209,7 +210,7 @@ CSMFilter::Token CSMFilter::Parser::getNextToken() return Token (Token::Type_None); } -boost::shared_ptr CSMFilter::Parser::parseImp() +boost::shared_ptr CSMFilter::Parser::parseImp (bool allowEmpty) { if (Token token = getNextToken()) { @@ -228,8 +229,21 @@ boost::shared_ptr CSMFilter::Parser::parseImp() return parseNAry (token); + case Token::Type_Keyword_Not: + { + boost::shared_ptr node = parseImp(); + + if (mError) + return boost::shared_ptr(); + + return boost::shared_ptr (new NotNode (node)); + } + case Token::Type_EOS: + if (!allowEmpty) + error(); + return boost::shared_ptr(); default: @@ -260,12 +274,6 @@ boost::shared_ptr CSMFilter::Parser::parseNAry (const Token& ke if (mError) return boost::shared_ptr(); - if (!node.get()) - { - error(); - return boost::shared_ptr(); - } - nodes.push_back (node); Token token = getNextToken(); @@ -309,7 +317,7 @@ bool CSMFilter::Parser::parse (const std::string& filter) mInput = filter; mIndex = 0; - boost::shared_ptr node = parseImp(); + boost::shared_ptr node = parseImp (true); if (mError) return false; diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index d9f14b5d9..13c77b09a 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -25,7 +25,7 @@ namespace CSMFilter Token checkKeywords (const Token& token); ///< Turn string token into keyword token, if possible. - boost::shared_ptr parseImp(); + boost::shared_ptr parseImp (bool allowEmpty = false); ///< Will return a null-pointer, if there is nothing more to parse. boost::shared_ptr parseNAry (const Token& keyword); diff --git a/apps/opencs/model/filter/unarynode.cpp b/apps/opencs/model/filter/unarynode.cpp index d687b6468..d1897f4b7 100644 --- a/apps/opencs/model/filter/unarynode.cpp +++ b/apps/opencs/model/filter/unarynode.cpp @@ -1,7 +1,9 @@ #include "unarynode.hpp" -CSMFilter::UnaryNode::UnaryNode (boost::shared_ptr child) : mChild (child) {} +CSMFilter::UnaryNode::UnaryNode (boost::shared_ptr child, const std::string& name) +: mChild (child), mName (name) +{} const CSMFilter::Node& CSMFilter::UnaryNode::getChild() const { @@ -23,3 +25,7 @@ bool CSMFilter::UnaryNode::isSimple() const return false; } +std::string CSMFilter::UnaryNode::toString (bool numericColumns) const +{ + return mName + " " + mChild->toString (numericColumns); +} \ No newline at end of file diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp index 6483a730f..9fd5faf3f 100644 --- a/apps/opencs/model/filter/unarynode.hpp +++ b/apps/opencs/model/filter/unarynode.hpp @@ -1,5 +1,5 @@ -#ifndef CSM_FILTER_UNARIYNODE_H -#define CSM_FILTER_UNARIYNODE_H +#ifndef CSM_FILTER_UNARYNODE_H +#define CSM_FILTER_UNARYNODE_H #include @@ -10,10 +10,11 @@ namespace CSMFilter class UnaryNode : public Node { boost::shared_ptr mChild; + std::string mName; public: - UnaryNode (boost::shared_ptr child); + UnaryNode (boost::shared_ptr child, const std::string& name); const Node& getChild() const; @@ -26,6 +27,10 @@ namespace CSMFilter virtual bool isSimple() const; ///< \return Can this filter be displayed in simple mode. + 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. }; } From decd826208ef06553fe72fd374d50b3af9627742 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 14:00:55 +0200 Subject: [PATCH 16/24] fixed an include guard --- apps/opencs/model/filter/leafnode.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/filter/leafnode.hpp b/apps/opencs/model/filter/leafnode.hpp index 2b0163065..a9790d01d 100644 --- a/apps/opencs/model/filter/leafnode.hpp +++ b/apps/opencs/model/filter/leafnode.hpp @@ -1,5 +1,5 @@ -#ifndef CSM_FILTER_UNARIYNODE_H -#define CSM_FILTER_UNARIYNODE_H +#ifndef CSM_FILTER_LEAFNODE_H +#define CSM_FILTER_LEAFNODE_H #include From de956737fe06a2ef516943ef3d48b847f6adddc5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 14:50:42 +0200 Subject: [PATCH 17/24] added text filter node --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/filter/parser.cpp | 77 ++++++++++++++++++++++++++- apps/opencs/model/filter/parser.hpp | 2 + apps/opencs/model/filter/textnode.cpp | 61 +++++++++++++++++++++ apps/opencs/model/filter/textnode.hpp | 33 ++++++++++++ 5 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/model/filter/textnode.cpp create mode 100644 apps/opencs/model/filter/textnode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index c74f0db22..ea78135b9 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -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 diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index 5dd0392e8..c2562ad1e 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -7,10 +7,13 @@ #include +#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::Parser::parseImp (bool allowEmpty) return boost::shared_ptr (new NotNode (node)); } + case Token::Type_Keyword_Text: + + return parseText(); + case Token::Type_EOS: if (!allowEmpty) @@ -261,7 +270,7 @@ boost::shared_ptr 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(); @@ -302,6 +311,70 @@ boost::shared_ptr CSMFilter::Parser::parseNAry (const Token& ke } } +boost::shared_ptr CSMFilter::Parser::parseText() +{ + Token token = getNextToken(); + + if (token.mType!=Token::Type_Open) + { + error(); + return boost::shared_ptr(); + } + + token = getNextToken(); + + if (!token) + return boost::shared_ptr(); + + // parse column ID + int columnId = -1; + + if (token.mType==Token::Type_Number) + { + if (static_cast (token.mNumber)==token.mNumber) + columnId = static_cast (token.mNumber); + } + else if (token.mType==Token::Type_String) + { + columnId = CSMWorld::Columns::getId (token.mString); + } + + if (columnId<0) + { + error(); + return boost::shared_ptr(); + } + + token = getNextToken(); + + if (token.mType!=Token::Type_Comma) + { + error(); + return boost::shared_ptr(); + } + + // parse text pattern + token = getNextToken(); + + if (token.mType!=Token::Type_String) + { + error(); + return boost::shared_ptr(); + } + + std::string text = token.mString; + + token = getNextToken(); + + if (token.mType!=Token::Type_Close) + { + error(); + return boost::shared_ptr(); + } + + return boost::shared_ptr (new TextNode (columnId, text)); +} + void CSMFilter::Parser::error() { mError = true; diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index 13c77b09a..2512de141 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -30,6 +30,8 @@ namespace CSMFilter boost::shared_ptr parseNAry (const Token& keyword); + boost::shared_ptr parseText(); + void error(); public: diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp new file mode 100644 index 000000000..f95c1ce28 --- /dev/null +++ b/apps/opencs/model/filter/textnode.cpp @@ -0,0 +1,61 @@ + +#include "textnode.hpp" + +#include +#include + +#include + +#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& columns) const +{ + const std::map::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 CSMFilter::TextNode::getReferencedColumns() const +{ + return std::vector (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 (mColumnId)) + << "\""; + + stream << ", \"" << mText << "\")"; + + return stream.str(); +} \ No newline at end of file diff --git a/apps/opencs/model/filter/textnode.hpp b/apps/opencs/model/filter/textnode.hpp new file mode 100644 index 000000000..663fa7382 --- /dev/null +++ b/apps/opencs/model/filter/textnode.hpp @@ -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& columns) const; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + + virtual std::vector 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 From f615a9397bd85643804a332cd0d71b0a65a514ea Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 15:16:22 +0200 Subject: [PATCH 18/24] made text node filter case-insensitive --- apps/opencs/model/filter/textnode.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index f95c1ce28..ec654267b 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -31,7 +31,8 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, if (data.type()!=QVariant::String) return false; - QRegExp regExp(QString::fromUtf8 (mText.c_str())); /// \todo make pattern syntax configurable + /// \todo make pattern syntax configurable + QRegExp regExp (QString::fromUtf8 (mText.c_str()), Qt::CaseInsensitive); return regExp.exactMatch (data.toString()); } From 63b1df85e75fb0f9418993be50b3c1b30fce4b2d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Aug 2013 15:22:39 +0200 Subject: [PATCH 19/24] fixed string parsing --- apps/opencs/model/filter/parser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index c2562ad1e..7c8f9d768 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -113,6 +113,9 @@ CSMFilter::Token CSMFilter::Parser::getStringToken() error(); return Token (Token::Type_None); } + + if (string[0]=='"') + string = string.substr (1, string.size()-2); } return checkKeywords (string); From c56007cceb18662f090ee2f350bb2b69ec7c937c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 23 Aug 2013 14:11:33 +0200 Subject: [PATCH 20/24] fixed a record counting bug (was using the wrong model) --- apps/opencs/view/world/table.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 75cbddc2a..72e78c738 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -257,9 +257,9 @@ void CSVWorld::Table::tableSizeUpdate() int deleted = 0; int modified = 0; - if (mModel->columnCount()>0) + if (mProxyModel->columnCount()>0) { - int rows = mModel->rowCount(); + int rows = mProxyModel->rowCount(); for (int i=0; i Date: Fri, 23 Aug 2013 14:49:41 +0200 Subject: [PATCH 21/24] fixed type in error message --- apps/opencs/model/filter/textnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index ec654267b..9987c66d2 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -19,7 +19,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, const std::map::const_iterator iter = columns.find (mColumnId); if (iter==columns.end()) - throw std::logic_error ("invalid column in test node test"); + throw std::logic_error ("invalid column in text node test"); if (iter->second==-1) return true; From 3cf60da5a70a8b7fa294756dc0fbb982e21ef5c9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 24 Aug 2013 14:43:38 +0200 Subject: [PATCH 22/24] added numeric value filter node --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/filter/parser.cpp | 127 ++++++++++++++++++++++++- apps/opencs/model/filter/parser.hpp | 2 + apps/opencs/model/filter/valuenode.cpp | 71 ++++++++++++++ apps/opencs/model/filter/valuenode.hpp | 37 +++++++ 5 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/model/filter/valuenode.cpp create mode 100644 apps/opencs/model/filter/valuenode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index ea78135b9..ad7b5b19c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -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 diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index 7c8f9d768..5e580b6e1 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -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::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::Parser::parseText() return boost::shared_ptr (new TextNode (columnId, text)); } +boost::shared_ptr CSMFilter::Parser::parseValue() +{ + Token token = getNextToken(); + + if (token.mType!=Token::Type_Open) + { + error(); + return boost::shared_ptr(); + } + + token = getNextToken(); + + if (!token) + return boost::shared_ptr(); + + // parse column ID + int columnId = -1; + + if (token.mType==Token::Type_Number) + { + if (static_cast (token.mNumber)==token.mNumber) + columnId = static_cast (token.mNumber); + } + else if (token.mType==Token::Type_String) + { + columnId = CSMWorld::Columns::getId (token.mString); + } + + if (columnId<0) + { + error(); + return boost::shared_ptr(); + } + + token = getNextToken(); + + if (token.mType!=Token::Type_Comma) + { + error(); + return boost::shared_ptr(); + } + + // 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(); + } + + token = getNextToken(); + + if (token.mType!=Token::Type_Number) + { + error(); + return boost::shared_ptr(); + } + + lower = token.mNumber; + + token = getNextToken(); + + if (token.mType!=Token::Type_Comma) + { + error(); + return boost::shared_ptr(); + } + + token = getNextToken(); + + if (token.mType!=Token::Type_Number) + { + error(); + return boost::shared_ptr(); + } + + 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(); + } + } + + token = getNextToken(); + + if (token.mType!=Token::Type_Close) + { + error(); + return boost::shared_ptr(); + } + + return boost::shared_ptr (new ValueNode (columnId, lower, upper, min, max)); +} + void CSMFilter::Parser::error() { mError = true; diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index 2512de141..1600992b7 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -32,6 +32,8 @@ namespace CSMFilter boost::shared_ptr parseText(); + boost::shared_ptr parseValue(); + void error(); public: diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp new file mode 100644 index 000000000..f6cb20e4c --- /dev/null +++ b/apps/opencs/model/filter/valuenode.cpp @@ -0,0 +1,71 @@ + +#include "valuenode.hpp" + +#include +#include + +#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& columns) const +{ + const std::map::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 CSMFilter::ValueNode::getReferencedColumns() const +{ + return std::vector (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 (mColumnId)) + << "\""; + + stream << ", \""; + + if (mLower==mUpper && mMin && mMax) + stream << mLower; + else + stream << (mMin ? "[" : "(") << mLower << ", " << mUpper << (mMax ? "]" : ")"); + + stream << ")"; + + return stream.str(); +} \ No newline at end of file diff --git a/apps/opencs/model/filter/valuenode.hpp b/apps/opencs/model/filter/valuenode.hpp new file mode 100644 index 000000000..faaa1e2ff --- /dev/null +++ b/apps/opencs/model/filter/valuenode.hpp @@ -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& columns) const; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + + virtual std::vector 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 From cf58670c85619ab33745a6c7f28e6e9228431919 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 24 Aug 2013 14:46:42 +0200 Subject: [PATCH 23/24] removed global filter scope (would have caused sync problems between projects) --- apps/opencs/model/filter/filter.hpp | 7 +++---- apps/opencs/view/filter/filtercreator.cpp | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/filter/filter.hpp b/apps/opencs/model/filter/filter.hpp index 7630ad410..62170ca80 100644 --- a/apps/opencs/model/filter/filter.hpp +++ b/apps/opencs/model/filter/filter.hpp @@ -13,10 +13,9 @@ namespace CSMFilter { enum Scope { - Scope_Global = 0, // per user - Scope_Project = 1, // per project - Scope_Session = 2, // exists only for one editing session; not saved - Scope_Content = 3 // embedded in the edited content file + Scope_Project = 0, // per project + Scope_Session = 1, // exists only for one editing session; not saved + Scope_Content = 2 // embedded in the edited content file }; Scope mScope; diff --git a/apps/opencs/view/filter/filtercreator.cpp b/apps/opencs/view/filter/filtercreator.cpp index 476eacbe1..47925ea57 100644 --- a/apps/opencs/view/filter/filtercreator.cpp +++ b/apps/opencs/view/filter/filtercreator.cpp @@ -10,7 +10,6 @@ std::string CSVFilter::FilterCreator::getNamespace() const { switch (mScope->currentIndex()) { - case CSMFilter::Filter::Scope_Global: return "global::"; case CSMFilter::Filter::Scope_Project: return "project::"; case CSMFilter::Filter::Scope_Session: return "session::"; } @@ -38,7 +37,6 @@ CSVFilter::FilterCreator::FilterCreator (CSMWorld::Data& data, QUndoStack& undoS mScope = new QComboBox (this); - mScope->addItem ("Global"); mScope->addItem ("Project"); mScope->addItem ("Session"); /// \ŧodo re-enable for OpenMW 1.1 @@ -51,7 +49,7 @@ CSVFilter::FilterCreator::FilterCreator (CSMWorld::Data& data, QUndoStack& undoS QLabel *label = new QLabel ("Scope", this); insertAtBeginning (label, false); - mScope->setCurrentIndex (2); + mScope->setCurrentIndex (1); } void CSVFilter::FilterCreator::reset() From 78c7de440d94492490e260777b28030377c64e56 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 24 Aug 2013 14:49:05 +0200 Subject: [PATCH 24/24] simplified filter nodes even more --- apps/opencs/model/filter/leafnode.cpp | 4 ---- apps/opencs/model/filter/leafnode.hpp | 3 --- apps/opencs/model/filter/narynode.cpp | 4 ---- apps/opencs/model/filter/narynode.hpp | 4 ---- apps/opencs/model/filter/node.hpp | 3 --- apps/opencs/model/filter/unarynode.cpp | 5 ----- apps/opencs/model/filter/unarynode.hpp | 3 --- 7 files changed, 26 deletions(-) diff --git a/apps/opencs/model/filter/leafnode.cpp b/apps/opencs/model/filter/leafnode.cpp index a1330f9dc..055a1747c 100644 --- a/apps/opencs/model/filter/leafnode.cpp +++ b/apps/opencs/model/filter/leafnode.cpp @@ -6,7 +6,3 @@ std::vector CSMFilter::LeafNode::getReferencedColumns() const return std::vector(); } -bool CSMFilter::LeafNode::isSimple() const -{ - return true; -} diff --git a/apps/opencs/model/filter/leafnode.hpp b/apps/opencs/model/filter/leafnode.hpp index a9790d01d..2f3d91070 100644 --- a/apps/opencs/model/filter/leafnode.hpp +++ b/apps/opencs/model/filter/leafnode.hpp @@ -14,9 +14,6 @@ namespace CSMFilter virtual std::vector 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 bool isSimple() const; - ///< \return Can this filter be displayed in simple mode. }; } diff --git a/apps/opencs/model/filter/narynode.cpp b/apps/opencs/model/filter/narynode.cpp index b96e7d4b2..98f706c87 100644 --- a/apps/opencs/model/filter/narynode.cpp +++ b/apps/opencs/model/filter/narynode.cpp @@ -57,8 +57,4 @@ std::string CSMFilter::NAryNode::toString (bool numericColumns) const return stream.str(); } -bool CSMFilter::NAryNode::isSimple() const -{ - return false; -} diff --git a/apps/opencs/model/filter/narynode.hpp b/apps/opencs/model/filter/narynode.hpp index 421847fae..aa501d009 100644 --- a/apps/opencs/model/filter/narynode.hpp +++ b/apps/opencs/model/filter/narynode.hpp @@ -31,10 +31,6 @@ namespace CSMFilter ///< 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. - }; } diff --git a/apps/opencs/model/filter/node.hpp b/apps/opencs/model/filter/node.hpp index 6783c3b5e..ef18353a4 100644 --- a/apps/opencs/model/filter/node.hpp +++ b/apps/opencs/model/filter/node.hpp @@ -41,9 +41,6 @@ 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 bool isSimple() const = 0; - ///< \return Can this filter be displayed in simple mode. - virtual std::string toString (bool numericColumns) const = 0; ///< Return a string that represents this node. /// diff --git a/apps/opencs/model/filter/unarynode.cpp b/apps/opencs/model/filter/unarynode.cpp index d1897f4b7..43a24b76a 100644 --- a/apps/opencs/model/filter/unarynode.cpp +++ b/apps/opencs/model/filter/unarynode.cpp @@ -20,11 +20,6 @@ std::vector CSMFilter::UnaryNode::getReferencedColumns() const return mChild->getReferencedColumns(); } -bool CSMFilter::UnaryNode::isSimple() const -{ - return false; -} - std::string CSMFilter::UnaryNode::toString (bool numericColumns) const { return mName + " " + mChild->toString (numericColumns); diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp index 9fd5faf3f..6bbc96092 100644 --- a/apps/opencs/model/filter/unarynode.hpp +++ b/apps/opencs/model/filter/unarynode.hpp @@ -24,9 +24,6 @@ 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 bool isSimple() const; - ///< \return Can this filter be displayed in simple mode. - virtual std::string toString (bool numericColumns) const; ///< Return a string that represents this node. ///