00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "QmitkDataStorageComboBox.h"
00019
00020 #include <itkCommand.h>
00021
00022
00023
00024 QmitkDataStorageComboBox::QmitkDataStorageComboBox( QWidget* parent, bool _AutoSelectNewNodes )
00025 : QComboBox(parent)
00026 , m_DataStorage(0)
00027 , m_Predicate(0)
00028 , m_BlockEvents(false)
00029 , m_AutoSelectNewNodes(_AutoSelectNewNodes)
00030 {
00031 this->Init();
00032 }
00033
00034 QmitkDataStorageComboBox::QmitkDataStorageComboBox( mitk::DataStorage* _DataStorage, const mitk::NodePredicateBase* _Predicate,
00035 QWidget* parent, bool _AutoSelectNewNodes )
00036 : QComboBox(parent)
00037 , m_DataStorage(0)
00038 , m_Predicate(_Predicate)
00039 , m_BlockEvents(false)
00040 , m_AutoSelectNewNodes(_AutoSelectNewNodes)
00041 {
00042
00043 this->Init();
00044 this->SetDataStorage(_DataStorage);
00045 }
00046
00047 QmitkDataStorageComboBox::~QmitkDataStorageComboBox()
00048 {
00049
00050 if(m_DataStorage.IsNotNull())
00051 {
00052 this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageComboBox
00053 , const mitk::DataNode*>( this, &QmitkDataStorageComboBox::AddNode ) );
00054
00055 this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageComboBox
00056 , const mitk::DataNode*>( this, &QmitkDataStorageComboBox::RemoveNode ) );
00057 }
00058
00059 while(m_Nodes.size() > 0)
00060 RemoveNode(0);
00061 }
00062
00063
00064 mitk::DataStorage::Pointer QmitkDataStorageComboBox::GetDataStorage() const
00065 {
00066 return m_DataStorage.GetPointer();
00067 }
00068
00069 const mitk::NodePredicateBase::ConstPointer QmitkDataStorageComboBox::GetPredicate() const
00070 {
00071 return m_Predicate.GetPointer();
00072 }
00073
00074 mitk::DataNode::Pointer QmitkDataStorageComboBox::GetNode( int index ) const
00075 {
00076 return (this->HasIndex(index))? m_Nodes.at(index): 0;
00077 }
00078
00079 mitk::DataNode::Pointer QmitkDataStorageComboBox::GetSelectedNode() const
00080 {
00081 int _CurrentIndex = this->currentIndex();
00082 return (_CurrentIndex >= 0)? this->GetNode(_CurrentIndex): 0;
00083 }
00084
00085 mitk::DataStorage::SetOfObjects::ConstPointer QmitkDataStorageComboBox::GetNodes() const
00086 {
00087 mitk::DataStorage::SetOfObjects::Pointer _SetOfObjects = mitk::DataStorage::SetOfObjects::New();
00088
00089 for (std::vector<mitk::DataNode*>::const_iterator it = m_Nodes.begin(); it != m_Nodes.end(); ++it)
00090 {
00091 _SetOfObjects->push_back(*it);
00092 }
00093
00094 return _SetOfObjects.GetPointer();
00095 }
00096
00097 bool QmitkDataStorageComboBox::GetAutoSelectNewItems()
00098 {
00099 return m_AutoSelectNewNodes;
00100 }
00101
00102
00103 void QmitkDataStorageComboBox::SetDataStorage(mitk::DataStorage* _DataStorage)
00104 {
00105
00106 if(m_DataStorage.GetPointer() != _DataStorage)
00107 {
00108
00109 if(m_DataStorage.IsNotNull())
00110 {
00111 this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageComboBox
00112 , const mitk::DataNode*>( this, &QmitkDataStorageComboBox::AddNode ) );
00113
00114 this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageComboBox
00115 , const mitk::DataNode*>( this, &QmitkDataStorageComboBox::RemoveNode ) );
00116 }
00117
00118 m_DataStorage = _DataStorage;
00119
00120
00121 if(m_DataStorage.IsNotNull())
00122 {
00123 this->m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageComboBox
00124 , const mitk::DataNode*>( this, &QmitkDataStorageComboBox::AddNode ) );
00125
00126 this->m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageComboBox
00127 , const mitk::DataNode*>( this, &QmitkDataStorageComboBox::RemoveNode ) );
00128 }
00129
00130
00131 this->Reset();
00132 }
00133 }
00134
00135 void QmitkDataStorageComboBox::SetPredicate(const mitk::NodePredicateBase* _Predicate)
00136 {
00137 if(m_Predicate != _Predicate)
00138 {
00139 m_Predicate = _Predicate;
00140 this->Reset();
00141 }
00142 }
00143
00144 void QmitkDataStorageComboBox::AddNode( const mitk::DataNode* _DataNode )
00145 {
00146
00147 if(!m_BlockEvents)
00148 {
00149 m_BlockEvents = true;
00150
00151 this->InsertNode(-1, _DataNode);
00152 m_BlockEvents = false;
00153 }
00154 }
00155
00156 void QmitkDataStorageComboBox::RemoveNode( int index )
00157 {
00158 if(this->HasIndex(index))
00159 {
00160
00161 mitk::DataNode* _DataNode = m_Nodes.at(index);
00162
00163 mitk::BaseProperty* nameProperty = _DataNode->GetProperty("name");
00164
00165 if(nameProperty)
00166 {
00167 nameProperty->RemoveObserver(m_NodesModifiedObserverTags[index]);
00168
00169 m_PropertyToNode.erase(_DataNode);
00170 }
00171
00172 _DataNode->RemoveObserver(m_NodesDeleteObserverTags[index]);
00173
00174 m_NodesModifiedObserverTags.erase(m_NodesModifiedObserverTags.begin()+index);
00175 m_NodesDeleteObserverTags.erase(m_NodesDeleteObserverTags.begin()+index);
00176
00177 this->removeItem(index);
00178
00179 m_Nodes.erase(m_Nodes.begin()+index);
00180 }
00181 }
00182
00183 void QmitkDataStorageComboBox::RemoveNode( const mitk::DataNode* _DataNode )
00184 {
00185
00186 if(!m_BlockEvents)
00187 {
00188 m_BlockEvents = true;
00189 this->RemoveNode( this->Find(_DataNode) );
00190 m_BlockEvents = false;
00191 }
00192 }
00193
00194 void QmitkDataStorageComboBox::SetNode(int index, const mitk::DataNode* _DataNode)
00195 {
00196 if(this->HasIndex(index))
00197 {
00198 this->InsertNode(index, _DataNode);
00199 }
00200 }
00201
00202 void QmitkDataStorageComboBox::SetNode( const mitk::DataNode* _DataNode, const mitk::DataNode* _OtherDataNode)
00203 {
00204 this->SetNode( this->Find(_DataNode), _OtherDataNode);
00205 }
00206
00207 void QmitkDataStorageComboBox::SetAutoSelectNewItems( bool _AutoSelectNewItems )
00208 {
00209 m_AutoSelectNewNodes = _AutoSelectNewItems;
00210 }
00211
00212 void QmitkDataStorageComboBox::OnDataNodeDeleteOrModified(const itk::Object *caller, const itk::EventObject &event)
00213 {
00214 if(!m_BlockEvents)
00215 {
00216 m_BlockEvents = true;
00217
00218
00219 const itk::ModifiedEvent* modifiedEvent = dynamic_cast<const itk::ModifiedEvent*>(&event);
00220
00221
00222 if(modifiedEvent)
00223 {
00224 const mitk::BaseProperty* _NameProperty = dynamic_cast<const mitk::BaseProperty*>(caller);
00225
00226
00227
00228 for(std::map<mitk::DataNode*, const mitk::BaseProperty*>::iterator it=m_PropertyToNode.begin()
00229 ; it!=m_PropertyToNode.end()
00230 ; ++it)
00231 {
00232
00233 if(it->second == _NameProperty)
00234 {
00235
00236 this->SetNode(it->first, it->first);
00237 break;
00238 }
00239 }
00240 }
00241 else
00242 {
00243 const mitk::DataNode* _ConstDataNode = dynamic_cast<const mitk::DataNode*>(caller);
00244 if(_ConstDataNode)
00245
00246 this->RemoveNode(_ConstDataNode);
00247 }
00248
00249 m_BlockEvents = false;
00250 }
00251 }
00252
00253 void QmitkDataStorageComboBox::SetSelectedNode(mitk::DataNode::Pointer item)
00254 {
00255 int index = this->Find(item);
00256 if (index == -1)
00257 {
00258 MITK_INFO << "QmitkDataStorageComboBox: item not available";
00259 }
00260 else
00261 {
00262 this->setCurrentIndex(index);
00263 }
00264
00265 }
00266
00267
00268 bool QmitkDataStorageComboBox::HasIndex(unsigned int index) const
00269 {
00270 return (m_Nodes.size() > 0 && index < m_Nodes.size());
00271 }
00272
00273 int QmitkDataStorageComboBox::Find( const mitk::DataNode* _DataNode ) const
00274 {
00275 int index = -1;
00276
00277 std::vector<mitk::DataNode*>::const_iterator nodeIt =
00278 std::find(m_Nodes.begin(), m_Nodes.end(), _DataNode);
00279
00280 if(nodeIt != m_Nodes.end())
00281 index = std::distance(m_Nodes.begin(), nodeIt);
00282
00283 return index;
00284 }
00285
00286
00287 void QmitkDataStorageComboBox::OnCurrentIndexChanged(int index)
00288 {
00289 if(index >= 0 && index < this->count())
00290 emit OnSelectionChanged(this->GetSelectedNode());
00291 if(index == -1)
00292 emit OnSelectionChanged(NULL);
00293 }
00294
00295 void QmitkDataStorageComboBox::InsertNode(int index, const mitk::DataNode* _DataNode)
00296 {
00297
00298 if(m_Predicate.IsNotNull() && !m_Predicate->CheckNode(_DataNode))
00299 return;
00300
00301 bool addNewNode = false;
00302 bool insertNewNode = false;
00303 bool changedNode = false;
00304
00305
00306 if(this->HasIndex(index))
00307 {
00308
00309 if(_DataNode != m_Nodes.at(index))
00310 {
00311
00312 this->RemoveNode(index);
00313 insertNewNode = true;
00314 }
00315 else
00316 changedNode = true;
00317 }
00318
00319 else
00320 {
00321 index = m_Nodes.size();
00322 addNewNode = true;
00323 }
00324
00325
00326 mitk::DataNode* _NonConstDataNode = const_cast<mitk::DataNode*>(_DataNode);
00327 mitk::BaseProperty* nameProperty = _NonConstDataNode->GetProperty("name");
00328
00329 if(!changedNode)
00330 {
00331
00332 if(this->Find(_DataNode) != -1)
00333 return;
00334
00335
00336 itk::MemberCommand<QmitkDataStorageComboBox>::Pointer modifiedCommand = itk::MemberCommand<QmitkDataStorageComboBox>::New();
00337 modifiedCommand->SetCallbackFunction(this, &QmitkDataStorageComboBox::OnDataNodeDeleteOrModified);
00338
00340 if(nameProperty)
00341 {
00342 m_NodesModifiedObserverTags.push_back( nameProperty->AddObserver(itk::ModifiedEvent(), modifiedCommand) );
00343 m_PropertyToNode[_NonConstDataNode] = nameProperty;
00344 }
00345
00346 else
00347 m_NodesModifiedObserverTags.push_back( -1 );
00348
00349
00350 itk::MemberCommand<QmitkDataStorageComboBox>::Pointer deleteCommand = itk::MemberCommand<QmitkDataStorageComboBox>::New();
00351 deleteCommand->SetCallbackFunction(this, &QmitkDataStorageComboBox::OnDataNodeDeleteOrModified);
00352 m_NodesDeleteObserverTags.push_back( _NonConstDataNode->AddObserver(itk::DeleteEvent(), modifiedCommand) );
00353 }
00354
00355
00356 if(addNewNode)
00357 m_Nodes.push_back( _NonConstDataNode );
00358 else if(insertNewNode)
00359 m_Nodes.insert( m_Nodes.begin()+index, _NonConstDataNode );
00360
00361
00362 std::string _NonConstDataNodeName = "unnamed node";
00363
00364 if(nameProperty)
00365 _NonConstDataNodeName = nameProperty->GetValueAsString();
00366
00367 if(addNewNode)
00368 {
00369 this->addItem(QString::fromStdString(_NonConstDataNodeName));
00370
00371 if(m_AutoSelectNewNodes || m_Nodes.size() == 1)
00372 this->setCurrentIndex(index);
00373 }
00374 else
00375 {
00376
00377 this->setItemText( index, QString::fromStdString(_NonConstDataNodeName));
00378 }
00379 }
00380
00381 void QmitkDataStorageComboBox::Init()
00382 {
00383 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(OnCurrentIndexChanged(int)));
00384 }
00385
00386 void QmitkDataStorageComboBox::Reset()
00387 {
00388
00389 while( !m_Nodes.empty() )
00390 {
00391
00392 this->RemoveNode( m_Nodes.size() - 1 );
00393 }
00394
00395
00396 this->clear();
00397
00398 if(m_DataStorage.IsNotNull())
00399 {
00400 mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects;
00401
00402
00403 if (m_Predicate.IsNotNull())
00404 setOfObjects = m_DataStorage->GetSubset(m_Predicate);
00405 else
00406 setOfObjects = m_DataStorage->GetAll();
00407
00408
00409 for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin()
00410 ; nodeIt != setOfObjects->End(); ++nodeIt)
00411 {
00412
00413 this->AddNode( nodeIt.Value().GetPointer() );
00414 }
00415 }
00416 }