diff --git a/Core/Code/Controllers/mitkOperationEvent.h b/Core/Code/Controllers/mitkOperationEvent.h index d31167a61e..a3f2ac08b8 100644 --- a/Core/Code/Controllers/mitkOperationEvent.h +++ b/Core/Code/Controllers/mitkOperationEvent.h @@ -1,210 +1,210 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef OPERATIONEVENT_H_HEADER_INCLUDED_C16E83FC #define OPERATIONEVENT_H_HEADER_INCLUDED_C16E83FC #include #include "mitkOperation.h" #include "mitkOperationActor.h" #include "mitkUndoModel.h" #include #include namespace mitk { //##Documentation //## @brief Represents an entry of the undo or redo stack. //## //## This basic entry includes a textual description of the item and a pair of IDs. Static //## member functions handle creation and incrementing of these IDs. //## //## The ObjectEventID is increased by the global EventMapper for most of the events (see //## code for details). Incrementation of the IDs is done in two steps. First the //## EventMapper sets a flag via (possibly multiple calls of) IncCurrObjectEventID(), then //## ExecuteIncrement() does the actual incementation. //## //## The GroupEventID is intended for logical grouping of several related Operations. -//## Currently this is used only by PointSetInteractor. How this is done and when to use +//## Currently this is used only by PointSetDataInteractor. How this is done and when to use //## GroupEventIDs is still undocumented. //## @ingroup Undo class MITK_CORE_EXPORT UndoStackItem { public: UndoStackItem(std::string description = ""); virtual ~UndoStackItem(); //##Documentation //## @brief For combining operations in groups //## //## This ID is used in the undo mechanism. //## For separation of the seperate operations //## If the GroupEventId of two OperationEvents is equal, //## then they share one group and will be undone in case of Undo(fine==false) static int GetCurrGroupEventId(); //##Documentation //## @brief For combining operations in Objects //## //## This ID is used in the Undo-Mechanism. //## For separation of the seperate operations //## If the ObjectEventId of two OperationEvents is equal, //## then they share one Object and will be undone in all cases of Undo(true and false). //## they shal not be seperated, because they were produced to realize one object-change. //## for example: OE_statechange and OE_addlastpoint static int GetCurrObjectEventId(); //##Documentation //## @brief Returns the GroupEventId for this object int GetGroupEventId(); //##Documentation //## @brief Returns the ObjectEventId for this object int GetObjectEventId(); //##Documentation //## @brief Returns the textual description of this object std::string GetDescription(); virtual void ReverseOperations(); virtual void ReverseAndExecute(); //##Documentation //## @brief Sets the current ObjectEventId to be incremended when ExecuteIncrement is called //## For example if a button click generates operations the ObjectEventId has to be incremented to be able to undo the operations. //## Difference between ObjectEventId and GroupEventId: The ObjectEventId capsulates all operations caused by one event. //## A GroupEventId capsulates several ObjectEventIds so that several operations caused by several events can be undone with one Undo call. static void IncCurrObjectEventId(); //##Documentation //## @brief Sets the current GroupEventId to be incremended when ExecuteIncrement is called //## For example if a button click generates operations the GroupEventId has to be incremented to be able to undo the operations. //## Difference between ObjectEventId and GroupEventId: The ObjectEventId capsulates all operations caused by one event. //## A GroupEventId capsulates several ObjectEventIds so that several operations caused by several events can be undone with one Undo call. static void IncCurrGroupEventId(); //##Documentation //## @brief Executes the incrementation of objectEventId and groupEventId if they are set to be incremented static void ExecuteIncrement(); protected: //##Documentation //## @brief true, if operation and undooperation have been swaped/changed bool m_Reversed; private: static int m_CurrObjectEventId; static int m_CurrGroupEventId; static bool m_IncrObjectEventId; static bool m_IncrGroupEventId; int m_ObjectEventId; int m_GroupEventId; std::string m_Description; UndoStackItem(UndoStackItem&); // hide copy constructor void operator=(const UndoStackItem&); // hide operator= }; //##Documentation //## @brief Represents a pair of operations: undo and the according redo. //## //## Additionally to the base class UndoStackItem, which only provides a description of an //## item, OperationEvent does the actual accounting of the undo/redo stack. This class //## holds two Operation objects (operation and its inverse operation) and the corresponding //## OperationActor. The operations may be swapped by the //## undo models, when an OperationEvent is moved from their undo to their redo //## stack or vice versa. //## //## Note, that memory management of operation and undooperation is done by this class. //## Memory of both objects is freed in the destructor. For this, the method IsValid() is needed which holds //## information of the state of m_Destination. In case the object referenced by m_Destination is already deleted, //## isValid() returns false. //## In more detail if the destination happens to be an itk::Object (often the case), OperationEvent is informed as soon //## as the object is deleted - from this moment on the OperationEvent gets invalid. You should //## check this flag before you call anything on destination //## //## @ingroup Undo class MITK_CORE_EXPORT OperationEvent : public UndoStackItem { public: //## @brief default constructor OperationEvent(OperationActor* destination, Operation* operation, Operation* undoOperation, std::string description = "" ); //## @brief default destructor //## //## removes observers if destination is valid //## and frees memory referenced by m_Operation and m_UndoOperation virtual ~OperationEvent(); //## @brief Returns the operation Operation* GetOperation(); //## @brief Returns the destination of the operations OperationActor* GetDestination(); friend class UndoModel; //## @brief Swaps the two operations and sets a flag, //## that it has been swapped and doOp is undoOp and undoOp is doOp virtual void ReverseOperations(); //##reverses and executes both operations (used, when moved from undo to redo stack) virtual void ReverseAndExecute(); //## @brief returns true if the destination still is present //## and false if it already has been deleted virtual bool IsValid(); protected: void OnObjectDeleted(); private: // Has to be observed for itk::DeleteEvents. // When destination is deleted, this stack item is invalid! OperationActor* m_Destination; //## reference to the operation Operation* m_Operation; //## reference to the undo operation Operation* m_UndoOperation; //## hide copy constructor OperationEvent(OperationEvent&); //## hide operator= void operator=(const OperationEvent&); //observertag used to listen to m_Destination unsigned long m_DeleteTag; //## stores if destination is valid or already has been freed bool m_Invalid; }; } //namespace mitk #endif /* OPERATIONEVENT_H_HEADER_INCLUDED_C16E83FC */ diff --git a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.cpp b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.cpp index 5816430fd0..41b5d0f9a2 100644 --- a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.cpp +++ b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.cpp @@ -1,306 +1,311 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkSimpleMeasurement.h" #include "ui_QmitkSimpleMeasurementControls.h" #include #include -#include +//#include #include #include #include #include #include #include QmitkSimpleMeasurement::QmitkSimpleMeasurement() { } QmitkSimpleMeasurement::~QmitkSimpleMeasurement() { //remove all measurements when view is closed for (std::size_t i=0; iGetDataStorage()->Remove(m_CreatedDistances.at(i)); } for (std::size_t i=0; iGetDataStorage()->Remove(m_CreatedAngles.at(i)); } for (std::size_t i=0; iGetDataStorage()->Remove(m_CreatedPaths.at(i)); } if (m_PointSetInteractor.IsNotNull()) { - mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor.GetPointer()); + m_SelectedPointSetNode->SetDataInteractor(NULL); + //mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor.GetPointer()); } } void QmitkSimpleMeasurement::Activated() { this->OnSelectionChanged(berry::IWorkbenchPart::Pointer(), this->GetCurrentSelection()); } void QmitkSimpleMeasurement::Deactivated() { } void QmitkSimpleMeasurement::Visible() { } void QmitkSimpleMeasurement::Hidden() { } void QmitkSimpleMeasurement::ActivatedZombieView(berry::SmartPointer /*zombieView*/) { // something else was selected. remove old interactor if (m_PointSetInteractor.IsNotNull()) { - mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor.GetPointer()); + m_SelectedPointSetNode->SetDataInteractor(NULL); + //mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor.GetPointer()); } } void QmitkSimpleMeasurement::AddDistanceSimpleMeasurement() { mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); QString name = "Distance " + QString::number(m_CreatedDistances.size()+1); mitk::DataNode::Pointer CurrentPointSetNode = mitk::DataNode::New(); CurrentPointSetNode->SetData(pointSet); CurrentPointSetNode->SetProperty("show contour", mitk::BoolProperty::New(true)); CurrentPointSetNode->SetProperty("name", mitk::StringProperty::New(name.toStdString())); CurrentPointSetNode->SetProperty("show distances", mitk::BoolProperty::New(true)); // add to ds and remember as created m_CreatedDistances.push_back(CurrentPointSetNode); this->GetDataStorage()->Add(CurrentPointSetNode); // make new selection QList selection; selection.push_back( CurrentPointSetNode ); this->FireNodesSelected( selection ); this->OnSelectionChanged(berry::IWorkbenchPart::Pointer(), selection ); } void QmitkSimpleMeasurement::AddAngleSimpleMeasurement() { mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); QString name = "Angle " + QString::number(m_CreatedAngles.size()+1); mitk::DataNode::Pointer _CurrentPointSetNode = mitk::DataNode::New(); _CurrentPointSetNode->SetData(pointSet); _CurrentPointSetNode->SetProperty("show contour", mitk::BoolProperty::New(true)); _CurrentPointSetNode->SetProperty("name", mitk::StringProperty::New(name.toStdString())); _CurrentPointSetNode->SetProperty("show angles", mitk::BoolProperty::New(true)); // add to ds and remember as created this->GetDataStorage()->Add(_CurrentPointSetNode); m_CreatedAngles.push_back( _CurrentPointSetNode ); // make new selection QList selection; selection.push_back( _CurrentPointSetNode ); this->FireNodesSelected( selection ); this->OnSelectionChanged(berry::IWorkbenchPart::Pointer(), selection ); } void QmitkSimpleMeasurement::AddPathSimpleMeasurement() { mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); QString name = "Path " + QString::number(m_CreatedPaths.size()+1); mitk::DataNode::Pointer _CurrentPointSetNode = mitk::DataNode::New(); _CurrentPointSetNode->SetData(pointSet); _CurrentPointSetNode->SetProperty("show contour", mitk::BoolProperty::New(true)); _CurrentPointSetNode->SetProperty("name", mitk::StringProperty::New(name.toStdString())); _CurrentPointSetNode->SetProperty("show distances", mitk::BoolProperty::New(true)); _CurrentPointSetNode->SetProperty("show angles", mitk::BoolProperty::New(true)); // add to ds and remember as created this->GetDataStorage()->Add(_CurrentPointSetNode); m_CreatedPaths.push_back( _CurrentPointSetNode ); // make new selection QList selection; selection.push_back( _CurrentPointSetNode ); this->FireNodesSelected( selection ); this->OnSelectionChanged(berry::IWorkbenchPart::Pointer(), selection ); } void QmitkSimpleMeasurement::CreateQtPartControl( QWidget* parent ) { m_CreatedDistances = std::vector(); m_CreatedAngles = std::vector(); m_CreatedPaths = std::vector(); m_Controls = new Ui::QmitkSimpleMeasurementControls; m_Controls->setupUi(parent); connect( (QObject*)(m_Controls->pbDistance), SIGNAL(clicked()),(QObject*) this, SLOT(AddDistanceSimpleMeasurement()) ); connect( (QObject*)(m_Controls->pbAngle), SIGNAL(clicked()),(QObject*) this, SLOT(AddAngleSimpleMeasurement()) ); connect( (QObject*)(m_Controls->pbPath), SIGNAL(clicked()),(QObject*) this, SLOT(AddPathSimpleMeasurement()) ); connect( (QObject*)(m_Controls->m_Finished), SIGNAL(clicked()),(QObject*) this, SLOT(Finished()) ); EndEditingMeasurement(); } void QmitkSimpleMeasurement::SetFocus() { m_Controls->m_Finished->setFocus(); } void QmitkSimpleMeasurement::Finished() { OnSelectionChanged(berry::IWorkbenchPart::Pointer(), QList()); } void QmitkSimpleMeasurement::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList &nodes) { mitk::DataNode::Pointer selectedNode ; if(nodes.size() > 0) selectedNode = nodes.front(); mitk::PointSet* pointSet = 0; if(selectedNode.IsNotNull()) pointSet = dynamic_cast ( selectedNode->GetData() ); // something else was selected. remove old interactor if (m_PointSetInteractor.IsNotNull()) { - mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor.GetPointer()); + m_SelectedPointSetNode->SetDataInteractor(NULL); + //mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor.GetPointer()); } bool pointsetCreatedByThis = false; // only go further if a pointset was selected if(pointSet) { // see if this pointset was created by us std::vector::iterator it = std::find( m_CreatedDistances.begin() , m_CreatedDistances.end(), selectedNode); if (it != m_CreatedDistances.end()) pointsetCreatedByThis = true; it = std::find( m_CreatedAngles.begin() , m_CreatedAngles.end(), selectedNode); if (it != m_CreatedAngles.end()) pointsetCreatedByThis = true; it = std::find( m_CreatedPaths.begin() , m_CreatedPaths.end(), selectedNode); if (it != m_CreatedPaths.end()) pointsetCreatedByThis = true; } // do nothing if it was not created by us or it is no pointset node or we are not activated if(pointsetCreatedByThis) { // otherwise: set text and add interactor for the pointset m_Controls->selectedPointSet->setText( QString::fromStdString(selectedNode->GetName()) ); - mitk::PointSetInteractor::Pointer newPointSetInteractor - = mitk::PointSetInteractor::New("pointsetinteractor", selectedNode.GetPointer()); - mitk::GlobalInteraction::GetInstance()->AddInteractor(newPointSetInteractor); - m_PointSetInteractor = newPointSetInteractor; + + m_PointSetInteractor = mitk::PointSetDataInteractor::New(); + m_PointSetInteractor->LoadStateMachine("PointSet.xml"); + m_PointSetInteractor->SetEventConfig("PointSetConfig.xml"); + m_PointSetInteractor->SetDataNode(selectedNode); + float green[] = { 0, 255, 0 }; float red[] = { 255, 0, 0 }; selectedNode->SetColor(green); if(m_SelectedPointSetNode.IsNotNull()) m_SelectedPointSetNode->SetColor(red); m_SelectedPointSetNode = selectedNode; StartEditingMeasurement(); } else { EndEditingMeasurement(); } } void QmitkSimpleMeasurement::NodeRemoved( const mitk::DataNode* node ) { // remove a node if it is destroyed from our created array m_CreatedDistances.erase(std::remove(m_CreatedDistances.begin(), m_CreatedDistances.end(), node), m_CreatedDistances.end()); m_CreatedAngles.erase(std::remove(m_CreatedAngles.begin(), m_CreatedAngles.end(), node), m_CreatedAngles.end()); m_CreatedPaths.erase(std::remove(m_CreatedPaths.begin(), m_CreatedPaths.end(), node), m_CreatedPaths.end()); } void QmitkSimpleMeasurement::StartEditingMeasurement() { m_Controls->explain_label->setVisible(true); m_Controls->m_Finished->setVisible(true); m_Controls->pbDistance->setEnabled(false); m_Controls->pbAngle->setEnabled(false); m_Controls->pbPath->setEnabled(false); UpdateMeasurementList(); } void QmitkSimpleMeasurement::EndEditingMeasurement() { m_Controls->pbDistance->setEnabled(true); m_Controls->pbAngle->setEnabled(true); m_Controls->pbPath->setEnabled(true); m_Controls->explain_label->setVisible(false); m_Controls->m_Finished->setVisible(false); m_Controls->selectedPointSet->setText( "None" ); UpdateMeasurementList(); } void QmitkSimpleMeasurement::UpdateMeasurementList() { m_Controls->m_MeasurementList->clear(); for (std::size_t i=0; i(m_CreatedDistances.at(i)->GetData()); if(points->GetSize()<2) { distance = "not available"; } else { distance = QString::number(points->GetPoint(0).EuclideanDistanceTo(points->GetPoint(1))) + " mm"; } QString name = QString(m_CreatedDistances.at(i)->GetName().c_str()) + " (" + distance + ")"; newItem->setText(name); m_Controls->m_MeasurementList->insertItem(m_Controls->m_MeasurementList->count(), newItem); } for (std::size_t i=0; iGetName().c_str(); newItem->setText(name); m_Controls->m_MeasurementList->insertItem(m_Controls->m_MeasurementList->count(), newItem); } for (std::size_t i=0; iGetName().c_str(); newItem->setText(name); m_Controls->m_MeasurementList->insertItem(m_Controls->m_MeasurementList->count(), newItem); } } diff --git a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.h b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.h index 9313b01104..58c1c5a4a8 100644 --- a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.h +++ b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/simplemeasurement/QmitkSimpleMeasurement.h @@ -1,106 +1,100 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKSIMPELEMEASUREMENT_H #define MITKSIMPELEMEASUREMENT_H #include #include -#include - +#include "mitkDataNode.h" +#include "mitkPointSetDataInteractor.h" #include "ui_QmitkSimpleMeasurementControls.h" namespace Ui { class QmitkSimpleMeasurementControls; } -namespace mitk { -class PointSetInteractor; -} - - /** * \brief SimpleMeasurement * Allows to measure distances, angles, etc. * * \sa QmitkAbstractView */ class QmitkSimpleMeasurement : public QmitkAbstractView, public mitk::IZombieViewPart { Q_OBJECT public: - QmitkSimpleMeasurement(); virtual ~QmitkSimpleMeasurement(); private: virtual void CreateQtPartControl(QWidget* parent); virtual void SetFocus(); virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &nodes); virtual void NodeRemoved(const mitk::DataNode* node); virtual void Activated(); virtual void Deactivated(); virtual void Visible(); virtual void Hidden(); virtual void ActivatedZombieView(berry::SmartPointer zombieView); private slots: void AddDistanceSimpleMeasurement(); void AddAngleSimpleMeasurement(); void AddPathSimpleMeasurement(); void Finished(); private: /** * controls containing sliders for scrolling through the slices */ Ui::QmitkSimpleMeasurementControls * m_Controls; /* * Interactor for performing the simplemeasurements. */ - mitk::WeakPointer m_PointSetInteractor; + mitk::PointSetDataInteractor::Pointer m_PointSetInteractor; /* * Interactor for performing the simplemeasurements. */ - mitk::WeakPointer m_SelectedPointSetNode; + mitk::DataNode::Pointer m_SelectedPointSetNode; /** @brief * Node representing the PointSets which were created by this application. */ std::vector m_CreatedDistances; std::vector m_CreatedAngles; std::vector m_CreatedPaths; void StartEditingMeasurement(); void EndEditingMeasurement(); void UpdateMeasurementList(); }; #endif // QMITK_MEASUREMENT_H__INCLUDED