SelectionFilter.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2009 Juergen Riegel (FreeCAD@juergen-riegel.net)        *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifdef __GNUC__
00026 # include <unistd.h>
00027 #endif
00028 
00029 #include <sstream>
00030 
00031 #include <App/Application.h>
00032 #include <App/Document.h>
00033 #include <App/DocumentObjectPy.h>
00034 #include <App/DocumentObject.h>
00035 #include <Base/Interpreter.h>
00036 
00037 #include "Selection.h"
00038 #include "SelectionFilter.h"
00039 //#include "SelectionFilterPy.h"
00040 #include "Application.h"
00041 
00042 using namespace Gui;
00043 
00044 // suppress annoying warnings from generated source files
00045 #ifdef _MSC_VER
00046 # pragma warning(disable : 4003)
00047 # pragma warning(disable : 4018)
00048 # pragma warning(disable : 4065)
00049 # pragma warning(disable : 4335) // disable MAC file format warning on VC
00050 #endif
00051 
00052 
00053 
00054 SelectionFilterGate::SelectionFilterGate(const char* filter)
00055 {
00056     Filter = new SelectionFilter(filter);
00057 }
00058 
00059 SelectionFilterGate::SelectionFilterGate(SelectionFilter* filter)
00060 {
00061     Filter = filter;
00062 }
00063 
00064 SelectionFilterGate::~SelectionFilterGate()
00065 {
00066     delete Filter;
00067 }
00068 
00069 bool SelectionFilterGate::allow(App::Document*pDoc,App::DocumentObject*pObj, const char*sSubName)
00070 {
00071     return Filter->test(pObj,sSubName);
00072 }
00073 
00074 
00075 
00076 SelectionFilter::SelectionFilter(const char* filter)
00077   : Ast(0)
00078 {
00079     setFilter(filter);
00080 }
00081 
00082 SelectionFilter::SelectionFilter(const std::string& filter)
00083   : Ast(0)
00084 {
00085     setFilter(filter.c_str());
00086 }
00087 
00088 void SelectionFilter::setFilter(const char* filter)
00089 {
00090     if( ! filter || filter[0] == 0){
00091         if (Ast)
00092             delete Ast;      
00093         Ast = 0;
00094     }else{
00095         Filter = filter;
00096         if(! parse())
00097             throw Base::Exception(Errors.c_str());
00098     }
00099 }
00100 
00101 SelectionFilter::~SelectionFilter()
00102 {
00103 }
00104 
00105 bool SelectionFilter::match(void)
00106 {
00107     if (!Ast)
00108         return false;
00109     Result.clear();
00110 
00111     for (std::vector< Node_Object *>::iterator it= Ast->Objects.begin();it!=Ast->Objects.end();++it){
00112         int min;
00113         int max;
00114 
00115         if ((*it)->Slice) {
00116             min          = (*it)->Slice->Min;
00117             max          = (*it)->Slice->Max;
00118         }
00119         else {
00120             min          = 1;
00121             max          = 1;
00122         }
00123 
00124         std::vector<Gui::SelectionObject> temp = Gui::Selection().getSelectionEx(0,(*it)->ObjectType);
00125 
00126         // test if subnames present
00127         if((*it)->SubName == ""){
00128             // if no subnames the count of the object get tested
00129             if ((int)temp.size()<min || (int)temp.size()>max)
00130                 return false;
00131         }else{
00132             // if subnames present count all subs over the selected object of type
00133             int subCount=0;
00134             for(std::vector<Gui::SelectionObject>::const_iterator it2=temp.begin();it2!=temp.end();++it2){
00135                 for(std::vector<std::string>::const_iterator it3=it2->getSubNames().begin();it3!=it2->getSubNames().end();++it3)
00136                     if( it3->find((*it)->SubName) != 0)
00137                         return false;
00138                 subCount += it2->getSubNames().size();
00139             }
00140             if(subCount<min || subCount>max)
00141                 return false;
00142         }
00143         Result.push_back(temp);
00144     }
00145     return true;
00146 }
00147 
00148 bool SelectionFilter::test(App::DocumentObject*pObj, const char*sSubName)
00149 {
00150     if (!Ast)
00151         return false;
00152 
00153     for (std::vector< Node_Object *>::iterator it= Ast->Objects.begin();it!=Ast->Objects.end();++it){
00154 
00155         if( pObj->getTypeId().isDerivedFrom((*it)->ObjectType) )
00156         {
00157             if(!sSubName)
00158                 return true;
00159             if((*it)->SubName == "")
00160                 return true;
00161             if( std::string(sSubName).find((*it)->SubName) == 0)
00162                 return true;
00163         }
00164     }
00165     return false;
00166 }
00167 
00168 void SelectionFilter::addError(const char* e)
00169 {
00170     Errors+=e;
00171     Errors += '\n';
00172 }
00173 
00174 
00175 //const App::DocumentObject * SelectionFilter::getObject(void) const
00176 //{
00177 //      if(DocName != ""){
00178 //              App::Document *doc = App::GetApplication().getDocument(DocName.c_str());
00179 //              if(doc && FeatName != "")
00180 //                      return doc->getObject(FeatName.c_str());
00181 //      }
00182 //      return 0;
00183 //}
00184 
00185 
00186 void SelectionFilterPy::init_type()
00187 {
00188     behaviors().name("SelectionFilter");
00189     behaviors().doc("Filter for certain selection");
00190     // you must have overwritten the virtual functions
00191     behaviors().supportRepr();
00192     behaviors().supportGetattr();
00193     behaviors().supportSetattr();
00194     behaviors().type_object()->tp_new = &PyMake;
00195     add_varargs_method("match",&SelectionFilterPy::match,"match()");
00196     add_varargs_method("result",&SelectionFilterPy::result,"result()");
00197     add_varargs_method("test",&SelectionFilterPy::test,"test()");
00198 }
00199 
00200 PyObject *SelectionFilterPy::PyMake(struct _typeobject *, PyObject *args, PyObject *)
00201 {
00202     char* str;
00203     if (!PyArg_ParseTuple(args, "s",&str))
00204         return 0;
00205     return new SelectionFilterPy(str);
00206 }
00207 
00208 SelectionFilterPy::SelectionFilterPy(const std::string& s)
00209   : filter(s)
00210 {
00211 }
00212 
00213 SelectionFilterPy::~SelectionFilterPy()
00214 {
00215 }
00216 
00217 Py::Object SelectionFilterPy::repr()
00218 {
00219     std::string s;
00220     std::ostringstream s_out;
00221     s_out << "SelectionFilter";
00222     return Py::String(s_out.str());
00223 }
00224 
00225 Py::Object SelectionFilterPy::match(const Py::Tuple& args)
00226 {
00227     return Py::Boolean(filter.match());
00228 }
00229 
00230 Py::Object SelectionFilterPy::test(const Py::Tuple& args)
00231 {
00232     PyObject * pcObj ;
00233     char* text=0;
00234     if (!PyArg_ParseTuple(args.ptr(), "O!|s",&(App::DocumentObjectPy::Type),&pcObj,&text))
00235         throw Py::Exception();
00236 
00237     App::DocumentObjectPy* docObj = static_cast<App::DocumentObjectPy*>(pcObj);
00238 
00239     return Py::Boolean(filter.test(docObj->getDocumentObjectPtr(),text));
00240 }
00241 
00242 Py::Object SelectionFilterPy::result(const Py::Tuple&)
00243 {
00244     Py::List list;
00245     std::vector<std::vector<SelectionObject> >::iterator it;
00246     for (it = filter.Result.begin(); it != filter.Result.end(); ++it) {
00247         std::vector<SelectionObject>::iterator jt;
00248         Py::Tuple tuple(it->size());
00249         int index=0;
00250         for (jt = it->begin(); jt != it->end(); ++jt) {
00251             tuple[index++] = Py::asObject(jt->getObject()->getPyObject());
00252         }
00253         list.append(tuple);
00254     }
00255     return list;
00256 }
00257 
00258 
00259 
00260 // === Parser & Scanner stuff ===============================================
00261 
00262 // include the Scanner and the Parser for the filter language
00263 
00264 SelectionFilter* ActFilter=0;
00265 Node_Block *TopBlock=0;
00266 
00267 // error func
00268 void yyerror(char *errorinfo)
00269         {  ActFilter->addError(errorinfo);  }
00270 
00271 
00272 // for VC9 (isatty and fileno not supported anymore)
00273 #ifdef _MSC_VER
00274 int isatty (int i) {return _isatty(i);}
00275 int fileno(FILE *stream) {return _fileno(stream);}
00276 #endif
00277 
00278 namespace SelectionParser {
00279 
00280 // show the parser the lexer method
00281 #define yylex SelectionFilterlex
00282 int SelectionFilterlex(void);
00283 
00284 // Parser, defined in SelectionFilter.y
00285 #include "SelectionFilter.tab.c"
00286 
00287 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00288 // Scanner, defined in SelectionFilter.l
00289 #include "lex.SelectionFilter.c"
00290 #endif // DOXYGEN_SHOULD_SKIP_THIS
00291 }
00292 
00293 bool SelectionFilter::parse(void)
00294 {
00295     Errors = "";
00296     SelectionParser::YY_BUFFER_STATE my_string_buffer = SelectionParser::SelectionFilter_scan_string (Filter.c_str());
00297     // be aware that this parser is not reentrant! Dont use with Threats!!!
00298     assert(!ActFilter);
00299     ActFilter = this;
00300     /*int my_parse_result =*/ SelectionParser::yyparse();
00301     ActFilter = 0;
00302     Ast = TopBlock;
00303     TopBlock = 0;
00304     SelectionParser::SelectionFilter_delete_buffer (my_string_buffer);
00305 
00306     if(Errors == "")
00307         return true;
00308     else{
00309         return false;
00310         delete Ast;
00311     }
00312 }

Generated on Wed Nov 23 19:00:37 2011 for FreeCAD by  doxygen 1.6.1