SelectionFilter.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00040 #include "Application.h"
00041
00042 using namespace Gui;
00043
00044
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
00127 if((*it)->SubName == ""){
00128
00129 if ((int)temp.size()<min || (int)temp.size()>max)
00130 return false;
00131 }else{
00132
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
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 void SelectionFilterPy::init_type()
00187 {
00188 behaviors().name("SelectionFilter");
00189 behaviors().doc("Filter for certain selection");
00190
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
00261
00262
00263
00264 SelectionFilter* ActFilter=0;
00265 Node_Block *TopBlock=0;
00266
00267
00268 void yyerror(char *errorinfo)
00269 { ActFilter->addError(errorinfo); }
00270
00271
00272
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
00281 #define yylex SelectionFilterlex
00282 int SelectionFilterlex(void);
00283
00284
00285 #include "SelectionFilter.tab.c"
00286
00287 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00288
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
00298 assert(!ActFilter);
00299 ActFilter = this;
00300 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 }