MeVisLabToolboxReference
|
00001 // **InsertLicense** code 00002 //---------------------------------------------------------------------------------- 00004 00009 // 00010 // Defines the following classes: 00011 // - ListContainerBase: An abstract ML module class implementing basic functionality 00012 // for a list container module. 00013 // - ListContainerTemplate: Class template for container modules for a specific list 00014 // class. Can also be used as a base class for viewer or editor modules. 00015 //---------------------------------------------------------------------------------- 00016 00017 00018 00019 #ifndef __mlListContainer_H 00020 #define __mlListContainer_H 00021 00022 00023 // ML-includes 00024 #ifndef __mlModuleIncludes_H 00025 #include "mlModuleIncludes.h" 00026 #endif 00027 #ifndef __mlBaseInit_H 00028 #include "mlBaseInit.h" 00029 #endif 00030 00031 00032 // Local includes 00033 #ifndef __mlListBase_H 00034 #include "mlListBase.h" 00035 #endif 00036 #ifndef __mlRangeCasts_H 00037 #include "mlRangeCasts.h" 00038 #endif 00039 00040 00041 ML_START_NAMESPACE 00042 00043 00046 typedef bool ListContainerHandleNotificationCB(void *usrData, Field* field); 00047 00048 // ------------------------------------------------------------------ 00050 // ------------------------------------------------------------------ 00051 00076 class MLBASEEXPORT ListContainerBase : public Module 00077 { 00078 00079 public: 00080 00082 ListContainerBase():Module(0,0) {}; 00083 00088 ListContainerBase (ListBase *listBasePtr, int inputNum, int outputNum); 00089 00091 00092 00093 virtual void handleNotification (Field *field); 00094 00096 virtual void activateAttachments (); 00097 00099 virtual void beginSaveFields (); 00100 00102 virtual void endSaveFields (); 00103 00105 00106 00108 void setHandleNotificationCB (ListContainerHandleNotificationCB *cb = NULL, 00109 void *userData = NULL); 00110 00111 00120 00121 00122 virtual void doDeleteAll (); 00123 00125 virtual void doDeleteItem (MLssize_t index); 00126 00130 virtual void doInsertItem (MLssize_t index, bool fromCurrentItem); 00131 00136 virtual void doModifyItem (MLssize_t index, Field *field, bool fromCurrentItem); 00137 00139 virtual void doCopyItemToTemplate (MLssize_t index); 00140 00142 virtual void doClearItem (MLssize_t index); 00143 00145 virtual void doSelectItem (MLssize_t index); 00146 00148 virtual void doUpdate (); 00149 00151 00153 BaseField* getOutputField() { return _fldOutputList; } 00154 00155 // Returns the maximum number of items. 00156 MLint maxNumItems() const { return _fldMaxSize->getIntValue(); } 00157 00159 enum OverflowModes 00160 { 00161 OvwNone = 0, 00162 OvwRemoveFirst, 00163 OvwRemoveLast, 00164 OvwRemoveAll, 00165 OvwRemoveNew, 00166 OvwNumModes 00167 }; 00168 00170 int overflowMode() const { return _fldOverflowMode->getEnumValue(); } 00171 00172 00173 protected: 00174 00178 00179 00180 virtual ListBase *getInternalList () = 0; 00181 00187 virtual bool setActiveList (Base *basePtr) = 0; 00188 00190 virtual bool ownsList () 00191 { return !_fldInputList || (_listBasePtr != _fldInputList->getBaseValue()); } 00192 00194 virtual MLssize_t getId (MLssize_t index) = 0; 00195 00197 00198 00202 00203 00204 virtual bool isPropertyField (Field *field); 00205 00207 virtual void resetPropertyFields (); 00208 00210 virtual void updatePropertyFields () = 0; 00211 00213 00214 00220 00221 00222 virtual void deleteItems (MLssize_t index, MLssize_t num) = 0; 00223 00227 virtual void insertItem (MLssize_t index, bool fromCurrentItem) = 0; 00228 00234 virtual bool modifyItem (MLssize_t index, Field *field, bool fromCurrentItem) = 0; 00235 00237 virtual void copyItemToTemplate (MLssize_t index) = 0; 00238 00240 virtual void copyTemplateToCurrent () = 0; 00241 00244 virtual void initItem (MLssize_t index) = 0; 00245 00247 00248 00250 00251 00252 00253 virtual void updateListString (bool forceEnable = false); 00254 00256 virtual void updateDisplay (); 00257 00259 virtual void updateActionFields (); 00260 00268 virtual void touchList (ListBase::ActionClass actionClass, MLssize_t id, MLssize_t index); 00269 00271 00272 00273 00275 00276 00277 BaseField *_fldOutputList; 00278 BaseField *_fldInputList; 00279 00280 StringField *_fldListString; 00281 IntField *_fldNumItems; 00282 IntField *_fldIndex; 00283 00284 BoolField *_fldPersistent; 00285 BoolField *_fldListStringEnable; 00286 BoolField *_fldOwnsList; 00287 BoolField *_fldApplySelect; 00288 00289 IntField *_fldId; 00290 StringField *_fldName; 00291 StringField *_fldNewName; 00292 00293 StringField *_fldActionClass; 00294 IntField *_fldActionIndex; 00295 IntField *_fldActionId; 00296 IntField *_fldCurrentIndex; 00297 00298 EnumField *_fldOverflowMode; 00299 IntField *_fldMaxSize; 00300 00301 NotifyField *_fldDelete; 00302 NotifyField *_fldDeleteAll; 00303 NotifyField *_fldInsert; 00304 NotifyField *_fldAdd; 00305 NotifyField *_fldUpdate; 00306 00307 BoolField *_fldUseInsertTemplate; 00308 NotifyField *_fldCopyItemToTemplate; 00309 NotifyField *_fldCopyTemplateToItem; 00310 NotifyField *_fldClearItem; 00311 00312 BoolField *_fldUpToDate; 00313 00315 00316 00317 int _lockNotification; 00318 00319 00320 private: 00321 00326 ListBase *_listBasePtr; 00327 00329 std::string _listStringBackup; 00330 00332 ListContainerHandleNotificationCB *_handleNotificationCB; 00333 00335 void* _handleNotificationUserData; 00336 00337 ML_ABSTRACT_MODULE_CLASS_HEADER(ListContainerBase) 00338 00339 }; 00340 00341 00342 00343 00344 00345 00346 // ------------------------------------------------------------------ 00348 // ------------------------------------------------------------------ 00349 00378 template <class T> 00379 class ListContainerTemplate : public ListContainerBase 00380 { 00381 public: 00382 00386 ListContainerTemplate (int inputNum, int outputNum); 00387 00389 virtual ~ListContainerTemplate () {} 00390 00391 00396 virtual T *getList () { return _listPtr; } 00397 00398 00402 typename T::itemType _currentItem; 00403 00404 00405 protected: 00406 00408 00409 00413 virtual bool setActiveList (Base *basePtr); 00414 00416 virtual ListBase *getInternalList () { return &_list; } 00417 00419 virtual MLssize_t getId (MLssize_t index); 00420 00422 00423 00425 00426 00427 virtual void updatePropertyFields (); 00428 00430 00431 00432 00434 00435 00436 virtual void deleteItems (MLssize_t index, MLssize_t num); 00437 00440 virtual void insertItem (MLssize_t index, bool fromCurrentItem); 00441 00446 virtual bool modifyItem (MLssize_t index, Field *field, bool fromCurrentItem); 00447 00449 virtual void copyItemToTemplate (MLssize_t index); 00450 00452 virtual void copyTemplateToCurrent (); 00453 00457 virtual void initItem (MLssize_t index); 00458 00460 00461 00466 T *_listPtr; 00467 00468 private: 00469 00470 //------------------------------------------------------------------------------------ 00473 //------------------------------------------------------------------------------------ 00474 ListContainerTemplate(const ListContainerTemplate &) 00475 { 00476 ML_PRINT_FATAL_ERROR("ListContainerTemplate::ListContainerTemplate(const ListContainerTemplate &)", 00477 ML_PROGRAMMING_ERROR, 00478 "Usage of copy constructor of ListContainerTemplate is not supported."); 00479 } 00480 00481 //------------------------------------------------------------------------------------ 00484 //------------------------------------------------------------------------------------ 00485 ListContainerTemplate& operator=(const ListContainerTemplate &) 00486 { 00487 ML_PRINT_FATAL_ERROR("ListContainerTemplate& ListContainerTemplate::operator=(const ListContainerTemplate &)", 00488 ML_PROGRAMMING_ERROR, 00489 "Usage of assignment operator of ListContainerTemplate is not supported."); 00490 return *this; 00491 } 00492 00493 00494 00496 T _list; 00497 00498 }; 00499 00500 00502 template <class T> 00503 ListContainerTemplate<T>::ListContainerTemplate (int inputNum, int outputNum) 00504 : ListContainerBase(&_list, inputNum, outputNum), 00505 _listPtr(&_list) 00506 { 00507 00508 ML_TRACE_IN("template <class T>ListContainerTemplate<T>::ListContainerTemplate (int inputNum, int outputNum):ListContainerBase(&_list, inputNum, outputNum), _listPtr(&_list)"); 00509 00510 // Suppress handleNotification() 00511 _lockNotification = 1; 00512 00513 // Get runtime type and name of this class and check for valid registration. 00514 const RuntimeType *rt = T::getClassTypeId(); 00515 ML_CHECK_RUNTIME_TYPE(rt); 00516 std::string rtName = rt->getName(); 00517 00518 // Add output list field 00519 00520 std::string listFieldName = std::string("out")+rtName; 00521 00522 _fldOutputList = getFieldContainer()->addBase(listFieldName.c_str()); 00523 _fldOutputList->setBaseValueAndAddAllowedType(_listPtr); 00524 00525 // Add input list field 00526 listFieldName = std::string("in")+rtName; 00527 _fldInputList = getFieldContainer()->addBase(listFieldName.c_str()); 00528 _fldInputList->setBaseValueAndAddAllowedType<ListBase>(NULL); 00529 00530 // Allow handleNotification() 00531 _lockNotification = 0; 00532 } 00533 00534 00538 template <class T> 00539 bool ListContainerTemplate<T>::setActiveList (Base *basePtr) 00540 { 00541 00542 ML_TRACE_IN("template <class T> bool ListContainerTemplate<T>::setActiveList (Base *basePtr)"); 00543 00544 bool listValid = false; 00545 00546 if (basePtr && ML_BASE_IS_A(basePtr, T)) 00547 { 00548 _listPtr = static_cast<T*>(basePtr); 00549 listValid = true; 00550 } else { 00551 _listPtr = NULL; 00552 } 00553 00554 return listValid; 00555 } 00556 00557 00559 template <class T> 00560 MLssize_t ListContainerTemplate<T>::getId (MLssize_t index) 00561 { 00562 00563 ML_TRACE_IN("template <class T> MLssize_t ListContainerTemplate<T>::getId (MLssize_tindex)"); 00564 00565 return (_listPtr && (index >= 0) && (index < static_cast<MLssize_t>(_listPtr->size())) ) 00566 ? (*_listPtr)[mlrange_cast<size_t>(index)].getId() : -1; 00567 } 00568 00569 00571 template <class T> 00572 void ListContainerTemplate<T>::updatePropertyFields () 00573 { 00574 00575 ML_TRACE_IN("template <class T> void ListContainerTemplate<T>::updatePropertyFields ()"); 00576 00577 const MLssize_t index = _fldIndex->getIntValue(); 00578 00579 if (_listPtr && (index >= 0) && (index < static_cast<MLssize_t>(_listPtr->size())) ) 00580 { 00581 _lockNotification++; 00582 00583 const BaseItem *item = &(*_listPtr)[mlrange_cast<size_t>(index)]; 00584 00585 _fldId->setIntValue(item->getId()); 00586 _fldName->setStringValue(item->name() ? item->name() : ""); 00587 00588 _lockNotification--; 00589 } 00590 } 00591 00592 00594 template <class T> 00595 void ListContainerTemplate<T>::deleteItems (MLssize_t index, MLssize_t num) 00596 { 00597 00598 ML_TRACE_IN("template <class T> void ListContainerTemplate<T>::deleteItems (MLssize_t index, MLssize_t num)"); 00599 00600 ML_TRY{ 00601 typename T::iterator it; 00602 const MLssize_t listSize = static_cast<MLssize_t>(_listPtr->size()); 00603 if (_listPtr && (index >= 0) && (index < listSize) && (num > 0)) 00604 { 00605 if (index+num > listSize){ 00606 num = listSize-index; 00607 } 00608 it = _listPtr->begin()+index; 00609 _listPtr->erase(it, it+num); 00610 } 00611 } 00612 ML_CATCH_RETHROW; 00613 } 00614 00615 00618 template <class T> 00619 void ListContainerTemplate<T>::insertItem (MLssize_t index, bool fromCurrentItem) 00620 { 00621 00622 ML_TRACE_IN("template <class T> void ListContainerTemplate<T>::insertItem (MLssize_t index, bool fromCurrentItem)"); 00623 00624 ML_TRY{ 00625 if (_listPtr && (index >= 0) && (index <= static_cast<MLssize_t>(_listPtr->size())) ) 00626 { 00627 if (fromCurrentItem) 00628 { 00629 // Generate new id and store in _currentItem 00630 _currentItem.setId(_listPtr->newId()); 00631 // Insert copy of _currentItem 00632 _listPtr->insert(_listPtr->begin()+index, _currentItem); 00633 00634 } else { 00635 00636 typename T::itemType tmpItem; 00637 // Insert new item and initialize 00638 _listPtr->insert(_listPtr->begin()+index, tmpItem); 00639 00640 // explicitly set the name to an empty string, 00641 // because the initial name is a NULL pointer using an item's standard constructor 00642 (*_listPtr)[mlrange_cast<size_t>(index)].setName(""); 00643 00644 initItem(index); 00645 } 00646 } 00647 } 00648 ML_CATCH_RETHROW; 00649 } 00650 00651 00656 template <class T> 00657 bool ListContainerTemplate<T>::modifyItem (MLssize_t index, Field *field, bool fromCurrentItem) 00658 { 00659 00660 ML_TRACE_IN("template <class T> bool ListContainerTemplate<T>::modifyItem (MLssize_t index, Field *field, bool fromCurrentItem)"); 00661 00662 ML_TRY{ 00663 bool modified = true; 00664 00665 if (_listPtr && (index >= 0) && (index < static_cast<MLssize_t>(_listPtr->size())) ) 00666 { 00667 if (fromCurrentItem){ 00668 00669 // Copy _currentItem to list item 00670 (*_listPtr)[mlrange_cast<size_t>(index)] = _currentItem; 00671 } 00672 else if (field == _fldId) 00673 { 00674 // Reject change to item id 00675 _fldId->setIntValue((*_listPtr)[mlrange_cast<size_t>(index)].getId()); 00676 modified = false; 00677 }else if (field == _fldName) { 00678 // Change item name 00679 (*_listPtr)[mlrange_cast<size_t>(index)].setName(_fldName->getStringValue().c_str()); 00680 } else { 00681 // Not a property field 00682 modified = false; 00683 } 00684 } else { 00685 // Invalid item or list 00686 modified = false; 00687 } 00688 00689 return modified; 00690 } 00691 ML_CATCH_RETHROW; 00692 } 00693 00695 template <class T> 00696 void ListContainerTemplate<T>::copyItemToTemplate(MLssize_t index) 00697 { 00698 00699 ML_TRACE_IN("template <class T> void ListContainerTemplate<T>::copyItemToTemplate(MLssize_t index)"); 00700 00701 typename T::itemType *item= &(*_listPtr)[mlrange_cast<size_t>(index)]; 00702 00703 _fldNewName->setStringValue( item->name() ? item->name() : "" ); 00704 00705 } 00706 00708 template <class T> 00709 void ListContainerTemplate<T>::copyTemplateToCurrent() 00710 { 00711 00712 ML_TRACE_IN("template <class T> void ListContainerTemplate<T>::copyTemplateToCurrent()"); 00713 00714 _currentItem.setName( _fldNewName->getStringValue().c_str() ); 00715 00716 } 00717 00721 template <class T> 00722 void ListContainerTemplate<T>::initItem (MLssize_t index) 00723 { 00724 00725 ML_TRACE_IN("template <class T> void ListContainerTemplate<T>::initItem (MLssize_t index)"); 00726 00727 typename T::itemType *item= &(*_listPtr)[mlrange_cast<size_t>(index)]; 00728 00729 if (item->getId() == 0) { 00730 // only assign a new id if the id is 0, 00731 // because we do not want to assign a new id if the clear-field is triggered 00732 // (0 is the initial id of an item, the first id returned by newId is 1) 00733 item->setId(_listPtr->newId()); 00734 } 00735 00736 item->setName(""); 00737 00738 } 00739 00740 00741 ML_END_NAMESPACE 00742 00743 #endif // __mlListContainer_H 00744