PropertyLinks.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
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 
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 // PropertyLink
00053 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00054 
00055 TYPESYSTEM_SOURCE(App::PropertyLink , App::Property);
00056 
00057 //**************************************************************************
00058 // Construction/Destruction
00059 
00060 
00061 PropertyLink::PropertyLink()
00062 :_pcLink(0)
00063 {
00064 
00065 }
00066 
00067 
00068 PropertyLink::~PropertyLink()
00069 {
00070 
00071 }
00072 
00073 //**************************************************************************
00074 // Base class implementer
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     // read my element
00125     reader.readElement("Link");
00126     // get the value of my attribute
00127     std::string name = reader.getAttribute("value");
00128 
00129     // Property not in a DocumentObject!
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 // PropertyLinkSub
00161 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00162 
00163 TYPESYSTEM_SOURCE(App::PropertyLinkSub , App::Property);
00164 
00165 //**************************************************************************
00166 // Construction/Destruction
00167 
00168 
00169 PropertyLinkSub::PropertyLinkSub()
00170 :_pcLinkSub(0)
00171 {
00172 
00173 }
00174 
00175 
00176 PropertyLinkSub::~PropertyLinkSub()
00177 {
00178 
00179 }
00180 
00181 //**************************************************************************
00182 // Base class implementer
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     // it can happen that the object is still alive but is not part of the document anymore and thus
00266     // returns 0
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     // read my element
00280     reader.readElement("LinkSub");
00281     // get the values of my attributes
00282     std::string name = reader.getAttribute("value");
00283     int count = reader.getAttributeAsInteger("count");
00284 
00285     // Property not in a DocumentObject!
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 // PropertyLinkList
00328 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00329 
00330 TYPESYSTEM_SOURCE(App::PropertyLinkList , App::PropertyLists);
00331 
00332 //**************************************************************************
00333 // Construction/Destruction
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     // read my element
00433     reader.readElement("LinkList");
00434     // get the value of my attribute
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         // In order to do copy/paste it must be allowed to have defined some
00444         // referenced objects in XML which do not exist anymore in the new
00445         // document. Thus, we should silently ingore this.
00446         // Property not in an object!
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     // assignment
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 // PropertyLinkSubList
00482 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00483 
00484 TYPESYSTEM_SOURCE(App::PropertyLinkSubList , App::PropertyLists);
00485 
00486 //**************************************************************************
00487 // Construction/Destruction
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     // read my element
00620     reader.readElement("LinkSubList");
00621     // get the value of my attribute
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         // In order to do copy/paste it must be allowed to have defined some
00633         // referenced objects in XML which do not exist anymore in the new
00634         // document. Thus, we should silently ingore this.
00635         // Property not in an object!
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     // assignment
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 }

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