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/Core/Code/Testing/mitkDataNodeTest.cpp b/Core/Code/Testing/mitkDataNodeTest.cpp index 23635a286b..478171a34f 100644 --- a/Core/Code/Testing/mitkDataNodeTest.cpp +++ b/Core/Code/Testing/mitkDataNodeTest.cpp @@ -1,295 +1,294 @@ /*=================================================================== 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 "mitkDataNode.h" #include #include "mitkVtkPropRenderer.h" #include "mitkTestingMacros.h" #include "mitkGlobalInteraction.h" #include //Basedata Test #include #include #include #include #include #include #include #include //Mapper Test #include #include #include #include #include #include #include #include #include //Interactors -#include -#include +#include //Propertylist Test /** * Simple example for a test for the (non-existent) class "DataNode". * * argc and argv are the command line parameters which were passed to * the ADD_TEST command in the CMakeLists.txt file. For the automatic * tests, argv is either empty for the simple tests or contains the filename * of a test image for the image tests (see CMakeLists.txt). */ class mitkDataNodeTestClass { public: static void TestDataSetting(mitk::DataNode::Pointer dataNode) { mitk::BaseData::Pointer baseData; //NULL pointer Test dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" ) baseData = mitk::RenderWindowFrame::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a RenderWindowFrame object was set correctly" ) // MITK_TEST_CONDITION( baseData->GetGeometry(0)->GetVtkTransform() == dataNode->GetVtkTransform(0), "Testing if a NULL pointer was set correctly" ) baseData = mitk::GeometryData::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GeometryData object was set correctly" ) baseData = mitk::Geometry2DData::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Geometry2DData object was set correctly" ) baseData = mitk::GradientBackground::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GradientBackground object was set correctly" ) baseData = mitk::ManufacturerLogo::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ManufacturerLogo object was set correctly" ) baseData = mitk::PointSet::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PointSet object was set correctly" ) baseData = mitk::Image::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Image object was set correctly" ) baseData = mitk::Surface::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Surface object was set correctly" ) } static void TestMapperSetting(mitk::DataNode::Pointer dataNode) { //tests the SetMapper() method //in dataNode is a mapper vector which can be accessed by index //in this test method we use only slot 0 (filled with null) and slot 1 //so we also test the destructor of the mapper classes mitk::Mapper::Pointer mapper; dataNode->SetMapper(0,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" ) mapper = mitk::Geometry2DDataMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a Geometry2DDataMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::ImageVtkMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ImageVtkMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::PointSetVtkMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::SurfaceGLMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceGLMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::Geometry2DDataVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a Geometry2DDataVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::PointSetVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::SurfaceVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::VolumeDataVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a VolumeDataVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) //linker error //mapper = mitk::LineVtkMapper3D::New(); //dataNode->SetMapper(1,mapper); //MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineVtkMapper3D was set correctly" ) //MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) } static void TestInteractorSetting(mitk::DataNode::Pointer dataNode) { //this method tests the SetInteractor() and GetInteractor methods - //the Interactor base class calls the DataNode->SetInteractor method + //the DataInteractor base class calls the DataNode->SetInteractor method - mitk::Interactor::Pointer interactor; + mitk::DataInteractor::Pointer interactor; - MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a NULL pointer was set correctly (Interactor)" ) + MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a NULL pointer was set correctly (DataInteractor)" ) - interactor = mitk::AffineInteractor::New("AffineInteractions click to select", dataNode); - dataNode->EnableInteractor(); - dataNode->DisableInteractor(); - MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a AffineInteractor was set correctly" ) + interactor = mitk::PointSetDataInteractor::New(); + interactor->SetDataNode(dataNode); + MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" ) - interactor = mitk::PointSetInteractor::New("AffineInteractions click to select", dataNode); - MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a PointSetInteractor was set correctly" ) + interactor = mitk::PointSetDataInteractor::New(); + dataNode->SetDataInteractor(interactor); + MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" ) } static void TestPropertyList(mitk::DataNode::Pointer dataNode) { mitk::PropertyList::Pointer propertyList = dataNode->GetPropertyList(); MITK_TEST_CONDITION(dataNode->GetPropertyList() != NULL, "Testing if the constructor set the propertylist" ) dataNode->SetIntProperty("int", -31337); int x; dataNode->GetIntProperty("int", x); MITK_TEST_CONDITION(x == -31337, "Testing Set/GetIntProperty"); dataNode->SetBoolProperty("bool", true); bool b; dataNode->GetBoolProperty("bool", b); MITK_TEST_CONDITION(b == true, "Testing Set/GetBoolProperty"); dataNode->SetFloatProperty("float", -31.337); float y; dataNode->GetFloatProperty("float", y); MITK_TEST_CONDITION(y - -31.337 < 0.01, "Testing Set/GetFloatProperty"); dataNode->SetStringProperty("string", "MITK"); std::string s = "GANZVIELPLATZ"; dataNode->GetStringProperty("string", s); MITK_TEST_CONDITION(s == "MITK", "Testing Set/GetStringProperty"); std::string name = "MyTestName"; dataNode->SetName(name.c_str()); MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName"); name = "MySecondTestName"; dataNode->SetName(name); MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName(std::string)"); MITK_TEST_CONDITION(propertyList == dataNode->GetPropertyList(), "Testing if the propertylist has changed during the last tests" ) } static void TestSelected(mitk::DataNode::Pointer dataNode) { vtkRenderWindow *renderWindow = vtkRenderWindow::New(); mitk::VtkPropRenderer::Pointer base = mitk::VtkPropRenderer::New( "the first renderer", renderWindow, mitk::RenderingManager::GetInstance() ); //with BaseRenderer==Null MITK_TEST_CONDITION(!dataNode->IsSelected(), "Testing if this node is not set as selected" ) dataNode->SetSelected(true); MITK_TEST_CONDITION(dataNode->IsSelected(), "Testing if this node is set as selected" ) dataNode->SetSelected(false); dataNode->SetSelected(true,base); MITK_TEST_CONDITION(dataNode->IsSelected(base), "Testing if this node with right base renderer is set as selected" ) //Delete RenderWindow correctly renderWindow->Delete(); } static void TestGetMTime(mitk::DataNode::Pointer dataNode) { unsigned long time; time = dataNode->GetMTime(); mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); dataNode->SetData(pointSet); MITK_TEST_CONDITION( time != dataNode->GetMTime(), "Testing if the node timestamp is updated after adding data to the node" ) mitk::Point3D point; point.Fill(3.0); pointSet->SetPoint(0,point); //less or equal because dataNode timestamp is little later then the basedata timestamp MITK_TEST_CONDITION( pointSet->GetMTime() <= dataNode->GetMTime(), "Testing if the node timestamp is updated after base data was modified" ) // testing if changing anything in the property list also sets the node in a modified state unsigned long lastModified = dataNode->GetMTime(); dataNode->SetIntProperty("testIntProp", 2344); MITK_TEST_CONDITION( lastModified <= dataNode->GetMTime(), "Testing if the node timestamp is updated after property list was modified" ) } }; //mitkDataNodeTestClass int mitkDataNodeTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("DataNode") // Global interaction must(!) be initialized mitk::GlobalInteraction::GetInstance()->Initialize("global"); // let's create an object of our class mitk::DataNode::Pointer myDataNode = mitk::DataNode::New(); // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation") //test setData() Method mitkDataNodeTestClass::TestDataSetting(myDataNode); mitkDataNodeTestClass::TestMapperSetting(myDataNode); // //note, that no data is set to the dataNode mitkDataNodeTestClass::TestInteractorSetting(myDataNode); mitkDataNodeTestClass::TestPropertyList(myDataNode); mitkDataNodeTestClass::TestSelected(myDataNode); mitkDataNodeTestClass::TestGetMTime(myDataNode); // write your own tests here and use the macros from mitkTestingMacros.h !!! // do not write to std::cout and do not return from this function yourself! // always end with this! MITK_TEST_END() } 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..b1da2782df 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,307 @@ /*=================================================================== 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 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); } } 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); } } 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); } 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