PropertyLinks.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
00026 #ifndef _PreComp_
00027 # include <assert.h>
00028 #endif
00029
00031 #include <CXX/Objects.hxx>
00032 #include <Base/Exception.h>
00033 #include <Base/Reader.h>
00034 #include <Base/Writer.h>
00035 #include <Base/Console.h>
00036
00037 #include "DocumentObject.h"
00038 #include "DocumentObjectPy.h"
00039 #include "Document.h"
00040
00041 #include "PropertyLinks.h"
00042
00043 using namespace App;
00044 using namespace Base;
00045 using namespace std;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 TYPESYSTEM_SOURCE(App::PropertyLink , App::Property);
00056
00057
00058
00059
00060
00061 PropertyLink::PropertyLink()
00062 :_pcLink(0)
00063 {
00064
00065 }
00066
00067
00068 PropertyLink::~PropertyLink()
00069 {
00070
00071 }
00072
00073
00074
00075
00076 void PropertyLink::setValue(App::DocumentObject * lValue)
00077 {
00078 aboutToSetValue();
00079 _pcLink=lValue;
00080 hasSetValue();
00081 }
00082
00083 App::DocumentObject * PropertyLink::getValue(void) const
00084 {
00085 return _pcLink;
00086 }
00087
00088 App::DocumentObject * PropertyLink::getValue(Base::Type t) const
00089 {
00090 return (_pcLink && _pcLink->getTypeId().isDerivedFrom(t)) ? _pcLink : 0;
00091 }
00092
00093 PyObject *PropertyLink::getPyObject(void)
00094 {
00095 if (_pcLink)
00096 return _pcLink->getPyObject();
00097 else
00098 Py_Return;
00099 }
00100
00101 void PropertyLink::setPyObject(PyObject *value)
00102 {
00103 if (PyObject_TypeCheck(value, &(DocumentObjectPy::Type))) {
00104 DocumentObjectPy *pcObject = (DocumentObjectPy*)value;
00105 setValue(pcObject->getDocumentObjectPtr());
00106 }
00107 else if (Py_None == value) {
00108 setValue(0);
00109 }
00110 else {
00111 std::string error = std::string("type must be 'DocumentObject' or 'NoneType', not ");
00112 error += value->ob_type->tp_name;
00113 throw Py::TypeError(error);
00114 }
00115 }
00116
00117 void PropertyLink::Save (Base::Writer &writer) const
00118 {
00119 writer.Stream() << writer.ind() << "<Link value=\"" << (_pcLink?_pcLink->getNameInDocument():"") <<"\"/>" << std::endl;
00120 }
00121
00122 void PropertyLink::Restore(Base::XMLReader &reader)
00123 {
00124
00125 reader.readElement("Link");
00126
00127 std::string name = reader.getAttribute("value");
00128
00129
00130 assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) );
00131
00132 if (name != "") {
00133 DocumentObject *pcObject = static_cast<DocumentObject*>(getContainer())->
00134 getDocument()->getObject(name.c_str());
00135 if (!pcObject)
00136 Base::Console().Warning("Lost link to '%s' while loading, maybe "
00137 "an object was not loaded correctly\n",name.c_str());
00138 setValue(pcObject);
00139 }
00140 else {
00141 setValue(0);
00142 }
00143 }
00144
00145 Property *PropertyLink::Copy(void) const
00146 {
00147 PropertyLink *p= new PropertyLink();
00148 p->_pcLink = _pcLink;
00149 return p;
00150 }
00151
00152 void PropertyLink::Paste(const Property &from)
00153 {
00154 aboutToSetValue();
00155 _pcLink = dynamic_cast<const PropertyLink&>(from)._pcLink;
00156 hasSetValue();
00157 }
00158
00159
00160
00161
00162
00163 TYPESYSTEM_SOURCE(App::PropertyLinkSub , App::Property);
00164
00165
00166
00167
00168
00169 PropertyLinkSub::PropertyLinkSub()
00170 :_pcLinkSub(0)
00171 {
00172
00173 }
00174
00175
00176 PropertyLinkSub::~PropertyLinkSub()
00177 {
00178
00179 }
00180
00181
00182
00183
00184 void PropertyLinkSub::setValue(App::DocumentObject * lValue, const std::vector<std::string> &SubList)
00185 {
00186 aboutToSetValue();
00187 _pcLinkSub=lValue;
00188 _cSubList = SubList;
00189 hasSetValue();
00190 }
00191
00192 App::DocumentObject * PropertyLinkSub::getValue(void) const
00193 {
00194 return _pcLinkSub;
00195 }
00196
00197 const std::vector<std::string>& PropertyLinkSub::getSubValues(void) const
00198 {
00199 return _cSubList;
00200 }
00201
00202 std::vector<std::string> PropertyLinkSub::getSubValuesStartsWith(const char* starter) const
00203 {
00204 std::vector<std::string> temp;
00205 for(std::vector<std::string>::const_iterator it=_cSubList.begin();it!=_cSubList.end();++it)
00206 if(strncmp(starter,it->c_str(),strlen(starter))==0)
00207 temp.push_back(*it);
00208 return temp;
00209 }
00210
00211 App::DocumentObject * PropertyLinkSub::getValue(Base::Type t) const
00212 {
00213 return (_pcLinkSub && _pcLinkSub->getTypeId().isDerivedFrom(t)) ? _pcLinkSub : 0;
00214 }
00215
00216 PyObject *PropertyLinkSub::getPyObject(void)
00217 {
00218 Py::Tuple tup(2);
00219 Py::List list(static_cast<int>(_cSubList.size()));
00220 if (_pcLinkSub) {
00221 _pcLinkSub->getPyObject();
00222 tup[0] = Py::Object(_pcLinkSub->getPyObject());
00223 for(unsigned int i = 0;i<_cSubList.size(); i++)
00224 list[i] = Py::String(_cSubList[i]);
00225 tup[1] = list;
00226 return Py::new_reference_to(tup);
00227 }
00228 else {
00229 return Py::new_reference_to(Py::None());
00230 }
00231 }
00232
00233 void PropertyLinkSub::setPyObject(PyObject *value)
00234 {
00235 if (PyObject_TypeCheck(value, &(DocumentObjectPy::Type))) {
00236 DocumentObjectPy *pcObject = (DocumentObjectPy*)value;
00237 setValue(pcObject->getDocumentObjectPtr());
00238 }
00239 else if (Py::Object(value).isTuple()) {
00240 Py::Tuple tup(value);
00241 if (PyObject_TypeCheck(tup[0].ptr(), &(DocumentObjectPy::Type))){
00242 DocumentObjectPy *pcObj = (DocumentObjectPy*)tup[0].ptr();
00243 Py::List list(tup[1]);
00244 std::vector<std::string> vals(list.size());
00245 unsigned int i=0;
00246 for(Py::List::iterator it = list.begin();it!=list.end();++it,++i)
00247 vals[i] = Py::String(*it);
00248
00249 setValue(pcObj->getDocumentObjectPtr(),vals);
00250 }
00251 }
00252 else if(Py_None == value) {
00253 setValue(0);
00254 }
00255 else {
00256 std::string error = std::string("type must be 'DocumentObject', 'NoneType' of ('DocumentObject',['String',]) not ");
00257 error += value->ob_type->tp_name;
00258 throw Py::TypeError(error);
00259 }
00260 }
00261
00262 void PropertyLinkSub::Save (Base::Writer &writer) const
00263 {
00264 const char* internal_name = "";
00265
00266
00267 if (_pcLinkSub && _pcLinkSub->getNameInDocument())
00268 internal_name = _pcLinkSub->getNameInDocument();
00269 writer.Stream() << writer.ind() << "<LinkSub value=\"" << internal_name <<"\" count=\"" << _cSubList.size() <<"\">" << std::endl;
00270 writer.incInd();
00271 for(unsigned int i = 0;i<_cSubList.size(); i++)
00272 writer.Stream() << writer.ind() << "<Sub value=\"" << _cSubList[i]<<"\"/>" << endl; ;
00273 writer.decInd();
00274 writer.Stream() << writer.ind() << "</LinkSub>" << endl ;
00275 }
00276
00277 void PropertyLinkSub::Restore(Base::XMLReader &reader)
00278 {
00279
00280 reader.readElement("LinkSub");
00281
00282 std::string name = reader.getAttribute("value");
00283 int count = reader.getAttributeAsInteger("count");
00284
00285
00286 assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) );
00287
00288 std::vector<std::string> values(count);
00289 for (int i = 0; i < count; i++) {
00290 reader.readElement("Sub");
00291 values[i] = reader.getAttribute("value");
00292 }
00293
00294 reader.readEndElement("LinkSub");
00295
00296 DocumentObject *pcObject;
00297 if (name != ""){
00298 pcObject = static_cast<DocumentObject*>(getContainer())->
00299 getDocument()->getObject(name.c_str());
00300 if (!pcObject)
00301 Base::Console().Warning("Lost link to '%s' while loading, maybe "
00302 "an object was not loaded correctly\n",name.c_str());
00303 setValue(pcObject,values);
00304 }
00305 else {
00306 setValue(0);
00307 }
00308 }
00309
00310 Property *PropertyLinkSub::Copy(void) const
00311 {
00312 PropertyLinkSub *p= new PropertyLinkSub();
00313 p->_pcLinkSub = _pcLinkSub;
00314 p->_cSubList = _cSubList;
00315 return p;
00316 }
00317
00318 void PropertyLinkSub::Paste(const Property &from)
00319 {
00320 aboutToSetValue();
00321 _pcLinkSub = dynamic_cast<const PropertyLinkSub&>(from)._pcLinkSub;
00322 _cSubList = dynamic_cast<const PropertyLinkSub&>(from)._cSubList;
00323 hasSetValue();
00324 }
00325
00326
00327
00328
00329
00330 TYPESYSTEM_SOURCE(App::PropertyLinkList , App::PropertyLists);
00331
00332
00333
00334
00335
00336 PropertyLinkList::PropertyLinkList()
00337 {
00338
00339 }
00340
00341 PropertyLinkList::~PropertyLinkList()
00342 {
00343
00344 }
00345
00346 void PropertyLinkList::setSize(int newSize)
00347 {
00348 _lValueList.resize(newSize);
00349 }
00350
00351 int PropertyLinkList::getSize(void) const
00352 {
00353 return static_cast<int>(_lValueList.size());
00354 }
00355
00356 void PropertyLinkList::setValue(DocumentObject* lValue)
00357 {
00358 if (lValue){
00359 aboutToSetValue();
00360 _lValueList.resize(1);
00361 _lValueList[0]=lValue;
00362 hasSetValue();
00363 }
00364 }
00365
00366 void PropertyLinkList::setValues(const std::vector<DocumentObject*>& lValue)
00367 {
00368 aboutToSetValue();
00369 _lValueList=lValue;
00370 hasSetValue();
00371 }
00372
00373 PyObject *PropertyLinkList::getPyObject(void)
00374 {
00375 int count = getSize();
00376 #if 0//FIXME: Should switch to tuple
00377 Py::Tuple sequence(count);
00378 #else
00379 Py::List sequence(count);
00380 #endif
00381 for (int i = 0;i<count; i++) {
00382 sequence.setItem(i, Py::asObject(_lValueList[i]->getPyObject()));
00383 }
00384
00385 return Py::new_reference_to(sequence);
00386 }
00387
00388 void PropertyLinkList::setPyObject(PyObject *value)
00389 {
00390 if (PyTuple_Check(value) || PyList_Check(value)) {
00391 Py::Sequence list(value);
00392 Py::Sequence::size_type size = list.size();
00393 std::vector<DocumentObject*> values;
00394 values.resize(size);
00395
00396 for (Py::Sequence::size_type i=0; i < size; i++) {
00397 Py::Object item = list[i];
00398 if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) {
00399 std::string error = std::string("type in list must be 'DocumentObject', not ");
00400 error += (*item)->ob_type->tp_name;
00401 throw Py::TypeError(error);
00402 }
00403
00404 values[i] = static_cast<DocumentObjectPy*>(*item)->getDocumentObjectPtr();
00405 }
00406
00407 setValues(values);
00408 }
00409 else if(PyObject_TypeCheck(value, &(DocumentObjectPy::Type))) {
00410 DocumentObjectPy *pcObject = static_cast<DocumentObjectPy*>(value);
00411 setValue(pcObject->getDocumentObjectPtr());
00412 }
00413 else {
00414 std::string error = std::string("type must be 'DocumentObject' or list of 'DocumentObject', not ");
00415 error += value->ob_type->tp_name;
00416 throw Py::TypeError(error);
00417 }
00418 }
00419
00420 void PropertyLinkList::Save (Base::Writer &writer) const
00421 {
00422 writer.Stream() << writer.ind() << "<LinkList count=\"" << getSize() <<"\">" << endl;
00423 writer.incInd();
00424 for(int i = 0;i<getSize(); i++)
00425 writer.Stream() << writer.ind() << "<Link value=\"" << _lValueList[i]->getNameInDocument() <<"\"/>" << endl; ;
00426 writer.decInd();
00427 writer.Stream() << writer.ind() << "</LinkList>" << endl ;
00428 }
00429
00430 void PropertyLinkList::Restore(Base::XMLReader &reader)
00431 {
00432
00433 reader.readElement("LinkList");
00434
00435 int count = reader.getAttributeAsInteger("count");
00436 assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) );
00437
00438 std::vector<DocumentObject*> values;
00439 values.reserve(count);
00440 for (int i = 0; i < count; i++) {
00441 reader.readElement("Link");
00442 std::string name = reader.getAttribute("value");
00443
00444
00445
00446
00447 DocumentObject* father = static_cast<DocumentObject*>(getContainer());
00448 DocumentObject* child = father->getDocument()->getObject(name.c_str());
00449 if (child)
00450 values.push_back(child);
00451 else
00452 Base::Console().Warning("Lost link to '%s' while loading, maybe "
00453 "an object was not loaded correctly\n",name.c_str());
00454 }
00455
00456 reader.readEndElement("LinkList");
00457
00458
00459 setValues(values);
00460 }
00461
00462 Property *PropertyLinkList::Copy(void) const
00463 {
00464 PropertyLinkList *p = new PropertyLinkList();
00465 p->_lValueList = _lValueList;
00466 return p;
00467 }
00468
00469 void PropertyLinkList::Paste(const Property &from)
00470 {
00471 aboutToSetValue();
00472 _lValueList = dynamic_cast<const PropertyLinkList&>(from)._lValueList;
00473 hasSetValue();
00474 }
00475
00476 unsigned int PropertyLinkList::getMemSize (void) const
00477 {
00478 return static_cast<unsigned int>(_lValueList.size() * sizeof(App::DocumentObject *));
00479 }
00480
00481
00482
00483
00484 TYPESYSTEM_SOURCE(App::PropertyLinkSubList , App::PropertyLists);
00485
00486
00487
00488
00489
00490 PropertyLinkSubList::PropertyLinkSubList()
00491 {
00492
00493 }
00494
00495 PropertyLinkSubList::~PropertyLinkSubList()
00496 {
00497
00498 }
00499
00500 void PropertyLinkSubList::setSize(int newSize)
00501 {
00502 _lValueList.resize(newSize);
00503 _lSubList .resize(newSize);
00504 }
00505
00506 int PropertyLinkSubList::getSize(void) const
00507 {
00508 return static_cast<int>(_lValueList.size());
00509 }
00510
00511 void PropertyLinkSubList::setValue(DocumentObject* lValue,const char* SubName)
00512 {
00513 if (lValue){
00514 aboutToSetValue();
00515 _lValueList.resize(1);
00516 _lValueList[0]=lValue;
00517 _lSubList.resize(1);
00518 _lSubList[0]=SubName;
00519 hasSetValue();
00520 }
00521 }
00522
00523 void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& lValue,const std::vector<const char*>& lSubNames)
00524 {
00525 aboutToSetValue();
00526 _lValueList = lValue;
00527 _lSubList.resize(lSubNames.size());
00528 int i = 0;
00529 for (std::vector<const char*>::const_iterator it = lSubNames.begin();it!=lSubNames.end();++it)
00530 _lSubList[i] = *it;
00531 hasSetValue();
00532 }
00533
00534 void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& lValue,const std::vector<std::string>& lSubNames)
00535 {
00536 aboutToSetValue();
00537 _lValueList = lValue;
00538 _lSubList = lSubNames;
00539 hasSetValue();
00540 }
00541
00542 PyObject *PropertyLinkSubList::getPyObject(void)
00543 {
00544 int count = getSize();
00545 #if 0//FIXME: Should switch to tuple
00546 Py::Tuple sequence(count);
00547 #else
00548 Py::List sequence(count);
00549 #endif
00550 for(int i = 0;i<count; i++){
00551 Py::Tuple tup(2);
00552 tup[0] = Py::Object(_lValueList[i]->getPyObject());
00553 tup[1] = Py::String(_lSubList[i].c_str());
00554 sequence[i] = tup;
00555 }
00556 return Py::new_reference_to(sequence);
00557
00558 }
00559
00560 void PropertyLinkSubList::setPyObject(PyObject *value)
00561 {
00562 if (PyTuple_Check(value) || PyList_Check(value)) {
00563 Py::Sequence list(value);
00564 Py::Sequence::size_type size = list.size();
00565
00566 std::vector<DocumentObject*> values;
00567 values.reserve(size);
00568 std::vector<std::string> SubNames;
00569 SubNames.reserve(size);
00570
00571 for (Py::Sequence::size_type i=0; i < size; i++) {
00572 Py::Object item = list[i];
00573 if (item.isTuple()) {
00574 Py::Tuple tup(item);
00575 if (PyObject_TypeCheck(tup[0].ptr(), &(DocumentObjectPy::Type))){
00576 DocumentObjectPy *pcObj;
00577 pcObj = static_cast<DocumentObjectPy*>(tup[0].ptr());
00578 values.push_back(pcObj->getDocumentObjectPtr());
00579 if (Py::Object(tup[1].ptr()).isString()){
00580 SubNames.push_back(Py::String(tup[1].ptr()));
00581 }
00582 }
00583 }
00584 else if (PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) {
00585 DocumentObjectPy *pcObj;
00586 pcObj = static_cast<DocumentObjectPy*>(*item);
00587 values.push_back(pcObj->getDocumentObjectPtr());
00588 }
00589 else if (item.isString()) {
00590 SubNames.push_back(Py::String(item));
00591 }
00592 }
00593
00594 setValues(values,SubNames);
00595 }
00596 else {
00597 std::string error = std::string("type must be 'DocumentObject' or list of 'DocumentObject', not ");
00598 error += value->ob_type->tp_name;
00599 throw Py::TypeError(error);
00600 }
00601 }
00602
00603 void PropertyLinkSubList::Save (Base::Writer &writer) const
00604 {
00605 writer.Stream() << writer.ind() << "<LinkSubList count=\"" << getSize() <<"\">" << endl;
00606 writer.incInd();
00607 for(int i = 0;i<getSize(); i++)
00608 writer.Stream() << writer.ind() <<
00609 "<Link " <<
00610 "obj=\"" << _lValueList[i]->getNameInDocument() <<
00611 "sub=\"" << _lSubList[i] <<
00612 "\"/>" << endl; ;
00613 writer.decInd();
00614 writer.Stream() << writer.ind() << "</LinkSubList>" << endl ;
00615 }
00616
00617 void PropertyLinkSubList::Restore(Base::XMLReader &reader)
00618 {
00619
00620 reader.readElement("LinkSubList");
00621
00622 int count = reader.getAttributeAsInteger("count");
00623 assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) );
00624
00625 std::vector<DocumentObject*> values;
00626 values.reserve(count);
00627 std::vector<std::string> SubNames;
00628 SubNames.reserve(count);
00629 for (int i = 0; i < count; i++) {
00630 reader.readElement("Link");
00631 std::string name = reader.getAttribute("obj");
00632
00633
00634
00635
00636 DocumentObject* father = static_cast<DocumentObject*>(getContainer());
00637 DocumentObject* child = father->getDocument()->getObject(name.c_str());
00638 if (child)
00639 values.push_back(child);
00640 else
00641 Base::Console().Warning("Lost link to '%s' while loading, maybe "
00642 "an object was not loaded correctly\n",name.c_str());
00643 std::string subName = reader.getAttribute("sub");
00644 SubNames.push_back(subName);
00645 }
00646
00647 reader.readEndElement("LinkSubList");
00648
00649
00650 setValues(values,SubNames);
00651 }
00652
00653 Property *PropertyLinkSubList::Copy(void) const
00654 {
00655 PropertyLinkSubList *p = new PropertyLinkSubList();
00656 p->_lValueList = _lValueList;
00657 p->_lSubList = _lSubList;
00658 return p;
00659 }
00660
00661 void PropertyLinkSubList::Paste(const Property &from)
00662 {
00663 aboutToSetValue();
00664 _lValueList = dynamic_cast<const PropertyLinkSubList&>(from)._lValueList;
00665 _lSubList = dynamic_cast<const PropertyLinkSubList&>(from)._lSubList;
00666 hasSetValue();
00667 }
00668
00669 unsigned int PropertyLinkSubList::getMemSize (void) const
00670 {
00671 unsigned int size = static_cast<unsigned int>(_lValueList.size() * sizeof(App::DocumentObject *));
00672 for(int i = 0;i<getSize(); i++)
00673 size += _lSubList[i].size();
00674
00675 return size;
00676 }