Classes | Public Member Functions | Protected Member Functions | Protected Attributes

QmitkDataStorageTableModel Class Reference

Own includes. More...

#include <QmitkDataStorageTableModel.h>

Inheritance diagram for QmitkDataStorageTableModel:
Inheritance graph
[legend]
Collaboration diagram for QmitkDataStorageTableModel:
Collaboration graph
[legend]

List of all members.

Classes

struct  DataNodeCompareFunction
 A struct that inherits from std::binary_function. You can use it in std::sort algorithm for sorting the node list elements. More...

Public Member Functions

 QmitkDataStorageTableModel (mitk::DataStorage::Pointer _DataStorage, mitk::NodePredicateBase *_Predicate=0, QObject *parent=0)
virtual ~QmitkDataStorageTableModel ()
const mitk::DataStorage::Pointer GetDataStorage () const
mitk::NodePredicateBase::Pointer GetPredicate () const
mitk::DataNode::Pointer GetNode (const QModelIndex &index) const
virtual QVariant headerData (int section, Qt::Orientation orientation, int role) const
virtual Qt::ItemFlags flags (const QModelIndex &index) const
virtual int rowCount (const QModelIndex &parent) const
virtual int columnCount (const QModelIndex &parent) const
virtual QVariant data (const QModelIndex &index, int role) const
void SetDataStorage (mitk::DataStorage::Pointer _DataStorage)
void SetPredicate (mitk::NodePredicateBase *_Predicate)
virtual void AddNode (const mitk::DataNode *node)
virtual void RemoveNode (const mitk::DataNode *node)
virtual std::vector
< mitk::DataNode * > 
GetNodeSet () const
virtual void PropertyModified (const itk::Object *caller, const itk::EventObject &event)
 Called when a single property was changed. The function searches through the list of nodes in this model for the changed property. If the property was found a dataChanged signal is emitted forcing all observing views to request the data again.
bool setData (const QModelIndex &index, const QVariant &value, int role)
void sort (int column, Qt::SortOrder order=Qt::AscendingOrder)
 Reimplemented sort function from QAbstractTableModel to enable sorting on the table.

Protected Member Functions

virtual void Reset ()

Protected Attributes

mitk::WeakPointer
< mitk::DataStorage
m_DataStorage
mitk::NodePredicateBase::Pointer m_Predicate
std::vector< mitk::DataNode * > m_NodeSet
std::map< mitk::BaseProperty
*, unsigned long > 
m_NamePropertyModifiedObserverTags
 Maps a property to an observer tag.
std::map< mitk::BaseProperty
*, unsigned long > 
m_VisiblePropertyModifiedObserverTags
 Maps a property to an observer tag.
bool m_BlockEvents
bool m_SortDescending
 The property is true when the property list is sorted in descending order.

Detailed Description

Own includes.

Toolkit includes. Forward declarations.

A table model for a set of DataNodes defined by a predicate. make columns interchangeable, select which properties to show as columns

Definition at line 38 of file QmitkDataStorageTableModel.h.


Constructor & Destructor Documentation

QmitkDataStorageTableModel::QmitkDataStorageTableModel ( mitk::DataStorage::Pointer  _DataStorage,
mitk::NodePredicateBase _Predicate = 0,
QObject *  parent = 0 
)

Constructs a new QmitkDataStorageTableModel and sets a predicate that defines this list.

See also:
setPredicate()

Definition at line 33 of file QmitkDataStorageTableModel.cpp.

References SetDataStorage(), and SetPredicate().

: QAbstractTableModel(parent)
, m_DataStorage(0)
, m_Predicate(0)
, m_BlockEvents(false)
, m_SortDescending(false)
{
  this->SetPredicate(_Predicate);
  this->SetDataStorage(_DataStorage);
}
QmitkDataStorageTableModel::~QmitkDataStorageTableModel (  ) [virtual]

Standard dtor. Delete predicate, disconnect from DataStorage.

Definition at line 46 of file QmitkDataStorageTableModel.cpp.

References SetDataStorage().

{
  // set data storage 0 to remove event listeners
  this->SetDataStorage(0);
}

Member Function Documentation

void QmitkDataStorageTableModel::AddNode ( const mitk::DataNode node ) [virtual]

Adds a node to this model. There are two constraints for nodes in this model: 1. If a predicate is set (not null) the node will be checked against it. 2. The node has to have a data object (no one wants to see empty nodes). Also adds event listeners to the node.

Definition at line 238 of file QmitkDataStorageTableModel.cpp.

References mitk::DataNode::GetData(), mitk::DataNode::GetProperty(), m_BlockEvents, m_NamePropertyModifiedObserverTags, m_NodeSet, m_Predicate, m_VisiblePropertyModifiedObserverTags, and PropertyModified().

Referenced by Reset(), and SetDataStorage().

{
  // garantuee no recursions when a new node event is thrown
  if(!m_BlockEvents)
  {
    // if we have a predicate, check node against predicate first
    if(m_Predicate.IsNotNull() && !m_Predicate->CheckNode(node))
      return;

    // dont add nodes without data (formerly known as helper objects)
    if(node->GetData() == 0)
      return;

    // create listener commands to listen to changes in the name or the visibility of the node
    itk::MemberCommand<QmitkDataStorageTableModel>::Pointer propertyModifiedCommand
      = itk::MemberCommand<QmitkDataStorageTableModel>::New();
    propertyModifiedCommand->SetCallbackFunction(this, &QmitkDataStorageTableModel::PropertyModified);

    mitk::BaseProperty* tempProperty = 0;

    // add listener for properties
    tempProperty = node->GetProperty("visible");
    if(tempProperty)
      m_VisiblePropertyModifiedObserverTags[tempProperty]
        = tempProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand);

    tempProperty = node->GetProperty("name");
    if(tempProperty)
      m_NamePropertyModifiedObserverTags[tempProperty]
        = tempProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand);

    // emit beginInsertRows event
    beginInsertRows(QModelIndex(), m_NodeSet.size(), m_NodeSet.size());

    // add node
    m_NodeSet.push_back(const_cast<mitk::DataNode*>(node));

    // emit endInsertRows event
    endInsertRows();
  }
}
int QmitkDataStorageTableModel::columnCount ( const QModelIndex &  parent ) const [virtual]

Overridden from QAbstractTableModel. Returns the number of features (columns) to display.

Reimplemented in QmitkPlanarFiguresTableModel.

Definition at line 126 of file QmitkDataStorageTableModel.cpp.

{
  // show name, type and visible columnn
  int columns = 3;
  return columns;
}
QVariant QmitkDataStorageTableModel::data ( const QModelIndex &  index,
int  role 
) const [virtual]

Overridden from QAbstractTableModel. Returns the data at index for given role.

Reimplemented in QmitkPlanarFiguresTableModel.

Definition at line 133 of file QmitkDataStorageTableModel.cpp.

References QmitkNodeDescriptor::GetClassName(), QmitkNodeDescriptorManager::GetDescriptor(), QmitkNodeDescriptor::GetIcon(), QmitkNodeDescriptorManager::GetInstance(), m_NodeSet, and QmitkDataNodeRole.

{
  QVariant data;

  if (index.isValid() && !m_NodeSet.empty())
  {
    mitk::DataNode::Pointer node = m_NodeSet.at(index.row());

    std::string nodeName = node->GetName();
    if(nodeName.empty())
      nodeName = "unnamed";

    // get name
    if(index.column() == 0)
    {
      // get name of node (may also be edited)
      if (role == Qt::DisplayRole || role == Qt::EditRole)
      {
        data = nodeName.c_str();
      }
      else if (role == QmitkDataNodeRole)
      {
        data = QVariant::fromValue(node);
      }
    }
    else if (index.column() == 1)
    {

      QmitkNodeDescriptor* nodeDescriptor 
        = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(node);

      // get type property of mitk::BaseData
      if (role == Qt::DisplayRole)
      {

        data = nodeDescriptor->GetClassName();
      }
      // show some nice icons for datatype
      else if(role == Qt::DecorationRole)
      {
        data = nodeDescriptor->GetIcon();
      }
    }
    else if (index.column() == 2)
    {
      // get visible property of mitk::BaseData
      bool visibility = false;

      if(node->GetVisibility(visibility, 0) && role == Qt::CheckStateRole)
      {
        data = (visibility ? Qt::Checked : Qt::Unchecked);
      } // node->GetVisibility(visibility, 0) && role == Qt::CheckStateRole

    } // index.column() == 2

  } // index.isValid() && !m_NodeSet.empty()
  return data;
}
Qt::ItemFlags QmitkDataStorageTableModel::flags ( const QModelIndex &  index ) const [virtual]

Overridden from QAbstractTableModel. Returns what can be done with an item.

Reimplemented in QmitkPlanarFiguresTableModel.

Definition at line 104 of file QmitkDataStorageTableModel.cpp.

{
  Qt::ItemFlags flags = QAbstractItemModel::flags(index);

  // name & visibility is editable
  if (index.column() == 0)
  {
    flags |= Qt::ItemIsEditable;
  }
  else if (index.column() == 2)
  {
    flags |= Qt::ItemIsUserCheckable;
  }

  return flags;
}
const mitk::DataStorage::Pointer QmitkDataStorageTableModel::GetDataStorage (  ) const

Get the DataStorage.

Definition at line 53 of file QmitkDataStorageTableModel.cpp.

References mitk::WeakPointer< TObjectType >::GetPointer(), and m_DataStorage.

{
  return m_DataStorage.GetPointer();
}
mitk::DataNode::Pointer QmitkDataStorageTableModel::GetNode ( const QModelIndex &  index ) const

Get node at a specific model index. Another way to implement this, is by introducing a new role like "DateTreeNode" and capture that in the data function.

Definition at line 63 of file QmitkDataStorageTableModel.cpp.

References m_NodeSet.

{
  mitk::DataNode::Pointer node;

  if(index.isValid())
  {
    node = m_NodeSet.at(index.row());
  }

  return node;
}
std::vector< mitk::DataNode * > QmitkDataStorageTableModel::GetNodeSet (  ) const [virtual]

Returns a copy of the node-vector that is shown by this model

Definition at line 476 of file QmitkDataStorageTableModel.cpp.

References m_NodeSet.

{
  return m_NodeSet;
}
mitk::NodePredicateBase::Pointer QmitkDataStorageTableModel::GetPredicate (  ) const

Get the predicate.

Definition at line 58 of file QmitkDataStorageTableModel.cpp.

References m_Predicate.

{
  return m_Predicate;
}
QVariant QmitkDataStorageTableModel::headerData ( int  section,
Qt::Orientation  orientation,
int  role 
) const [virtual]

Overridden from QAbstractTableModel. Returns the header data at section for given orientation and role.

Reimplemented in QmitkPlanarFiguresTableModel.

Definition at line 76 of file QmitkDataStorageTableModel.cpp.

{
  QVariant headerData;

  // show only horizontal header
  if ( role == Qt::DisplayRole )
  {
    if( orientation == Qt::Horizontal )
    {
      // first column: "Name"
      if(section == 0)
        headerData = "Name";
      else if(section == 1)
        headerData = "Data Type";
      else if(section == 2)
        headerData = "Visibility";
    }
    else if( orientation == Qt::Vertical )
    {
      // show numbers for rows
      headerData = section+1;
    }
  }

  return headerData;
}
void QmitkDataStorageTableModel::PropertyModified ( const itk::Object *  caller,
const itk::EventObject &  event 
) [virtual]

Called when a single property was changed. The function searches through the list of nodes in this model for the changed property. If the property was found a dataChanged signal is emitted forcing all observing views to request the data again.

Definition at line 320 of file QmitkDataStorageTableModel.cpp.

References QuadProgPP::distance(), m_BlockEvents, and m_NodeSet.

Referenced by AddNode().

{
  if(!m_BlockEvents)
  {
    // get modified property
    const mitk::BaseProperty* modifiedProperty = dynamic_cast<const mitk::BaseProperty*>(caller);

    if(modifiedProperty)
    {
      // find node that holds the modified property
      int row = -1;
      int column = -1;

      std::vector<mitk::DataNode*>::iterator it;
      mitk::BaseProperty* visibilityProperty = 0;
      mitk::BaseProperty* nameProperty = 0;

      // search for property that changed and emit datachanged on the corresponding ModelIndex
      for(it=m_NodeSet.begin(); it!=m_NodeSet.end(); it++)
      {
        // check for the visible property or the name property
        visibilityProperty = (*it)->GetProperty("visible");
        if(modifiedProperty == visibilityProperty)
        {
          column = 2;
          break;
        }

        nameProperty = (*it)->GetProperty("name");
        if(modifiedProperty == nameProperty)
        {
          column = 0;
          break;
        }
      }

      // if we have the property we have a valid iterator
      if( it != m_NodeSet.end() )
        row = std::distance(m_NodeSet.begin(), it);

      // now emit the dataChanged signal
      QModelIndex indexOfChangedProperty = index(row, column);
      emit dataChanged(indexOfChangedProperty, indexOfChangedProperty);
    }
  }
}
void QmitkDataStorageTableModel::RemoveNode ( const mitk::DataNode node ) [virtual]

Removes a node from this model. Also removes any event listener from the node.

Definition at line 280 of file QmitkDataStorageTableModel.cpp.

References QuadProgPP::distance(), m_BlockEvents, m_NamePropertyModifiedObserverTags, m_NodeSet, and m_VisiblePropertyModifiedObserverTags.

Referenced by Reset(), and SetDataStorage().

{
  // garantuee no recursions when a new node event is thrown
  if(!m_BlockEvents)
  {
    // find corresponding node
    std::vector<mitk::DataNode*>::iterator nodeIt
      = std::find(m_NodeSet.begin(), m_NodeSet.end(), node);

    if(nodeIt != m_NodeSet.end())
    {
      // now: remove listeners for name property ...
      mitk::BaseProperty* tempProperty = 0;

      tempProperty = (*nodeIt)->GetProperty("visible");
      if(tempProperty)
        tempProperty->RemoveObserver(m_VisiblePropertyModifiedObserverTags[tempProperty]);
      m_VisiblePropertyModifiedObserverTags.erase(tempProperty);

      // ... and visibility property
      tempProperty = (*nodeIt)->GetProperty("name");
      if(tempProperty)
        tempProperty->RemoveObserver(m_NamePropertyModifiedObserverTags[tempProperty]);
      m_NamePropertyModifiedObserverTags.erase(tempProperty);

      // get an index from iterator
      int row = std::distance(m_NodeSet.begin(), nodeIt);

      // emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model)
      this->beginRemoveRows(QModelIndex(), row, row);

      // remove node
      m_NodeSet.erase(nodeIt);

      // emit endRemoveRows event
      endRemoveRows();
    }
  }
}
void QmitkDataStorageTableModel::Reset (  ) [protected, virtual]

Called when DataStorage or Predicate changed. Resets whole model and reads all nodes in again.

Definition at line 401 of file QmitkDataStorageTableModel.cpp.

References AddNode(), mitk::WeakPointer< TObjectType >::IsNotNull(), m_DataStorage, m_NamePropertyModifiedObserverTags, m_NodeSet, m_Predicate, m_VisiblePropertyModifiedObserverTags, and RemoveNode().

Referenced by SetDataStorage(), and SetPredicate().

{
  mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet;

  // remove all nodes now (dont use iterators because removing elements
  // would invalidate the iterator)
  // start at the last element: first in, last out
  unsigned int i = m_NodeSet.size();
  while(!m_NodeSet.empty())
  {
    --i;
    this->RemoveNode(m_NodeSet.at(i));
  }

  // normally now everything should be empty->just to be sure
  // erase all arrays again
  m_NamePropertyModifiedObserverTags.clear();
  m_VisiblePropertyModifiedObserverTags.clear();
  m_NodeSet.clear();

  // the whole reset depends on the fact if a data storage is set or not
  if(m_DataStorage.IsNotNull())
  {
    if(m_Predicate.IsNotNull())
      // get subset
      _NodeSet = m_DataStorage->GetSubset(m_Predicate);
    // if predicate is NULL, select all nodes
    else
    {
      _NodeSet = m_DataStorage->GetAll();
      // remove ghost root node
    }

    // finally add all nodes to the model
    for(mitk::DataStorage::SetOfObjects::const_iterator it=_NodeSet->begin(); it!=_NodeSet->end()
      ; it++)
    {
      // save node
      this->AddNode(*it);
    }

  }
}
int QmitkDataStorageTableModel::rowCount ( const QModelIndex &  parent ) const [virtual]

Overridden from QAbstractTableModel. Returns the node count.

Definition at line 121 of file QmitkDataStorageTableModel.cpp.

References m_NodeSet.

{
  return m_NodeSet.size();
}
bool QmitkDataStorageTableModel::setData ( const QModelIndex &  index,
const QVariant &  value,
int  role 
)

Overridden from QAbstractTableModel. Sets data at index for given role.

Definition at line 367 of file QmitkDataStorageTableModel.cpp.

References mitk::RenderingManager::GetInstance(), m_BlockEvents, and m_NodeSet.

{
  bool noErr = false;

  if (index.isValid() && (role == Qt::EditRole || role == Qt::CheckStateRole))
  {
    // any change events produced here should not be caught in this class
    // --> set m_BlockEvents to true
    m_BlockEvents = true;

    mitk::DataNode::Pointer node = m_NodeSet.at(index.row());

    if(index.column() == 0)
    {
      node->SetStringProperty("name", value.toString().toStdString().c_str());
    }
    else if(index.column() == 2)
    {
      node->SetBoolProperty("visible", (value.toInt() == Qt::Checked ? true : false));
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
    }

    // inform listeners about changes
    emit dataChanged(index, index);

    m_BlockEvents = false;
    noErr = true;
  }

  return noErr;
}
void QmitkDataStorageTableModel::SetDataStorage ( mitk::DataStorage::Pointer  _DataStorage )

Sets the DataStorage.

Definition at line 203 of file QmitkDataStorageTableModel.cpp.

References AddNode(), mitk::WeakPointer< TObjectType >::GetPointer(), m_DataStorage, RemoveNode(), and Reset().

Referenced by QmitkDataStorageTableModel(), and ~QmitkDataStorageTableModel().

{
  // only proceed if we have a new datastorage
  if(m_DataStorage.GetPointer() != _DataStorage.GetPointer())
  {
    // if a data storage was set before remove old event listeners
    if(m_DataStorage != 0)
    {
      this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
        , const mitk::DataNode*>( this, &QmitkDataStorageTableModel::AddNode ) );

      this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
        , const mitk::DataNode*>( this, &QmitkDataStorageTableModel::RemoveNode ) );
    }

    // set new data storage
    m_DataStorage = _DataStorage.GetPointer();

    // if new storage is not 0 subscribe for events
    if(m_DataStorage != 0)
    {
      // subscribe for node added/removed events
      this->m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
        , const mitk::DataNode*>( this, &QmitkDataStorageTableModel::AddNode ) );

      this->m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
        , const mitk::DataNode*>( this, &QmitkDataStorageTableModel::RemoveNode ) );
    }

    // Reset model (even if datastorage is 0->will be checked in Reset())
    this->Reset();
  }
}
void QmitkDataStorageTableModel::SetPredicate ( mitk::NodePredicateBase _Predicate )

Sets the predicate. QmitkDataStorageTableModel is owner of the predicate!

Definition at line 193 of file QmitkDataStorageTableModel.cpp.

References m_Predicate, and Reset().

Referenced by QmitkDataStorageTableModel().

{
  // ensure that a new predicate is set in order to avoid unnecessary changed events
  if(m_Predicate != _Predicate)
  {
    m_Predicate = _Predicate;
    this->Reset();
  }
}
void QmitkDataStorageTableModel::sort ( int  column,
Qt::SortOrder  order = Qt::AscendingOrder 
)

Reimplemented sort function from QAbstractTableModel to enable sorting on the table.

Definition at line 445 of file QmitkDataStorageTableModel.cpp.

References QmitkDataStorageTableModel::DataNodeCompareFunction::CompareByClassName, QmitkDataStorageTableModel::DataNodeCompareFunction::CompareByName, QmitkDataStorageTableModel::DataNodeCompareFunction::CompareByVisibility, QmitkDataStorageTableModel::DataNodeCompareFunction::Greater, QmitkDataStorageTableModel::DataNodeCompareFunction::Less, and m_NodeSet.

{
  bool sortDescending = (order == Qt::DescendingOrder) ? true: false;

  // do not sort twice !!! (dont know why, but qt calls this func twice. STUPID!)
/*
  if(sortDescending != m_SortDescending)
  {*/

    //m_SortDescending = sortDescending;

    DataNodeCompareFunction::CompareCriteria _CompareCriteria
      = DataNodeCompareFunction::CompareByName;

    DataNodeCompareFunction::CompareOperator _CompareOperator
      = sortDescending ? DataNodeCompareFunction::Greater: DataNodeCompareFunction::Less;

    if(column == 1)
      _CompareCriteria = DataNodeCompareFunction::CompareByClassName;

    else if(column == 2)
      _CompareCriteria = DataNodeCompareFunction::CompareByVisibility;


    DataNodeCompareFunction compareFunc(_CompareCriteria, _CompareOperator);
    std::sort(m_NodeSet.begin(), m_NodeSet.end(), compareFunc);

    QAbstractTableModel::reset();
  //}
}

Member Data Documentation

Saves if this model is currently working on events to prevent endless event loops.

Definition at line 218 of file QmitkDataStorageTableModel.h.

Referenced by AddNode(), PropertyModified(), RemoveNode(), and setData().

Pointer to the DataStorage from which the nodes are selected (remember: in BlueBerry there might be more than one DataStorage). Store it in a weak pointer. This is a GUI class which should not hold a strong reference to any non-GUI Object.

Definition at line 197 of file QmitkDataStorageTableModel.h.

Referenced by GetDataStorage(), Reset(), and SetDataStorage().

Maps a property to an observer tag.

Definition at line 210 of file QmitkDataStorageTableModel.h.

Referenced by AddNode(), RemoveNode(), and Reset().

Holds the predicate that defines this SubSet of Nodes. If m_Predicate is NULL all Nodes will be selected.

Definition at line 202 of file QmitkDataStorageTableModel.h.

Referenced by AddNode(), GetPredicate(), Reset(), and SetPredicate().

The property is true when the property list is sorted in descending order.

Definition at line 222 of file QmitkDataStorageTableModel.h.

Maps a property to an observer tag.

Definition at line 214 of file QmitkDataStorageTableModel.h.

Referenced by AddNode(), RemoveNode(), and Reset().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines