diff --git a/Core/Code/Controllers/mitkSliceNavigationController.h b/Core/Code/Controllers/mitkSliceNavigationController.h index d44289adcf..74efc11c4c 100644 --- a/Core/Code/Controllers/mitkSliceNavigationController.h +++ b/Core/Code/Controllers/mitkSliceNavigationController.h @@ -1,606 +1,599 @@ /*=================================================================== 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 SLICENAVIGATIONCONTROLLER_H_HEADER_INCLUDED_C1C55A2F #define SLICENAVIGATIONCONTROLLER_H_HEADER_INCLUDED_C1C55A2F #include #include "mitkBaseController.h" #include "mitkRenderingManager.h" #include "mitkTimeGeometry.h" #include "mitkMessage.h" #pragma GCC visibility push(default) #include #pragma GCC visibility pop #include #include #include "mitkRestorePlanePositionOperation.h" #include "mitkDataStorage.h" //DEPRECATED #include namespace mitk { #define mitkTimeSlicedGeometryEventMacro( classname , super ) \ class MITK_CORE_EXPORT DEPRECATED(classname) : public super { \ public: \ typedef classname Self; \ typedef super Superclass; \ classname(TimeGeometry* aTimeGeometry, unsigned int aPos) \ : Superclass(aTimeGeometry, aPos) {} \ virtual ~classname() {} \ virtual const char * GetEventName() const { return #classname; } \ virtual bool CheckEvent(const ::itk::EventObject* e) const \ { return dynamic_cast(e); } \ virtual ::itk::EventObject* MakeObject() const \ { return new Self(GetTimeGeometry(), GetPos()); } \ private: \ void operator=(const Self&); \ } #define mitkTimeGeometryEventMacro( classname , super ) \ class MITK_CORE_EXPORT classname : public super { \ public: \ typedef classname Self; \ typedef super Superclass; \ classname(TimeGeometry* aTimeGeometry, unsigned int aPos) \ : Superclass(aTimeGeometry, aPos) {} \ virtual ~classname() {} \ virtual const char * GetEventName() const { return #classname; } \ virtual bool CheckEvent(const ::itk::EventObject* e) const \ { return dynamic_cast(e); } \ virtual ::itk::EventObject* MakeObject() const \ { return new Self(GetTimeGeometry(), GetPos()); } \ private: \ void operator=(const Self&); \ } class PlaneGeometry; class Geometry3D; class BaseRenderer; /** * \brief Controls the selection of the slice the associated BaseRenderer * will display * * A SliceNavigationController takes a Geometry3D or a TimeGeometry as input world geometry * (TODO what are the exact requirements?) and generates a TimeGeometry * as output. The TimeGeometry holds a number of SlicedGeometry3Ds and * these in turn hold a series of Geometry2Ds. One of these Geometry2Ds is * selected as world geometry for the BaseRenderers associated to 2D views. * * The SliceNavigationController holds has Steppers (one for the slice, a * second for the time step), which control the selection of a single * Geometry2D from the TimeGeometry. SliceNavigationController generates * ITK events to tell observers, like a BaseRenderer, when the selected slice * or timestep changes. * * SliceNavigationControllers are registered as listeners to GlobalInteraction * by the QmitkStdMultiWidget. In ExecuteAction, the controllers react to * PositionEvents by setting the steppers to the slice which is nearest to the * point of the PositionEvent. * * Example: * \code * // Initialization * sliceCtrl = mitk::SliceNavigationController::New(); * * // Tell the navigator the geometry to be sliced (with geometry a * // Geometry3D::ConstPointer) * sliceCtrl->SetInputWorldGeometry(geometry.GetPointer()); * * // Tell the navigator in which direction it shall slice the data * sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Axial); * * // Connect one or more BaseRenderer to this navigator, i.e.: events sent * // by the navigator when stepping through the slices (e.g. by * // sliceCtrl->GetSlice()->Next()) will be received by the BaseRenderer * // (in this example only slice-changes, see also ConnectGeometryTimeEvent * // and ConnectGeometryEvents.) * sliceCtrl->ConnectGeometrySliceEvent(renderer.GetPointer()); * * //create a world geometry and send the information to the connected renderer(s) * sliceCtrl->Update(); * \endcode * * * You can connect visible navigators to a SliceNavigationController, e.g., a * QmitkSliderNavigator (for Qt): * * \code * // Create the visible navigator (a slider with a spin-box) * QmitkSliderNavigator* navigator = * new QmitkSliderNavigator(parent, "slidernavigator"); * * // Connect the navigator to the slice-stepper of the * // SliceNavigationController. For initialization (position, mininal and * // maximal values) the values of the SliceNavigationController are used. * // Thus, accessing methods of a navigator is normally not necessary, since * // everything can be set via the (Qt-independent) SliceNavigationController. * // The QmitkStepperAdapter converts the Qt-signals to Qt-independent * // itk-events. * new QmitkStepperAdapter(navigator, sliceCtrl->GetSlice(), "navigatoradaptor"); * \endcode * * If you do not want that all renderwindows are updated when a new slice is * selected, you can use a specific RenderingManager, which updates only those * renderwindows that should be updated. This is sometimes useful when a 3D view * does not need to be updated when the slices in some 2D views are changed. * QmitkSliderNavigator (for Qt): * * \code * // create a specific RenderingManager * mitk::RenderingManager::Pointer myManager = mitk::RenderingManager::New(); * * // tell the RenderingManager to update only renderwindow1 and renderwindow2 * myManager->AddRenderWindow(renderwindow1); * myManager->AddRenderWindow(renderwindow2); * * // tell the SliceNavigationController of renderwindow1 and renderwindow2 * // to use the specific RenderingManager instead of the global one * renderwindow1->GetSliceNavigationController()->SetRenderingManager(myManager); * renderwindow2->GetSliceNavigationController()->SetRenderingManager(myManager); * \endcode * * \todo implement for non-evenly-timed geometry! * \ingroup NavigationControl */ class MITK_CORE_EXPORT SliceNavigationController : public BaseController { public: mitkClassMacro(SliceNavigationController,BaseController); itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkNewMacro1Param(Self, const char *); /** * \brief Possible view directions, \a Original will uses * the Geometry2D instances in a SlicedGeometry3D provided * as input world geometry (by SetInputWorldGeometry). */ enum ViewDirection { -#ifdef _MSC_VER - Transversal, // deprecated -#endif - Axial = 0, - Sagittal = 1, - Frontal = 2, + Axial, + Sagittal, + Frontal, Original }; -#ifdef __GNUC__ - __attribute__ ((deprecated)) static const ViewDirection Transversal = ViewDirection(Axial); -#endif - /** * \brief Set the input world geometry3D out of which the * geometries for slicing will be created. * * Any previous previous set input geometry (3D or Time) will * be ignored in future. */ void SetInputWorldGeometry3D(const mitk::Geometry3D* geometry); itkGetConstObjectMacro(InputWorldGeometry3D, mitk::Geometry3D); /** * \brief Set the input world geometry3D out of which the * geometries for slicing will be created. * * Any previous previous set input geometry (3D or Time) will * be ignored in future. * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201 */ DEPRECATED(void SetInputWorldGeometry(const mitk::TimeSlicedGeometry* geometry)); /** * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201 */ DEPRECATED(TimeSlicedGeometry* GetInputWorldGeometry()); void SetInputWorldTimeGeometry(const mitk::TimeGeometry* geometry); itkGetConstObjectMacro(InputWorldTimeGeometry, mitk::TimeGeometry); /** * \brief Access the created geometry */ itkGetConstObjectMacro(CreatedWorldGeometry, mitk::TimeGeometry); /** * \brief Set the desired view directions * * \sa ViewDirection * \sa Update(ViewDirection viewDirection, bool top = true, * bool frontside = true, bool rotated = false) */ itkSetEnumMacro(ViewDirection, ViewDirection); itkGetEnumMacro(ViewDirection, ViewDirection); /** * \brief Set the default view direction * * This is used to re-initialize the view direction of the SNC to the * default value with SetViewDirectionToDefault() * * \sa ViewDirection * \sa Update(ViewDirection viewDirection, bool top = true, * bool frontside = true, bool rotated = false) */ itkSetEnumMacro(DefaultViewDirection, ViewDirection); itkGetEnumMacro(DefaultViewDirection, ViewDirection); const char* GetViewDirectionAsString(); virtual void SetViewDirectionToDefault(); /** * \brief Do the actual creation and send it to the connected * observers (renderers) * */ virtual void Update(); /** * \brief Extended version of Update, additionally allowing to * specify the direction/orientation of the created geometry. * */ virtual void Update(ViewDirection viewDirection, bool top = true, bool frontside = true, bool rotated = false); /** * \brief Send the created geometry to the connected * observers (renderers) * * Called by Update(). */ virtual void SendCreatedWorldGeometry(); /** * \brief Tell observers to re-read the currently selected 2D geometry * * Called by mitk::SlicesRotator during rotation. */ virtual void SendCreatedWorldGeometryUpdate(); /** * \brief Send the currently selected slice to the connected * observers (renderers) * * Called by Update(). */ virtual void SendSlice(); /** * \brief Send the currently selected time to the connected * observers (renderers) * * Called by Update(). */ virtual void SendTime(); /** * \brief Set the RenderingManager to be used * * If \a NULL, the default RenderingManager will be used. */ itkSetObjectMacro(RenderingManager, RenderingManager); mitk::RenderingManager* GetRenderingManager() const; #pragma GCC visibility push(default) itkEventMacro( UpdateEvent, itk::AnyEvent ); #pragma GCC visibility pop class MITK_CORE_EXPORT TimeGeometryEvent : public itk::AnyEvent { public: typedef TimeGeometryEvent Self; typedef itk::AnyEvent Superclass; TimeGeometryEvent( TimeGeometry* aTimeGeometry, unsigned int aPos) : m_TimeGeometry(aTimeGeometry), m_Pos(aPos) {} virtual ~TimeGeometryEvent() {} virtual const char * GetEventName() const { return "TimeGeometryEvent"; } virtual bool CheckEvent(const ::itk::EventObject* e) const { return dynamic_cast(e); } virtual ::itk::EventObject* MakeObject() const { return new Self(m_TimeGeometry, m_Pos); } TimeGeometry* GetTimeGeometry() const { return m_TimeGeometry; } unsigned int GetPos() const { return m_Pos; } private: TimeGeometry::Pointer m_TimeGeometry; unsigned int m_Pos; // TimeGeometryEvent(const Self&); void operator=(const Self&); //just hide }; /** * \deprecatedSince{2013_09} Please use TimeGeometryEvent instead: For additional information see http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201 */ DEPRECATED(typedef TimeGeometryEvent TimeSlicedGeometryEvent); mitkTimeGeometryEventMacro( GeometrySendEvent,TimeGeometryEvent ); mitkTimeGeometryEventMacro( GeometryUpdateEvent, TimeGeometryEvent ); mitkTimeGeometryEventMacro( GeometryTimeEvent, TimeGeometryEvent ); mitkTimeGeometryEventMacro( GeometrySliceEvent, TimeGeometryEvent ); template void ConnectGeometrySendEvent(T* receiver) { typedef typename itk::ReceptorMemberCommand::Pointer ReceptorMemberCommandPointer; ReceptorMemberCommandPointer eventReceptorCommand = itk::ReceptorMemberCommand::New(); eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometry); unsigned long tag = AddObserver(GeometrySendEvent(NULL,0), eventReceptorCommand); m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag); } template void ConnectGeometryUpdateEvent(T* receiver) { typedef typename itk::ReceptorMemberCommand::Pointer ReceptorMemberCommandPointer; ReceptorMemberCommandPointer eventReceptorCommand = itk::ReceptorMemberCommand::New(); eventReceptorCommand->SetCallbackFunction(receiver, &T::UpdateGeometry); unsigned long tag = AddObserver(GeometryUpdateEvent(NULL,0), eventReceptorCommand); m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag); } template void ConnectGeometrySliceEvent(T* receiver, bool connectSendEvent=true) { typedef typename itk::ReceptorMemberCommand::Pointer ReceptorMemberCommandPointer; ReceptorMemberCommandPointer eventReceptorCommand = itk::ReceptorMemberCommand::New(); eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometrySlice); unsigned long tag = AddObserver(GeometrySliceEvent(NULL,0), eventReceptorCommand); m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag); if(connectSendEvent) ConnectGeometrySendEvent(receiver); } template void ConnectGeometryTimeEvent(T* receiver, bool connectSendEvent=true) { typedef typename itk::ReceptorMemberCommand::Pointer ReceptorMemberCommandPointer; ReceptorMemberCommandPointer eventReceptorCommand = itk::ReceptorMemberCommand::New(); eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometryTime); unsigned long tag = AddObserver(GeometryTimeEvent(NULL,0), eventReceptorCommand); m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag); if(connectSendEvent) ConnectGeometrySendEvent(receiver); } template void ConnectGeometryEvents(T* receiver) { //connect sendEvent only once ConnectGeometrySliceEvent(receiver, false); ConnectGeometryTimeEvent(receiver); } // use a templated method to get the right offset when casting to void* template void Disconnect(T* receiver) { ObserverTagsMapType::iterator i = m_ReceiverToObserverTagsMap.find(static_cast(receiver)); if (i == m_ReceiverToObserverTagsMap.end()) return; const std::list& tags = i->second; for (std::list::const_iterator tagIter = tags.begin(); tagIter != tags.end(); ++tagIter) { RemoveObserver(*tagIter); } m_ReceiverToObserverTagsMap.erase(i); } Message<> crosshairPositionEvent; /** * \brief To connect multiple SliceNavigationController, we can * act as an observer ourselves: implemented interface * \warning not implemented */ virtual void SetGeometry(const itk::EventObject & geometrySliceEvent); /** * \brief To connect multiple SliceNavigationController, we can * act as an observer ourselves: implemented interface */ virtual void SetGeometrySlice(const itk::EventObject & geometrySliceEvent); /** * \brief To connect multiple SliceNavigationController, we can * act as an observer ourselves: implemented interface */ virtual void SetGeometryTime(const itk::EventObject & geometryTimeEvent); /** \brief Positions the SNC according to the specified point */ void SelectSliceByPoint( const mitk::Point3D &point ); /** \brief Returns the TimeGeometry created by the SNC. */ mitk::TimeGeometry *GetCreatedWorldGeometry(); /** \brief Returns the Geometry3D of the currently selected time step. */ const mitk::Geometry3D *GetCurrentGeometry3D(); /** \brief Returns the currently selected Plane in the current * Geometry3D (if existent). */ const mitk::PlaneGeometry *GetCurrentPlaneGeometry(); /** \brief Sets the BaseRenderer associated with this SNC (if any). While * the BaseRenderer is not directly used by SNC, this is a convenience * method to enable BaseRenderer access via the SNC. */ void SetRenderer( BaseRenderer *renderer ); /** \brief Gets the BaseRenderer associated with this SNC (if any). While * the BaseRenderer is not directly used by SNC, this is a convenience * method to enable BaseRenderer access via the SNC. Returns NULL if no * BaseRenderer has been specified*/ BaseRenderer *GetRenderer() const; /** \brief Re-orients the slice stack. All slices will be oriented to the given normal vector. The given point (world coordinates) defines the selected slice. Careful: The resulting axis vectors are not clearly defined this way. If you want to define them clearly, use ReorientSlices (const mitk::Point3D &point, const mitk::Vector3D &axisVec0, const mitk::Vector3D &axisVec1). */ void ReorientSlices( const mitk::Point3D &point, const mitk::Vector3D &normal ); /** \brief Re-orients the slice stack so that all planes are oriented according to the * given axis vectors. The given Point eventually defines selected slice. */ void ReorientSlices( const mitk::Point3D &point, const mitk::Vector3D &axisVec0, const mitk::Vector3D &axisVec1 ); virtual bool ExecuteAction( Action* action, mitk::StateEvent const* stateEvent); void ExecuteOperation(Operation* operation); /** * \brief Feature option to lock planes during mouse interaction. * This option flag disables the mouse event which causes the center * cross to move near by. */ itkSetMacro(SliceLocked, bool); itkGetMacro(SliceLocked, bool); itkBooleanMacro(SliceLocked); /** * \brief Feature option to lock slice rotation. * * This option flag disables separately the rotation of a slice which is * implemented in mitkSliceRotator. */ itkSetMacro(SliceRotationLocked, bool); itkGetMacro(SliceRotationLocked, bool); itkBooleanMacro(SliceRotationLocked); /** * \brief Adjusts the numerical range of the slice stepper according to * the current geometry orientation of this SNC's SlicedGeometry. */ void AdjustSliceStepperRange(); protected: SliceNavigationController(const char * type = NULL); virtual ~SliceNavigationController(); mitk::DataNode::Pointer GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes,mitk::Point3D worldposition); /* template static void buildstring( mitkIpPicDescriptor *pic, itk::Point p, std::string &s, T = 0) { std::string value; std::stringstream stream; stream.imbue(std::locale::classic()); stream<=0 && p[1] >=0 && p[2]>=0) && (unsigned int)p[0] < pic->n[0] && (unsigned int)p[1] < pic->n[1] && (unsigned int)p[2] < pic->n[2] ) { if(pic->bpe!=24) { stream<<(((T*) pic->data)[ p[0] + p[1]*pic->n[0] + p[2]*pic->n[0]*pic->n[1] ]); } else { stream<<(((T*) pic->data)[p[0]*3 + 0 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 ]); stream<<(((T*) pic->data)[p[0]*3 + 1 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 ]); stream<<(((T*) pic->data)[p[0]*3 + 2 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 ]); } s = stream.str(); } else { s+= "point out of data"; } }; */ mitk::Geometry3D::ConstPointer m_InputWorldGeometry3D; mitk::TimeGeometry::ConstPointer m_InputWorldTimeGeometry; mitk::TimeGeometry::Pointer m_CreatedWorldGeometry; ViewDirection m_ViewDirection; ViewDirection m_DefaultViewDirection; mitk::RenderingManager::Pointer m_RenderingManager; mitk::BaseRenderer *m_Renderer; itkSetMacro(Top, bool); itkGetMacro(Top, bool); itkBooleanMacro(Top); itkSetMacro(FrontSide, bool); itkGetMacro(FrontSide, bool); itkBooleanMacro(FrontSide); itkSetMacro(Rotated, bool); itkGetMacro(Rotated, bool); itkBooleanMacro(Rotated); bool m_Top; bool m_FrontSide; bool m_Rotated; bool m_BlockUpdate; bool m_SliceLocked; bool m_SliceRotationLocked; unsigned int m_OldPos; typedef std::map > ObserverTagsMapType; ObserverTagsMapType m_ReceiverToObserverTagsMap; }; } // namespace mitk #endif /* SLICENAVIGATIONCONTROLLER_H_HEADER_INCLUDED_C1C55A2F */ diff --git a/Core/Code/DataManagement/mitkDataNode.cpp b/Core/Code/DataManagement/mitkDataNode.cpp index 57e790dfe6..22fdada0d5 100644 --- a/Core/Code/DataManagement/mitkDataNode.cpp +++ b/Core/Code/DataManagement/mitkDataNode.cpp @@ -1,568 +1,579 @@ /*=================================================================== 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 "mitkCoreObjectFactory.h" #include #include "mitkProperties.h" #include "mitkStringProperty.h" #include "mitkGroupTagProperty.h" #include "mitkSmartPointerProperty.h" //#include "mitkMaterialProperty.h" #include "mitkColorProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkGeometry3D.h" #include "mitkRenderingManager.h" #include "mitkGlobalInteraction.h" #include "mitkEventMapper.h" #include "mitkGenericProperty.h" #include "mitkCoreObjectFactory.h" mitk::Mapper* mitk::DataNode::GetMapper(MapperSlotId id) const { if( (id >= m_Mappers.size()) || (m_Mappers[id].IsNull()) ) { if(id >= m_Mappers.capacity()) { // int i, size=id-m_Mappers.capacity()+10; m_Mappers.resize(id+10); } m_Mappers[id] = CoreObjectFactory::GetInstance()->CreateMapper(const_cast(this),id); } return m_Mappers[id]; } mitk::BaseData* mitk::DataNode::GetData() const { return m_Data; } mitk::Interactor* mitk::DataNode::GetInteractor() const { return m_Interactor; } void mitk::DataNode::SetData(mitk::BaseData* baseData) { if(m_Data!=baseData) { m_Data=baseData; m_Mappers.clear(); m_Mappers.resize(10); mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this); m_DataReferenceChangedTime.Modified(); Modified(); //inform the interactor about the change if (m_Interactor.IsNotNull()) m_Interactor->DataChanged(); } } void mitk::DataNode::SetInteractor(mitk::Interactor* interactor) { m_Interactor = interactor; if(m_Interactor.IsNotNull()) m_Interactor->SetDataNode(this); } mitk::DataNode::DataNode() : m_Data(NULL), m_PropertyListModifiedObserverTag(0) { m_Mappers.resize(10); m_PropertyList = PropertyList::New(); // subscribe for modified event itk::MemberCommand::Pointer _PropertyListModifiedCommand = itk::MemberCommand::New(); _PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::DataNode::PropertyListModified); m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand); } mitk::DataNode::~DataNode() { if(m_PropertyList.IsNotNull()) // remove modified event listener m_PropertyList->RemoveObserver(m_PropertyListModifiedObserverTag); Interactor* interactor = this->GetInteractor(); if ( interactor ) { mitk::GlobalInteraction::GetInstance()->RemoveInteractor( interactor ); } m_Mappers.clear(); m_Data = NULL; } mitk::DataNode& mitk::DataNode::operator=(const DataNode& right) { mitk::DataNode* node=mitk::DataNode::New(); node->SetData(right.GetData()); return *node; } mitk::DataNode& mitk::DataNode::operator=(mitk::BaseData* right) { mitk::DataNode* node=mitk::DataNode::New(); node->SetData(right); return *node; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) MBI_STD::istream& mitk::operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn ) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) MBI_STD::istream& operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn ) #endif { dtn = mitk::DataNode::New(); //i >> av.get(); return i; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) MBI_STD::ostream& mitk::operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) MBI_STD::ostream& operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn) #endif { if(dtn->GetData()!=NULL) o<GetData()->GetNameOfClass(); else o<<"empty data"; return o; } void mitk::DataNode::SetMapper(MapperSlotId id, mitk::Mapper* mapper) { m_Mappers[id] = mapper; if (mapper!=NULL) mapper->SetDataNode(this); } void mitk::DataNode::UpdateOutputInformation() { if (this->GetSource()) { this->GetSource()->UpdateOutputInformation(); } } void mitk::DataNode::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::DataNode::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::DataNode::VerifyRequestedRegion() { return true; } void mitk::DataNode::SetRequestedRegion( const itk::DataObject * /*data*/) { } void mitk::DataNode::CopyInformation(const itk::DataObject * /*data*/) { } + mitk::PropertyList* mitk::DataNode::GetPropertyList(const mitk::BaseRenderer* renderer) const { if(renderer==NULL) return m_PropertyList; - mitk::PropertyList::Pointer & propertyList = m_MapOfPropertyLists[renderer]; + return this->GetPropertyList(renderer->GetName()); +} + +mitk::PropertyList* mitk::DataNode::GetPropertyList(const std::string& rendererName) const +{ + if (rendererName.empty()) + return m_PropertyList; + + mitk::PropertyList::Pointer & propertyList = m_MapOfPropertyLists[rendererName]; if(propertyList.IsNull()) propertyList = mitk::PropertyList::New(); - assert(m_MapOfPropertyLists[renderer].IsNotNull()); + assert(m_MapOfPropertyLists[rendererName].IsNotNull()); return propertyList; } void mitk::DataNode::ConcatenatePropertyList(PropertyList *pList, bool replace) { m_PropertyList->ConcatenatePropertyList(pList, replace); } mitk::BaseProperty* mitk::DataNode::GetProperty(const char *propertyKey, const mitk::BaseRenderer* renderer) const { if(propertyKey==NULL) return NULL; //renderer specified? if (renderer) { - std::map::const_iterator it; + std::string rendererName = renderer->GetName(); + + MapOfPropertyLists::const_iterator it; //check for the renderer specific property - it=m_MapOfPropertyLists.find(renderer); + it=m_MapOfPropertyLists.find(rendererName); if(it!=m_MapOfPropertyLists.end()) //found { mitk::BaseProperty::Pointer property; property=it->second->GetProperty(propertyKey); if(property.IsNotNull())//found an enabled property in the render specific list return property; else //found a renderer specific list, but not the desired property return m_PropertyList->GetProperty(propertyKey); //return renderer unspecific property } else //didn't find the property list of the given renderer { //return the renderer unspecific property if there is one return m_PropertyList->GetProperty(propertyKey); } } else //no specific renderer given; use the renderer independent one { mitk::BaseProperty::Pointer property; property=m_PropertyList->GetProperty(propertyKey); if(property.IsNotNull()) return property; } //only to satisfy compiler! return NULL; } mitk::DataNode::GroupTagList mitk::DataNode::GetGroupTags() const { GroupTagList groups; const PropertyList::PropertyMap* propertyMap = m_PropertyList->GetMap(); for ( PropertyList::PropertyMap::const_iterator groupIter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here groupIter != propertyMap->end(); ++groupIter ) { const BaseProperty* bp = groupIter->second; if ( dynamic_cast(bp) ) { groups.insert( groupIter->first ); } } return groups; } bool mitk::DataNode::GetBoolProperty(const char* propertyKey, bool& boolValue, mitk::BaseRenderer* renderer) const { mitk::BoolProperty::Pointer boolprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(boolprop.IsNull()) return false; boolValue = boolprop->GetValue(); return true; } bool mitk::DataNode::GetIntProperty(const char* propertyKey, int &intValue, mitk::BaseRenderer* renderer) const { mitk::IntProperty::Pointer intprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(intprop.IsNull()) return false; intValue = intprop->GetValue(); return true; } bool mitk::DataNode::GetFloatProperty(const char* propertyKey, float &floatValue, mitk::BaseRenderer* renderer) const { mitk::FloatProperty::Pointer floatprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(floatprop.IsNull()) return false; floatValue = floatprop->GetValue(); return true; } bool mitk::DataNode::GetStringProperty(const char* propertyKey, std::string& string, mitk::BaseRenderer* renderer) const { mitk::StringProperty::Pointer stringProp = dynamic_cast(GetProperty(propertyKey, renderer)); if(stringProp.IsNull()) { return false; } else { //memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous string = stringProp->GetValue(); return true; } } bool mitk::DataNode::GetColor(float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey) const { mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(colorprop.IsNull()) return false; memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); return true; } bool mitk::DataNode::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* propertyKey) const { mitk::FloatProperty::Pointer opacityprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(opacityprop.IsNull()) return false; opacity=opacityprop->GetValue(); return true; } bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey) const { mitk::LevelWindowProperty::Pointer levWinProp = dynamic_cast(GetProperty(propertyKey, renderer)); if(levWinProp.IsNull()) return false; levelWindow=levWinProp->GetLevelWindow(); return true; } void mitk::DataNode::SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(color); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer, const char* propertyKey) { float color[3]; color[0]=red; color[1]=green; color[2]=blue; SetColor(color, renderer, propertyKey); } void mitk::DataNode::SetColor(const float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(rgb); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetVisibility(bool visible, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::BoolProperty::Pointer prop; prop = mitk::BoolProperty::New(visible); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetOpacity(float opacity, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::FloatProperty::Pointer prop; prop = mitk::FloatProperty::New(opacity); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::LevelWindowProperty::Pointer prop; prop = mitk::LevelWindowProperty::New(levelWindow); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetIntProperty(const char* propertyKey, int intValue, mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::DataNode::SetBoolProperty( const char* propertyKey, bool boolValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::DataNode::SetFloatProperty( const char* propertyKey, float floatValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::DataNode::SetStringProperty( const char* propertyKey, const char* stringValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } void mitk::DataNode::SetProperty(const char *propertyKey, BaseProperty* propertyValue, const mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue); } void mitk::DataNode::ReplaceProperty(const char *propertyKey, BaseProperty* propertyValue, const mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue); } void mitk::DataNode::AddProperty(const char *propertyKey, BaseProperty* propertyValue, const mitk::BaseRenderer* renderer, bool overwrite) { if((overwrite) || (GetProperty(propertyKey, renderer) == NULL)) { SetProperty(propertyKey, propertyValue, renderer); } } vtkLinearTransform* mitk::DataNode::GetVtkTransform(int t) const { assert(m_Data.IsNotNull()); mitk::Geometry3D* geometry = m_Data->GetGeometry(t); if(geometry == NULL) return NULL; return geometry->GetVtkTransform(); } unsigned long mitk::DataNode::GetMTime() const { unsigned long time = Superclass::GetMTime(); if(m_Data.IsNotNull()) { if((time < m_Data->GetMTime()) || ((m_Data->GetSource().IsNotNull()) && (time < m_Data->GetSource()->GetMTime())) ) { Modified(); return Superclass::GetMTime(); } } return time; } void mitk::DataNode::SetSelected(bool selected, mitk::BaseRenderer* renderer) { mitk::BoolProperty::Pointer selectedProperty = dynamic_cast(GetProperty("selected")); if ( selectedProperty.IsNull() ) { selectedProperty = mitk::BoolProperty::New(); selectedProperty->SetValue(false); SetProperty("selected", selectedProperty, renderer); } if( selectedProperty->GetValue() != selected ) { selectedProperty->SetValue(selected); itk::ModifiedEvent event; InvokeEvent( event ); } } /* class SelectedEvent : public itk::ModifiedEvent { public: typedef SelectedEvent Self; typedef itk::ModifiedEvent Superclass; SelectedEvent(DataNode* dataNode) { m_DataNode = dataNode; }; DataNode* GetDataNode() { return m_DataNode; }; virtual const char * GetEventName() const { return "SelectedEvent"; } virtual bool CheckEvent(const ::itk::EventObject* e) const { return dynamic_cast(e); } virtual ::itk::EventObject* MakeObject() const { return new Self(m_DataNode); } private: DataNode* m_DataNode; SelectedEvent(const Self& event) { m_DataNode = event.m_DataNode; }; void operator=(const Self& event) { m_DataNode = event.m_DataNode; } }; */ bool mitk::DataNode::IsSelected(mitk::BaseRenderer* renderer) { bool selected; if ( !GetBoolProperty("selected", selected, renderer) ) return false; return selected; } void mitk::DataNode::SetInteractorEnabled( const bool& enabled ) { if ( m_Interactor.IsNull() ) { itkWarningMacro("Interactor is NULL. Couldn't enable or disable interaction."); return; } if ( enabled ) mitk::GlobalInteraction::GetInstance()->AddInteractor( m_Interactor.GetPointer() ); else mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor.GetPointer() ); } void mitk::DataNode::EnableInteractor() { SetInteractorEnabled( true ); } void mitk::DataNode::DisableInteractor() { SetInteractorEnabled( false ); } bool mitk::DataNode::IsInteractorEnabled() const { return mitk::GlobalInteraction::GetInstance()->InteractorRegistered( m_Interactor.GetPointer() ); } void mitk::DataNode::SetDataInteractor(const DataInteractor::Pointer& interactor) { m_DataInteractor = interactor; Modified(); // the interactor has changed, so we have ti invoke an InteractorChangedEvent const mitk::DataNode::InteractorChangedEvent changedEvent; InvokeEvent( changedEvent ); } mitk::DataInteractor::Pointer mitk::DataNode::GetDataInteractor() const { return m_DataInteractor; } void mitk::DataNode::PropertyListModified( const itk::Object* /*caller*/, const itk::EventObject& ) { Modified(); } diff --git a/Core/Code/DataManagement/mitkDataNode.h b/Core/Code/DataManagement/mitkDataNode.h index 194e0b518f..1b735eb02e 100644 --- a/Core/Code/DataManagement/mitkDataNode.h +++ b/Core/Code/DataManagement/mitkDataNode.h @@ -1,540 +1,541 @@ /*=================================================================== 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 DATATREENODE_H_HEADER_INCLUDED_C1E14338 #define DATATREENODE_H_HEADER_INCLUDED_C1E14338 #include "mitkImageSource.h" #include "mitkBaseData.h" //#include "mitkMapper.h" #include "mitkInteractor.h" #include "mitkDataInteractor.h" #ifdef MBI_NO_STD_NAMESPACE #define MBI_STD #include #include #else #define MBI_STD std #include #include #endif #include "mitkStringProperty.h" #include "mitkColorProperty.h" #include "mitkPropertyList.h" //#include "mitkMapper.h" #include #include #include "mitkLevelWindow.h" class vtkLinearTransform; namespace mitk { class BaseRenderer; class Mapper; //##Documentation //## @brief Class for nodes of the DataTree //## //## Contains the data (instance of BaseData), a list of mappers, which can //## draw the data, a transform (vtkTransform) and a list of properties //## (PropertyList). //## @ingroup DataManagement //## //## @todo clean up all the GetProperty methods. There are too many different flavours... Can most probably be reduced to bool GetProperty(type&) //## //## @warning Change in semantics of SetProperty() since Aug 25th 2006. Check your usage of this method if you do //## more with properties than just call SetProperty( "key", new SomeProperty("value") ). class MITK_CORE_EXPORT DataNode : public itk::DataObject { public: typedef mitk::Geometry3D::Pointer Geometry3DPointer; typedef std::vector< itk::SmartPointer< Mapper > > MapperVector; - typedef std::map MapOfPropertyLists; + typedef std::map MapOfPropertyLists; typedef std::set GroupTagList; /** * \brief Definition of an itk::Event that is invoked when * a DataInteractor is set on this DataNode. */ itkEventMacro(InteractorChangedEvent, itk::AnyEvent); mitkClassMacro(DataNode, itk::DataObject); itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitk::Mapper* GetMapper(MapperSlotId id) const; //##Documentation //## @brief Get the data object (instance of BaseData, e.g., an Image) //## managed by this DataNode BaseData* GetData() const; //##Documentation //## @brief Get the transformation applied prior to displaying the data as //## a vtkTransform //## \deprecated use GetData()->GetGeometry()->GetVtkTransform() instead vtkLinearTransform* GetVtkTransform(int t=0) const; //##Documentation //## @brief Get the Interactor. //## @deprecatedSince{2013_03} Use DataInteractor and GetDataInteractor instead. Interactor* GetInteractor() const; //##Documentation //## @brief Set the data object (instance of BaseData, e.g., an Image) //## managed by this DataNode //## @warning the actor-mode of the vtkInteractor does not work any more, if the transform of the //## data-tree-node is connected to the transform of the basedata via vtkTransform->SetInput. virtual void SetData(mitk::BaseData* baseData); //##Documentation //## @brief Set the Interactor. //## @deprecatedSince{2013_03} Use DataInteractor and SetDataInteractor instead. virtual void SetInteractor(Interactor* interactor); virtual void SetDataInteractor(const DataInteractor::Pointer& interactor); virtual DataInteractor::Pointer GetDataInteractor() const; mitk::DataNode& operator=(const DataNode& right); mitk::DataNode& operator=(BaseData* right); virtual void SetMapper(MapperSlotId id, mitk::Mapper* mapper); virtual void UpdateOutputInformation(); virtual void SetRequestedRegionToLargestPossibleRegion(); virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); virtual bool VerifyRequestedRegion(); virtual void SetRequestedRegion( const itk::DataObject *data); virtual void CopyInformation(const itk::DataObject *data); //##Documentation //## @brief Set the property (instance of BaseProperty) with key @a propertyKey in the PropertyList //## of the @a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-value. //## //## @warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do //## more with properties than just call SetProperty( "key", new SomeProperty("value") ). //## //## @sa GetProperty //## @sa m_PropertyList //## @sa m_MapOfPropertyLists void SetProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL); //##Documentation //## @brief Replace the property (instance of BaseProperty) with key @a propertyKey in the PropertyList //## of the @a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-reference. //## //## If @a renderer is @a NULL the property is set in the BaseRenderer-independent //## PropertyList of this DataNode. //## @sa GetProperty //## @sa m_PropertyList //## @sa m_MapOfPropertyLists void ReplaceProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL); //##Documentation //## @brief Add the property (instance of BaseProperty) if it does //## not exist (or always if \a overwrite is \a true) //## with key @a propertyKey in the PropertyList //## of the @a renderer (if NULL, use BaseRenderer-independent //## PropertyList). This is set-by-value. //## //## For \a overwrite == \a false the property is \em not changed //## if it already exists. For \a overwrite == \a true the method //## is identical to SetProperty. //## //## @sa SetProperty //## @sa GetProperty //## @sa m_PropertyList //## @sa m_MapOfPropertyLists void AddProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL, bool overwrite = false); //##Documentation //## @brief Get the PropertyList of the @a renderer. If @a renderer is @a //## NULL, the BaseRenderer-independent PropertyList of this DataNode //## is returned. //## @sa GetProperty //## @sa m_PropertyList //## @sa m_MapOfPropertyLists mitk::PropertyList* GetPropertyList(const mitk::BaseRenderer* renderer = NULL) const; + mitk::PropertyList* GetPropertyList(const std::string& rendererName) const; //##Documentation //## @brief Add values from another PropertyList. //## //## Overwrites values in m_PropertyList only when possible (i.e. when types are compatible). //## If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty, //## set the @param replace. //## //## @param replace true: if @param pList contains a property "visible" of type ColorProperty and our m_PropertyList also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects behind the pointer. //## //## @sa SetProperty //## @sa ReplaceProperty //## @sa m_PropertyList void ConcatenatePropertyList(PropertyList* pList, bool replace = false); //##Documentation //## @brief Get the property (instance of BaseProperty) with key @a propertyKey from the PropertyList //## of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. //## //## If @a renderer is @a NULL or the @a propertyKey cannot be found //## in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent //## PropertyList of this DataNode is queried. //## @sa GetPropertyList //## @sa m_PropertyList //## @sa m_MapOfPropertyLists mitk::BaseProperty* GetProperty(const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const; //##Documentation //## @brief Get the property of type T with key @a propertyKey from the PropertyList //## of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. //## //## If @a renderer is @a NULL or the @a propertyKey cannot be found //## in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent //## PropertyList of this DataNode is queried. //## @sa GetPropertyList //## @sa m_PropertyList //## @sa m_MapOfPropertyLists template bool GetProperty(itk::SmartPointer &property, const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property.IsNotNull(); } //##Documentation //## @brief Get the property of type T with key @a propertyKey from the PropertyList //## of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. //## //## If @a renderer is @a NULL or the @a propertyKey cannot be found //## in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent //## PropertyList of this DataNode is queried. //## @sa GetPropertyList //## @sa m_PropertyList //## @sa m_MapOfPropertyLists template bool GetProperty(T* &property, const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property!=NULL; } //##Documentation //## @brief Convenience access method for GenericProperty properties //## (T being the type of the second parameter) //## @return @a true property was found template bool GetPropertyValue(const char* propertyKey, T & value, mitk::BaseRenderer* renderer=NULL) const { GenericProperty* gp= dynamic_cast*>(GetProperty(propertyKey, renderer)); if ( gp != NULL ) { value = gp->GetValue(); return true; } return false; } // @brief Get a set of all group tags from this node's property list GroupTagList GetGroupTags() const; //##Documentation //## @brief Convenience access method for bool properties (instances of //## BoolProperty) //## @return @a true property was found bool GetBoolProperty(const char* propertyKey, bool &boolValue, mitk::BaseRenderer* renderer = NULL) const; //##Documentation //## @brief Convenience access method for int properties (instances of //## IntProperty) //## @return @a true property was found bool GetIntProperty(const char* propertyKey, int &intValue, mitk::BaseRenderer* renderer=NULL) const; //##Documentation //## @brief Convenience access method for float properties (instances of //## FloatProperty) //## @return @a true property was found bool GetFloatProperty(const char* propertyKey, float &floatValue, mitk::BaseRenderer* renderer = NULL) const; //##Documentation //## @brief Convenience access method for string properties (instances of //## StringProperty) //## @return @a true property was found bool GetStringProperty(const char* propertyKey, std::string& string, mitk::BaseRenderer* renderer = NULL) const; //##Documentation //## @brief Convenience access method for color properties (instances of //## ColorProperty) //## @return @a true property was found bool GetColor(float rgb[3], mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color") const; //##Documentation //## @brief Convenience access method for level-window properties (instances of //## LevelWindowProperty) //## @return @a true property was found bool GetLevelWindow(mitk::LevelWindow &levelWindow, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow") const; //## //##Documentation //## @brief set the node as selected void SetSelected(bool selected, mitk::BaseRenderer* renderer=NULL); //## //##Documentation //## @brief set the node as selected //## @return @a true node is selected bool IsSelected(mitk::BaseRenderer* renderer=NULL); //##Documentation //## @brief Convenience access method for accessing the name of an object (instance of //## StringProperty with property-key "name") //## @return @a true property was found bool GetName(std::string& nodeName, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "name") const { return GetStringProperty(propertyKey, nodeName, renderer); } //##Documentation //## @brief Extra convenience access method for accessing the name of an object (instance of //## StringProperty with property-key "name"). //## //## This method does not take the renderer specific //## propertylists into account, because the name of an object should never be renderer specific. //## @returns a std::string with the name of the object (content of "name" Property). //## If there is no "name" Property, an empty string will be returned. virtual std::string GetName() const { mitk::StringProperty* sp = dynamic_cast(this->GetProperty("name")); if (sp == NULL) return ""; return sp->GetValue(); } //##Documentation //## @brief Extra convenience access method to set the name of an object. //## //## The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". virtual void SetName( const char* name) { if (name == NULL) return; this->SetProperty("name", StringProperty::New(name)); } //##Documentation //## @brief Extra convenience access method to set the name of an object. //## //## The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". virtual void SetName( const std::string name) { this->SetName(name.c_str()); } //##Documentation //## @brief Convenience access method for visibility properties (instances //## of BoolProperty with property-key "visible") //## @return @a true property was found //## @sa IsVisible bool GetVisibility(bool &visible, mitk::BaseRenderer* renderer, const char* propertyKey = "visible") const { return GetBoolProperty(propertyKey, visible, renderer); } //##Documentation //## @brief Convenience access method for opacity properties (instances of //## FloatProperty) //## @return @a true property was found bool GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* propertyKey = "opacity") const; //##Documentation //## @brief Convenience access method for boolean properties (instances //## of BoolProperty). Return value is the value of the property. If the property is //## not found, the value of @a defaultIsOn is returned. //## //## Thus, the return value has a different meaning than in the //## GetBoolProperty method! //## @sa GetBoolProperty bool IsOn(const char* propertyKey, mitk::BaseRenderer* renderer, bool defaultIsOn = true) const { if(propertyKey==NULL) return defaultIsOn; GetBoolProperty(propertyKey, defaultIsOn, renderer); return defaultIsOn; } //##Documentation //## @brief Convenience access method for visibility properties (instances //## of BoolProperty). Return value is the visibility. Default is //## visible==true, i.e., true is returned even if the property (@a //## propertyKey) is not found. //## //## Thus, the return value has a different meaning than in the //## GetVisibility method! //## @sa GetVisibility //## @sa IsOn bool IsVisible(mitk::BaseRenderer* renderer, const char* propertyKey = "visible", bool defaultIsOn = true) const { return IsOn(propertyKey, renderer, defaultIsOn); } //##Documentation //## @brief Convenience method for setting color properties (instances of //## ColorProperty) void SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color"); //##Documentation //## @brief Convenience method for setting color properties (instances of //## ColorProperty) void SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color"); //##Documentation //## @brief Convenience method for setting color properties (instances of //## ColorProperty) void SetColor(const float rgb[3], mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color"); //##Documentation //## @brief Convenience method for setting visibility properties (instances //## of BoolProperty) //## @param visible If set to true, the data will be rendered. If false, the render will skip this data. //## @param renderer Specify a renderer if the visibility shall be specific to a renderer //## @param propertykey Can be used to specify a user defined name of the visibility propery. void SetVisibility(bool visible, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "visible"); //##Documentation //## @brief Convenience method for setting opacity properties (instances of //## FloatProperty) void SetOpacity(float opacity, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "opacity"); //##Documentation //## @brief Convenience method for setting level-window properties //## (instances of LevelWindowProperty) void SetLevelWindow(mitk::LevelWindow levelWindow, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow"); //##Documentation //## @brief Convenience method for setting int properties (instances of //## IntProperty) void SetIntProperty(const char* propertyKey, int intValue, mitk::BaseRenderer* renderer=NULL); //##Documentation //## @brief Convenience method for setting int properties (instances of //## IntProperty) void SetBoolProperty(const char* propertyKey, bool boolValue, mitk::BaseRenderer* renderer=NULL); //##Documentation //## @brief Convenience method for setting int properties (instances of //## IntProperty) void SetFloatProperty(const char* propertyKey, float floatValue, mitk::BaseRenderer* renderer=NULL); //##Documentation //## @brief Convenience method for setting int properties (instances of //## IntProperty) void SetStringProperty(const char* propertyKey, const char* string, mitk::BaseRenderer* renderer=NULL); //##Documentation //## @brief Get the timestamp of the last change of the contents of this node or //## the referenced BaseData. virtual unsigned long GetMTime() const; //##Documentation //## @brief Get the timestamp of the last change of the reference to the //## BaseData. unsigned long GetDataReferenceChangedTime() const { return m_DataReferenceChangedTime.GetMTime(); } //##Documentation //## @brief Adds or removes the associated interactor to mitk::GLobalInteraction. //## virtual void SetInteractorEnabled( const bool& enabled ); //##Documentation //## @brief Adds the interactor to mitk::GlobalInteraction //## virtual void EnableInteractor(); //##Documentation //## @brief Removes the Interactor from mitk::GlobalInteraction //## virtual void DisableInteractor(); //##Documentation //## @brief Tests, if the interactor is already added to mitk::GlobalInteraction //## virtual bool IsInteractorEnabled() const; protected: DataNode(); virtual ~DataNode(); //## //## Invoked when the property list was modified. Calls Modified() of the DataNode virtual void PropertyListModified(const itk::Object *caller, const itk::EventObject &event); //##Documentation //## @brief Mapper-slots mutable MapperVector m_Mappers; //##Documentation //## @brief The data object (instance of BaseData, e.g., an Image) managed //## by this DataNode BaseData::Pointer m_Data; //##Documentation //## @brief BaseRenderer-independent PropertyList //## //## Properties herein can be overwritten specifically for each BaseRenderer //## by the BaseRenderer-specific properties defined in m_MapOfPropertyLists. PropertyList::Pointer m_PropertyList; //##Documentation //## @brief Map associating each BaseRenderer with its own PropertyList mutable MapOfPropertyLists m_MapOfPropertyLists; //##Documentation //## @brief Interactor, that handles the Interaction Interactor::Pointer m_Interactor; // TODO: INTERACTION_LEGACY DataInteractor::Pointer m_DataInteractor; //##Documentation //## @brief Timestamp of the last change of m_Data itk::TimeStamp m_DataReferenceChangedTime; unsigned long m_PropertyListModifiedObserverTag; }; #if (_MSC_VER > 1200) || !defined(_MSC_VER) MITK_CORE_EXPORT MBI_STD::istream& operator>>( MBI_STD::istream& i, DataNode::Pointer& dtn ); MITK_CORE_EXPORT MBI_STD::ostream& operator<<( MBI_STD::ostream& o, DataNode::Pointer& dtn); #endif } // namespace mitk #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) MITK_CORE_EXPORT MBI_STD::istream& operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn ); MITK_CORE_EXPORT MBI_STD::ostream& operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn); #endif #endif /* DATATREENODE_H_HEADER_INCLUDED_C1E14338 */ diff --git a/Core/Code/DataManagement/mitkPlaneGeometry.h b/Core/Code/DataManagement/mitkPlaneGeometry.h index 3a3fcd9bea..ed8fd8d6e7 100644 --- a/Core/Code/DataManagement/mitkPlaneGeometry.h +++ b/Core/Code/DataManagement/mitkPlaneGeometry.h @@ -1,435 +1,428 @@ /*=================================================================== 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 PLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C #define PLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C #include #include "mitkGeometry2D.h" #include "mitkRestorePlanePositionOperation.h" #include namespace mitk { template < class TCoordRep, unsigned int NPointDimension > class Line; typedef Line Line3D; /** * \brief Describes a two-dimensional, rectangular plane * * \ingroup Geometry */ class MITK_CORE_EXPORT PlaneGeometry : public Geometry2D { public: mitkClassMacro(PlaneGeometry,Geometry2D); /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) enum PlaneOrientation { -#ifdef _MSC_VER - Transversal, // deprecated -#endif - Axial = 0, + Axial, Sagittal, Frontal }; -#ifdef __GNUC__ - __attribute__ ((deprecated)) static const PlaneOrientation Transversal = PlaneOrientation(Axial); -#endif - virtual void IndexToWorld(const Point2D &pt_units, Point2D &pt_mm) const; virtual void WorldToIndex(const Point2D &pt_mm, Point2D &pt_units) const; //##Documentation //## @brief Convert (continuous or discrete) index coordinates of a \em vector //## \a vec_units to world coordinates (in mm) //## @deprecated First parameter (Point2D) is not used. If possible, please use void IndexToWorld(const mitk::Vector2D& vec_units, mitk::Vector2D& vec_mm) const. //## For further information about coordinates types, please see the Geometry documentation virtual void IndexToWorld(const mitk::Point2D &atPt2d_untis, const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const; //##Documentation //## @brief Convert (continuous or discrete) index coordinates of a \em vector //## \a vec_units to world coordinates (in mm) //## For further information about coordinates types, please see the Geometry documentation virtual void IndexToWorld(const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const; //##Documentation //## @brief Convert world coordinates (in mm) of a \em vector //## \a vec_mm to (continuous!) index coordinates. //## @deprecated First parameter (Point2D) is not used. If possible, please use void WorldToIndex(const mitk::Vector2D& vec_mm, mitk::Vector2D& vec_units) const. //## For further information about coordinates types, please see the Geometry documentation virtual void WorldToIndex(const mitk::Point2D &atPt2d_mm, const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const; //##Documentation //## @brief Convert world coordinates (in mm) of a \em vector //## \a vec_mm to (continuous!) index coordinates. //## For further information about coordinates types, please see the Geometry documentation virtual void WorldToIndex(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const; virtual void Initialize(); /** * \brief Initialize a plane with orientation \a planeorientation * (default: axial) with respect to \a geometry3D (default: identity). * Spacing also taken from \a geometry3D. * * \warning A former version of this method created a geometry with unit * spacing. For unit spacing use * * \code * // for in-plane unit spacing: * thisgeometry->SetSizeInUnits(thisgeometry->GetExtentInMM(0), * thisgeometry->GetExtentInMM(1)); * // additionally, for unit spacing in normal direction (former version * // did not do this): * thisgeometry->SetExtentInMM(2, 1.0); * \endcode */ virtual void InitializeStandardPlane( const Geometry3D* geometry3D, PlaneOrientation planeorientation = Axial, ScalarType zPosition = 0, bool frontside=true, bool rotated=false ); /** * \brief Initialize a plane with orientation \a planeorientation * (default: axial) with respect to \a geometry3D (default: identity). * Spacing also taken from \a geometry3D. * * \param top if \a true, create plane at top, otherwise at bottom * (for PlaneOrientation Axial, for other plane locations respectively) */ virtual void InitializeStandardPlane( const Geometry3D* geometry3D, bool top, PlaneOrientation planeorientation = Axial, bool frontside=true, bool rotated=false ); /** * \brief Initialize a plane with orientation \a planeorientation * (default: axial) with respect to \a transform (default: identity) * given width and height in units. * */ virtual void InitializeStandardPlane( ScalarType width, ScalarType height, const AffineTransform3D* transform = NULL, PlaneOrientation planeorientation = Axial, ScalarType zPosition = 0, bool frontside=true, bool rotated=false ); /** * \brief Initialize plane with orientation \a planeorientation * (default: axial) given width, height and spacing. * */ virtual void InitializeStandardPlane( ScalarType width, ScalarType height, const Vector3D & spacing, PlaneOrientation planeorientation = Axial, ScalarType zPosition = 0, bool frontside = true, bool rotated = false ); /** * \brief Initialize plane by width and height in pixels, right-/down-vector * (itk) to describe orientation in world-space (vectors will be normalized) * and spacing (default: 1.0 mm in all directions). * * The vectors are normalized and multiplied by the respective spacing before * they are set in the matrix. */ virtual void InitializeStandardPlane( ScalarType width, ScalarType height, const Vector3D& rightVector, const Vector3D& downVector, const Vector3D *spacing = NULL ); /** * \brief Initialize plane by width and height in pixels, * right-/down-vector (vnl) to describe orientation in world-space (vectors * will be normalized) and spacing (default: 1.0 mm in all directions). * * The vectors are normalized and multiplied by the respective spacing * before they are set in the matrix. */ virtual void InitializeStandardPlane( ScalarType width, ScalarType height, const VnlVector& rightVector, const VnlVector& downVector, const Vector3D * spacing = NULL ); /** * \brief Initialize plane by right-/down-vector (itk) and spacing * (default: 1.0 mm in all directions). * * The length of the right-/-down-vector is used as width/height in units, * respectively. Then, the vectors are normalized and multiplied by the * respective spacing before they are set in the matrix. */ virtual void InitializeStandardPlane( const Vector3D& rightVector, const Vector3D& downVector, const Vector3D * spacing = NULL ); /** * \brief Initialize plane by right-/down-vector (vnl) and spacing * (default: 1.0 mm in all directions). * * The length of the right-/-down-vector is used as width/height in units, * respectively. Then, the vectors are normalized and multiplied by the * respective spacing before they are set in the matrix. */ virtual void InitializeStandardPlane( const VnlVector& rightVector, const VnlVector& downVector, const Vector3D * spacing = NULL ); /** * \brief Initialize plane by origin and normal (size is 1.0 mm in * all directions, direction of right-/down-vector valid but * undefined). * */ virtual void InitializePlane( const Point3D& origin, const Vector3D& normal); /** * \brief Initialize plane by right-/down-vector. * * \warning The vectors are set into the matrix as they are, * \em without normalization! */ void SetMatrixByVectors( const VnlVector& rightVector, const VnlVector& downVector, ScalarType thickness=1.0 ); /** * \brief Change \a transform so that the third column of the * transform-martix is perpendicular to the first two columns * */ static void EnsurePerpendicularNormal( AffineTransform3D* transform ); /** * \brief Normal of the plane * */ Vector3D GetNormal() const; /** * \brief Normal of the plane as VnlVector * */ VnlVector GetNormalVnl() const; virtual ScalarType SignedDistance( const Point3D& pt3d_mm ) const; virtual bool IsAbove( const Point3D& pt3d_mm ) const; /** * \brief Distance of the point from the plane * (bounding-box \em not considered) * */ ScalarType DistanceFromPlane( const Point3D& pt3d_mm ) const ; /** * \brief Signed distance of the point from the plane * (bounding-box \em not considered) * * > 0 : point is in the direction of the direction vector. */ inline ScalarType SignedDistanceFromPlane( const Point3D& pt3d_mm ) const { ScalarType len = GetNormalVnl().two_norm(); if( len == 0 ) return 0; return (pt3d_mm-GetOrigin())*GetNormal() / len; } /** * \brief Distance of the plane from another plane * (bounding-box \em not considered) * * Result is 0 if planes are not parallel. */ ScalarType DistanceFromPlane(const PlaneGeometry* plane) const { return fabs(SignedDistanceFromPlane(plane)); } /** * \brief Signed distance of the plane from another plane * (bounding-box \em not considered) * * Result is 0 if planes are not parallel. */ inline ScalarType SignedDistanceFromPlane( const PlaneGeometry *plane ) const { if(IsParallel(plane)) { return SignedDistance(plane->GetOrigin()); } return 0; } /** * \brief Calculate the intersecting line of two planes * * \return \a true planes are intersecting * \return \a false planes do not intersect */ bool IntersectionLine( const PlaneGeometry *plane, Line3D &crossline ) const; /** * \brief Calculate two points where another plane intersects the border of this plane * * \return number of intersection points (0..2). First interection point (if existing) * is returned in \a lineFrom, second in \a lineTo. */ unsigned int IntersectWithPlane2D(const PlaneGeometry *plane, Point2D &lineFrom, Point2D &lineTo ) const ; /** * \brief Calculate the angle between two planes * * \return angle in radiants */ double Angle( const PlaneGeometry *plane ) const; /** * \brief Calculate the angle between the plane and a line * * \return angle in radiants */ double Angle( const Line3D &line ) const; /** * \brief Calculate intersection point between the plane and a line * * \param intersectionPoint intersection point * \return \a true if \em unique intersection exists, i.e., if line * is \em not on or parallel to the plane */ bool IntersectionPoint( const Line3D &line, Point3D &intersectionPoint ) const; /** * \brief Calculate line parameter of intersection point between the * plane and a line * * \param t parameter of line: intersection point is * line.GetPoint()+t*line.GetDirection() * \return \a true if \em unique intersection exists, i.e., if line * is \em not on or parallel to the plane */ bool IntersectionPointParam( const Line3D &line, double &t ) const; /** * \brief Returns whether the plane is parallel to another plane * * @return true iff the normal vectors both point to the same or exactly oposit direction */ bool IsParallel( const PlaneGeometry *plane ) const; /** * \brief Returns whether the point is on the plane * (bounding-box \em not considered) */ bool IsOnPlane( const Point3D &point ) const; /** * \brief Returns whether the line is on the plane * (bounding-box \em not considered) */ bool IsOnPlane( const Line3D &line ) const; /** * \brief Returns whether the plane is on the plane * (bounding-box \em not considered) * * @return true iff the normal vector of the planes point to the same or the exactly oposit direction and * the distance of the planes is < eps * */ bool IsOnPlane( const PlaneGeometry *plane ) const; /** * \brief Returns the lot from the point to the plane */ Point3D ProjectPointOntoPlane( const Point3D &pt ) const; virtual void SetIndexToWorldTransform( AffineTransform3D *transform); virtual void SetBounds( const BoundingBox::BoundsArrayType &bounds ); virtual itk::LightObject::Pointer InternalClone() const; /** Implements operation to re-orient the plane */ virtual void ExecuteOperation( Operation *operation ); protected: PlaneGeometry(); virtual ~PlaneGeometry(); virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const; private: /** * \brief Compares plane with another plane: \a true if IsOnPlane * (bounding-box \em not considered) */ virtual bool operator==( const PlaneGeometry * ) const { return false; }; /** * \brief Compares plane with another plane: \a false if IsOnPlane * (bounding-box \em not considered) */ virtual bool operator!=( const PlaneGeometry * ) const { return false; }; }; } // namespace mitk #endif /* PLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C */ diff --git a/Modules/QtWidgets/QmitkRenderWindowMenu.h b/Modules/QtWidgets/QmitkRenderWindowMenu.h index 838a05f6dc..8b55966a57 100644 --- a/Modules/QtWidgets/QmitkRenderWindowMenu.h +++ b/Modules/QtWidgets/QmitkRenderWindowMenu.h @@ -1,342 +1,328 @@ /*=================================================================== 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 QmitkRenderWindowMenu_h #define QmitkRenderWindowMenu_h #if defined(_WIN32) || defined(__APPLE__) #define QMITK_USE_EXTERNAL_RENDERWINDOW_MENU #endif #include #include "mitkBaseRenderer.h" #include #include #include #include #include #include #include class QmitkStdMultiWidget; /** * \ingroup QmitkModule * \brief The QmitkRenderWindowMenu is a popup Widget which shows * up when the mouse curser enter a QmitkRenderWindow. * The Menu Widget is located in the right top corner of each * RenderWindow. It includes different settings. For example * the layout design can be changed with the setting button. Switching * between full-screen mode and layout design can be done * with the full-screen button. Splitting the Widget horizontal or * vertical as well closing the Widget is not implemented yet. * The popup Widget can be deactivated with ActivateMenuWidget(false) in * QmitkRenderWindow. * * \sa QmitkRenderWindow * \sa QmitkStdMultiWidget * */ class QMITK_EXPORT QmitkRenderWindowMenu : public QWidget { Q_OBJECT public: QmitkRenderWindowMenu( QWidget* parent = 0, Qt::WFlags f = 0, mitk::BaseRenderer * b = 0, QmitkStdMultiWidget* mw = 0 ); virtual ~QmitkRenderWindowMenu(); /*! Return visibility of settings menu. The menu is connected with m_SettingsButton and includes layout direction (axial, coronal .. ) and layout design (standard layout, 2D images top, 3D bottom ... ). */ bool GetSettingsMenuVisibilty() { if( m_Settings == NULL) return false; else return m_Settings->isVisible(); } /*! Set layout index. Defines layout direction (axial, coronal, sagital or threeD) of the parent. */ void SetLayoutIndex( unsigned int layoutIndex ); /*! Return layout direction of parent (axial, coronal, sagital or threeD) */ unsigned int GetLayoutIndex() { return m_Layout; } /*! Update list of layout design (standard layout, 2D images top, 3D bottom ..). Set action of current layout design to disable and all other to enable. */ void UpdateLayoutDesignList( int layoutDesignIndex ); /*! Move menu widget to correct position (right upper corner). E.g. it is necessary when the full-screen mode is activated.*/ #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU void MoveWidgetToCorrectPos(float opacity); #else void MoveWidgetToCorrectPos(float /*opacity*/); #endif void ChangeFullScreenMode( bool state ); void NotifyNewWidgetPlanesMode( int mode ); protected: /*! Create menu widget. The menu contains five QPushButtons (hori-split, verti-split, full-screen, settings and close button) and their signal/slot connection for handling. */ void CreateMenuWidget(); /*! Create settings menu which contains layout direction and the different layout designs. */ void CreateSettingsWidget(); /*! Reimplemented from QWidget. The paint event is a request to repaint all or part of a widget.*/ void paintEvent(QPaintEvent *event); /*! Update list of layout direction (axial, coronal, sagital or threeD). Set action of currect layout direction to disable and all other to enable. Normaly the user can switch here between the different layout direction, but this is not supported yet. */ void UpdateLayoutList(); /*! Change Icon of full-screen button depending on full-screen mode. */ void ChangeFullScreenIcon(); int currentCrosshairRotationMode; public slots: void SetCrossHairVisibility( bool state ) ; signals: void ResetView(); // == "global reinit" // \brief int parameters are enum from QmitkStdMultiWidget void ChangeCrosshairRotationMode(int); /*! emit signal, when layout design changed by the setting menu.*/ void SignalChangeLayoutDesign( int layoutDesign ); public slots: void DeferredHideMenu( ); void DeferredShowMenu( ); void smoothHide( ); protected slots: /// /// this function is continously called by a timer /// to do the auto rotation /// void AutoRotateNextStep(); /// /// this function is invoked when the auto-rotate action /// is clicked /// void OnAutoRotationActionTriggered(); void enterEvent( QEvent* /*e*/ ); void leaveEvent( QEvent* /*e*/ ); void OnTSNumChanged(int); void OnCrosshairRotationModeSelected(QAction*); /*! slot for activating/deactivating the full-screen mode. The slot is connected to the clicked() event of m_FullScreenButton. Activating the full-screen maximize the current widget, deactivating restore If layout design changed by the settings menu, the full-Screen mode is automatically switch to false. */ void OnFullScreenButton( bool checked ); /*! Slot for opening setting menu. The slot is connected to the clicked() event of m_SettingsButton. The settings menu includes differen layout directions (axial, coronal, saggital and 3D) as well all layout design (standard layout, 2D images top, 3D bottom ..)*/ void OnSettingsButton( bool checked ); /*! Slot for changing layout design to standard layout. The slot is connected to the triggered() signal of m_DefaultLayoutAction. */ void OnChangeLayoutToDefault(bool); /*! Slot for changing layout design to 2D images top, 3D bottom layout. The slot is connected to the triggered() signal of m_2DImagesUpLayoutAction. */ void OnChangeLayoutTo2DImagesUp(bool); /*! Slot for changing layout design to 2D images left, 3D right layout. The slot is connected to the triggered() signal of m_2DImagesLeftLayoutAction. */ void OnChangeLayoutTo2DImagesLeft(bool); /*! Slot for changing layout to Big 3D layout. The slot is connected to the triggered() signal of m_Big3DLayoutAction. */ void OnChangeLayoutToBig3D(bool); /*! Slot for changing layout design to Axial plane layout. The slot is connected to the triggered() signal of m_Widget1LayoutAction. */ void OnChangeLayoutToWidget1(bool); /*! Slot for changing layout design to Sagittal plane layout. The slot is connected to the triggered() signal of m_Widget2LayoutAction. */ void OnChangeLayoutToWidget2(bool); /*! Slot for changing layout design to Coronal plane layout. The slot is connected to the triggered() signal of m_Widget3LayoutAction. */ void OnChangeLayoutToWidget3(bool); /*! Slot for changing layout design to Coronal top, 3D bottom layout. The slot is connected to the triggered() signal of m_RowWidget3And4LayoutAction. */ void OnChangeLayoutToRowWidget3And4(bool); /*! Slot for changing layout design to Coronal left, 3D right layout. The slot is connected to the triggered() signal of m_ColumnWidget3And4LayoutAction. */ void OnChangeLayoutToColumnWidget3And4(bool); /*! Slot for changing layout design to Sagittal top, Coronal n 3D bottom layout. The slot is connected to the triggered() signal of m_SmallUpperWidget2Big3and4LayoutAction. */ void OnChangeLayoutToSmallUpperWidget2Big3and4(bool); /*! Slot for changing layout design to Axial n Sagittal left, 3D right layout. The slot is connected to the triggered() signal of m_2x2Dand3DWidgetLayoutAction. */ void OnChangeLayoutTo2x2Dand3DWidget(bool); /*! Slot for changing layout design to Axial n 3D left, Sagittal right layout. The slot is connected to the triggered() signal of m_Left2Dand3DRight2DLayoutAction. */ void OnChangeLayoutToLeft2Dand3DRight2D(bool); void OnCrossHairMenuAboutToShow(); public: /*! enum for layout direction*/ enum { -#ifdef _MSC_VER - TRANSVERSAL, // deprecated -#endif - AXIAL = 0, + AXIAL, SAGITTAL, CORONAL, THREE_D }; -#ifdef __GNUC__ - __attribute__ ((deprecated)) static const int TRANSVERSAL = AXIAL; -#endif - /*! enum for layout design */ enum { LAYOUT_DEFAULT, LAYOUT_2DIMAGEUP, LAYOUT_2DIMAGELEFT, LAYOUT_BIG3D, -#ifdef _MSC_VER - LAYOUT_TRANSVERSAL, // deprecated -#endif - LAYOUT_AXIAL = LAYOUT_BIG3D + 1, + LAYOUT_AXIAL, LAYOUT_SAGITTAL, LAYOUT_CORONAL, LAYOUT_2X2DAND3DWIDGET, LAYOUT_ROWWIDGET3AND4, LAYOUT_COLUMNWIDGET3AND4, LAYOUT_ROWWIDGETSMALL3ANDBIG4, //not in use in this class, but we need it here to synchronize with the SdtMultiWidget. LAYOUT_SMALLUPPERWIDGET2BIGAND4, LAYOUT_LEFT2DAND3DRIGHT2D }; -#ifdef __GNUC__ - __attribute__ ((deprecated)) static const int LAYOUT_TRANSVERSAL = LAYOUT_AXIAL; -#endif - void ShowMenu(); void HideMenu(); protected: QPushButton* m_CrosshairModeButton; //QAction* m_ShowHideCrosshairVisibilityAction; /*! QPushButton for activating/deactivating full-screen mode*/ QPushButton* m_FullScreenButton; /*! QPushButton for open the settings menu*/ QPushButton* m_SettingsButton; /*! QAction for Default layout design */ QAction* m_DefaultLayoutAction; /*! QAction for 2D images up layout design */ QAction* m_2DImagesUpLayoutAction; /*! QAction for 2D images left layout design */ QAction* m_2DImagesLeftLayoutAction; /*! QAction for big 3D layout design */ QAction* m_Big3DLayoutAction; /*! QAction for big axial layout design */ QAction* m_Widget1LayoutAction; /*! QAction for big saggital layout design */ QAction* m_Widget2LayoutAction; /*! QAction for big coronal layout design */ QAction* m_Widget3LayoutAction; /*! QAction for coronal top, 3D bottom layout design */ QAction* m_RowWidget3And4LayoutAction; /*! QAction for coronal left, 3D right layout design */ QAction* m_ColumnWidget3And4LayoutAction; /*! QAction for sagittal top, coronal n 3D bottom layout design */ QAction* m_SmallUpperWidget2Big3and4LayoutAction; /*! QAction for axial n sagittal left, 3D right layout design */ QAction* m_2x2Dand3DWidgetLayoutAction; /*! QAction for axial n 3D left, sagittal right layout design*/ QAction* m_Left2Dand3DRight2DLayoutAction; QLabel *m_TSLabel; /*! QMenu containg all layout direction and layout design settings.*/ QMenu* m_Settings; QMenu* m_CrosshairMenu; /*! Index of layout direction. 0: axial; 1: saggital; 2: coronal; 3: threeD */ unsigned int m_Layout; /*! Index of layout design. 0: LAYOUT_DEFAULT; 1: LAYOUT_2DIMAGEUP; 2: LAYOUT_2DIMAGELEFT; 3: LAYOUT_BIG3D 4: LAYOUT_AXIAL; 5: LAYOUT_SAGITTAL; 6: LAYOUT_CORONAL; 7: LAYOUT_2X2DAND3DWIDGET; 8: LAYOUT_ROWWIDGET3AND4; 9: LAYOUT_COLUMNWIDGET3AND4; 10: LAYOUT_ROWWIDGETSMALL3ANDBIG4; 11: LAYOUT_SMALLUPPERWIDGET2BIGAND4; 12: LAYOUT_LEFT2DAND3DRIGHT2D */ unsigned int m_LayoutDesign; /*! Store index of old layout design. It is used e.g. for the full-screen mode, when deactivating the mode the former layout design will restore.*/ unsigned int m_OldLayoutDesign; /*! Flag if full-screen mode is activated or deactivated. */ bool m_FullScreenMode; bool m_Entered; bool m_Hidden; private: mitk::BaseRenderer::Pointer m_Renderer; QmitkStdMultiWidget* m_MultiWidget; /// /// a timer for the auto rotate action /// QTimer m_AutoRotationTimer; }; #endif // QmitkRenderWindowMenu_H diff --git a/Modules/QtWidgets/QmitkStdMultiWidget.h b/Modules/QtWidgets/QmitkStdMultiWidget.h index f58f5e7db0..678c13028d 100644 --- a/Modules/QtWidgets/QmitkStdMultiWidget.h +++ b/Modules/QtWidgets/QmitkStdMultiWidget.h @@ -1,362 +1,361 @@ /*=================================================================== 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 QMITKSTDMULTIWIDGET_H_ #define QMITKSTDMULTIWIDGET_H_ #include #include "mitkPositionTracker.h" #include "mitkSlicesRotator.h" #include "mitkSlicesSwiveller.h" #include "mitkRenderWindowFrame.h" #include "mitkManufacturerLogo.h" #include "mitkGradientBackground.h" #include "mitkCoordinateSupplier.h" #include "mitkDataStorage.h" #include "mitkMouseModeSwitcher.h" #include #include #include #include #include #include "vtkTextProperty.h" #include "vtkCornerAnnotation.h" class QHBoxLayout; class QVBoxLayout; class QGridLayout; class QSpacerItem; class QmitkLevelWindowWidget; class QmitkRenderWindow; namespace mitk { class RenderingManager; } /// \ingroup QmitkModule class QMITK_EXPORT QmitkStdMultiWidget : public QWidget { Q_OBJECT public: QmitkStdMultiWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, mitk::RenderingManager* renderingManager = 0); virtual ~QmitkStdMultiWidget(); mitk::SliceNavigationController* GetTimeNavigationController(); void RequestUpdate(); void ForceImmediateUpdate(); mitk::MouseModeSwitcher* GetMouseModeSwitcher(); QmitkRenderWindow* GetRenderWindow1() const; QmitkRenderWindow* GetRenderWindow2() const; QmitkRenderWindow* GetRenderWindow3() const; QmitkRenderWindow* GetRenderWindow4() const; const mitk::Point3D & GetLastLeftClickPosition() const; const mitk::Point3D GetCrossPosition() const; void EnablePositionTracking(); void DisablePositionTracking(); int GetLayout() const; mitk::SlicesRotator * GetSlicesRotator() const; mitk::SlicesSwiveller * GetSlicesSwiveller() const; bool GetGradientBackgroundFlag() const; /*! \brief Access node of widget plane 1 \return DataNode holding widget plane 1 */ mitk::DataNode::Pointer GetWidgetPlane1(); /*! \brief Access node of widget plane 2 \return DataNode holding widget plane 2 */ mitk::DataNode::Pointer GetWidgetPlane2(); /*! \brief Access node of widget plane 3 \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane3(); /*! \brief Convenience method to access node of widget planes \param id number of widget plane to be returned \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane(int id); bool IsColoredRectanglesEnabled() const; bool IsDepartmentLogoEnabled() const; bool IsCrosshairNavigationEnabled() const; void InitializeWidget(); /// called when the StdMultiWidget is closed to remove the 3 widget planes and the helper node from the DataStorage void RemovePlanesFromDataStorage(); void AddPlanesToDataStorage(); void SetDataStorage( mitk::DataStorage* ds ); /** \brief Listener to the CrosshairPositionEvent Ensures the CrosshairPositionEvent is handled only once and at the end of the Qt-Event loop */ void HandleCrosshairPositionEvent(); /// activate Menu Widget. true: activated, false: deactivated void ActivateMenuWidget( bool state ); bool IsMenuWidgetEnabled() const; protected: void UpdateAllWidgets(); void HideAllWidgetToolbars(); mitk::DataNode::Pointer GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes); public slots: /// Receives the signal from HandleCrosshairPositionEvent, executes the StatusBar update void HandleCrosshairPositionEventDelayed(); void changeLayoutTo2DImagesUp(); void changeLayoutTo2DImagesLeft(); void changeLayoutToDefault(); void changeLayoutToBig3D(); void changeLayoutToWidget1(); void changeLayoutToWidget2(); void changeLayoutToWidget3(); void changeLayoutToRowWidget3And4(); void changeLayoutToColumnWidget3And4(); void changeLayoutToRowWidgetSmall3andBig4(); void changeLayoutToSmallUpperWidget2Big3and4(); void changeLayoutTo2x2Dand3DWidget(); void changeLayoutToLeft2Dand3DRight2D(); void changeLayoutTo2DUpAnd3DDown(); void Fit(); void InitPositionTracking(); void AddDisplayPlaneSubTree(); void EnableStandardLevelWindow(); void DisableStandardLevelWindow(); bool InitializeStandardViews( const mitk::Geometry3D * geometry ); void wheelEvent( QWheelEvent * e ); void mousePressEvent(QMouseEvent * e); void moveEvent( QMoveEvent* e ); void leaveEvent ( QEvent * e ); void EnsureDisplayContainsPoint( mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p); void MoveCrossToPosition(const mitk::Point3D& newPosition); void EnableNavigationControllerEventListening(); void DisableNavigationControllerEventListening(); void EnableGradientBackground(); void DisableGradientBackground(); void EnableDepartmentLogo(); void DisableDepartmentLogo(); void EnableColoredRectangles(); void DisableColoredRectangles(); void SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer=NULL); void SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer=NULL); void SetWidgetPlanesLocked(bool locked); void SetWidgetPlanesRotationLocked(bool locked); void SetWidgetPlanesRotationLinked( bool link ); void SetWidgetPlaneMode( int mode ); void SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower ); void SetDepartmentLogoPath( const char * path ); void SetWidgetPlaneModeToSlicing( bool activate ); void SetWidgetPlaneModeToRotation( bool activate ); void SetWidgetPlaneModeToSwivel( bool activate ); void OnLayoutDesignChanged( int layoutDesignIndex ); void ResetCrosshair(); void MouseModeSelected( mitk::MouseModeSwitcher::MouseMode mouseMode ); signals: void LeftMouseClicked(mitk::Point3D pointValue); void WheelMoved(QWheelEvent*); void WidgetPlanesRotationLinked(bool); void WidgetPlanesRotationEnabled(bool); void ViewsInitialized(); void WidgetPlaneModeSlicing(bool); void WidgetPlaneModeRotation(bool); void WidgetPlaneModeSwivel(bool); void WidgetPlaneModeChange(int); void WidgetNotifyNewCrossHairMode(int); void Moved(); public: /** Define RenderWindow (public)*/ QmitkRenderWindow* mitkWidget1; QmitkRenderWindow* mitkWidget2; QmitkRenderWindow* mitkWidget3; QmitkRenderWindow* mitkWidget4; QmitkLevelWindowWidget* levelWindowWidget; /********************************/ enum { PLANE_MODE_SLICING = 0, PLANE_MODE_ROTATION, PLANE_MODE_SWIVEL }; enum { LAYOUT_DEFAULT = 0, LAYOUT_2D_IMAGES_UP, LAYOUT_2D_IMAGES_LEFT, LAYOUT_BIG_3D, LAYOUT_WIDGET1, LAYOUT_WIDGET2, LAYOUT_WIDGET3, LAYOUT_2X_2D_AND_3D_WIDGET, LAYOUT_ROW_WIDGET_3_AND_4, LAYOUT_COLUMN_WIDGET_3_AND_4, LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4 , LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4,LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET, LAYOUT_2D_UP_AND_3D_DOWN}; enum { - TRANSVERSAL, - AXIAL = TRANSVERSAL, + AXIAL, SAGITTAL, CORONAL, THREE_D }; protected: QHBoxLayout* QmitkStdMultiWidgetLayout; int m_Layout; int m_PlaneMode; mitk::RenderingManager* m_RenderingManager; mitk::RenderWindowFrame::Pointer m_RectangleRendering3; mitk::RenderWindowFrame::Pointer m_RectangleRendering2; mitk::RenderWindowFrame::Pointer m_RectangleRendering1; mitk::RenderWindowFrame::Pointer m_RectangleRendering4; mitk::ManufacturerLogo::Pointer m_LogoRendering1; mitk::ManufacturerLogo::Pointer m_LogoRendering2; mitk::ManufacturerLogo::Pointer m_LogoRendering3; mitk::ManufacturerLogo::Pointer m_LogoRendering4; mitk::GradientBackground::Pointer m_GradientBackground1; mitk::GradientBackground::Pointer m_GradientBackground2; mitk::GradientBackground::Pointer m_GradientBackground4; mitk::GradientBackground::Pointer m_GradientBackground3; bool m_GradientBackgroundFlag; mitk::MouseModeSwitcher::Pointer m_MouseModeSwitcher; mitk::CoordinateSupplier::Pointer m_LastLeftClickPositionSupplier; mitk::PositionTracker::Pointer m_PositionTracker; mitk::SliceNavigationController* m_TimeNavigationController; mitk::SlicesRotator::Pointer m_SlicesRotator; mitk::SlicesSwiveller::Pointer m_SlicesSwiveller; mitk::DataNode::Pointer m_PositionTrackerNode; mitk::DataStorage::Pointer m_DataStorage; mitk::DataNode::Pointer m_PlaneNode1; mitk::DataNode::Pointer m_PlaneNode2; mitk::DataNode::Pointer m_PlaneNode3; mitk::DataNode::Pointer m_Node; QSplitter *m_MainSplit; QSplitter *m_LayoutSplit; QSplitter *m_SubSplit1; QSplitter *m_SubSplit2; QWidget *mitkWidget1Container; QWidget *mitkWidget2Container; QWidget *mitkWidget3Container; QWidget *mitkWidget4Container; struct { vtkCornerAnnotation *cornerText; vtkTextProperty *textProp; vtkRenderer *ren; } m_CornerAnnotaions[3]; bool m_PendingCrosshairPositionEvent; bool m_CrosshairNavigationEnabled; }; #endif /*QMITKSTDMULTIWIDGET_H_*/ diff --git a/Modules/SceneSerialization/mitkSceneReaderV1.cpp b/Modules/SceneSerialization/mitkSceneReaderV1.cpp index 18ad2a1f7f..252294eaa6 100644 --- a/Modules/SceneSerialization/mitkSceneReaderV1.cpp +++ b/Modules/SceneSerialization/mitkSceneReaderV1.cpp @@ -1,391 +1,382 @@ /*=================================================================== 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 "mitkSceneReaderV1.h" #include "mitkSerializerMacros.h" #include "mitkDataNodeFactory.h" #include "mitkBaseRenderer.h" #include "mitkPropertyListDeserializer.h" #include "mitkProgressBar.h" #include "Poco/Path.h" #include MITK_REGISTER_SERIALIZER(SceneReaderV1) bool mitk::SceneReaderV1::LoadScene( TiXmlDocument& document, const std::string& workingDirectory, DataStorage* storage ) { assert(storage); bool error(false); // TODO prepare to detect errors (such as cycles) from wrongly written or edited xml files //Get number of elements to initialze progress bar // 1. if there is a element, // - construct a name for the appropriate serializer // - try to instantiate this serializer via itk object factory // - if serializer could be created, use it to read the file into a BaseData object // - if successful, call the new node's SetData(..) // create a node for the tag "data" and test if node was created typedef std::vector DataNodeVector; DataNodeVector DataNodes; unsigned int listSize = 0; for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL; element = element->NextSiblingElement("node") ) { ++listSize; DataNodes.push_back( LoadBaseDataFromDataTag( element->FirstChildElement("data"), workingDirectory, error ) ); } OrderedLayers orderedLayers; this->GetLayerOrder(document, workingDirectory, DataNodes, orderedLayers); ProgressBar::GetInstance()->AddStepsToDo( listSize ); // iterate all nodes // first level nodes should be elements DataNodeVector::iterator nit = DataNodes.begin(); for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL || nit != DataNodes.end(); element = element->NextSiblingElement("node"), ++nit ) { mitk::DataNode::Pointer node = *nit; // in case dataXmlElement is valid test whether it containts the "properties" child tag // and process further if and only if yes TiXmlElement *dataXmlElement = element->FirstChildElement("data"); if( dataXmlElement && dataXmlElement->FirstChildElement("properties") ) { TiXmlElement *baseDataElement = dataXmlElement->FirstChildElement("properties"); if ( node->GetData() ) { DecorateBaseDataWithProperties( node->GetData(), baseDataElement, workingDirectory); } else { MITK_WARN << "BaseData properties stored in scene file, but BaseData can't be read" << std::endl; } } // 2. check child nodes const char* uida = element->Attribute("UID"); std::string uid(""); if (uida) { uid = uida; m_NodeForID[uid] = node.GetPointer(); m_IDForNode[ node.GetPointer() ] = uid; } else { MITK_ERROR << "No UID found for current node. Node will have no parents."; error = true; } // 3. if there are nodes, // - instantiate the appropriate PropertyListDeSerializer // - use them to construct PropertyList objects // - add these properties to the node (if necessary, use renderwindow name) bool success = DecorateNodeWithProperties(node, element, workingDirectory); if (!success) { MITK_ERROR << "Could not load properties for node."; error = true; } // remember node for later adding to DataStorage //node->GetIntProperty("layer", layer); int layer; OrderedLayers::iterator it = orderedLayers.find(uid); layer = (*it).second; m_OrderedNodePairs.insert( std::make_pair( layer, std::make_pair( node, std::list() ) ) ); // 4. if there are elements, remember parent objects for( TiXmlElement* source = element->FirstChildElement("source"); source != NULL; source = source->NextSiblingElement("source") ) { const char* sourceUID = source->Attribute("UID"); if (sourceUID) { m_OrderedNodePairs[layer].second.push_back( std::string(sourceUID) ); } } ProgressBar::GetInstance()->Progress(); } // end for all // remove all unknown parent UIDs for (LayerPropertyMapType::iterator nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { for (std::list::iterator parentsIter = nodesIter->second.second.begin(); parentsIter != nodesIter->second.second.end();) { if (m_NodeForID.find( *parentsIter ) == m_NodeForID.end()) { parentsIter = nodesIter->second.second.erase( parentsIter ); MITK_WARN << "Found a DataNode with unknown parents. Will add it to DataStorage without any parent objects."; error = true; } else { ++parentsIter; } } } // repeat // for all created nodes unsigned int lastMapSize(0); while ( lastMapSize != m_OrderedNodePairs.size()) // this is to prevent infinite loops; each iteration must at least add one node to DataStorage { lastMapSize = m_OrderedNodePairs.size(); for (LayerPropertyMapType::iterator nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { bool addNow(true); // if any parent node is not yet in DataStorage, skip node for now and check later for (std::list::iterator parentsIter = nodesIter->second.second.begin(); parentsIter != nodesIter->second.second.end(); ++parentsIter) { if ( !storage->Exists( m_NodeForID[ *parentsIter ] ) ) { addNow = false; break; } } if (addNow) { DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New(); for (std::list::iterator parentsIter = nodesIter->second.second.begin(); parentsIter != nodesIter->second.second.end(); ++parentsIter) { parents->push_back( m_NodeForID[ *parentsIter ] ); } // if all parents are found in datastorage (or are unknown), add node to DataStorage storage->Add( nodesIter->second.first, parents ); // remove this node from m_OrderedNodePairs m_OrderedNodePairs.erase( nodesIter ); // break this for loop because iterators are probably invalid break; } } } // All nodes that are still in m_OrderedNodePairs at this point are not part of a proper directed graph structure. We'll add such nodes without any parent information. for (LayerPropertyMapType::iterator nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { storage->Add( nodesIter->second.first ); MITK_WARN << "Encountered node that is not part of a directed graph structure. Will be added to DataStorage without parents."; error = true; } return !error; } void mitk::SceneReaderV1::GetLayerOrder(TiXmlDocument& document, const std::string& workingDirectory, std::vector DataNodes, OrderedLayers& order) { typedef std::vector DataNodeVector; DataNodeVector::iterator nit = DataNodes.begin(); for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL || nit != DataNodes.end(); element = element->NextSiblingElement("node"), ++nit ) { DataNode::Pointer node = *nit; DecorateNodeWithProperties(node, element, workingDirectory); int layer; node->GetIntProperty("layer", layer); std::string uid = element->Attribute("UID"); this->m_UnorderedLayers.insert( std::make_pair( layer, uid ) ); } int lastLayer = itk::NumericTraits::min(); UnorderedLayers::iterator it; for (it = m_UnorderedLayers.begin(); it != m_UnorderedLayers.end(); it++) { int currentLayer = (*it).first; if (currentLayer == lastLayer) { ++currentLayer; } order.insert( std::make_pair( (*it).second, currentLayer ) ); lastLayer = currentLayer; } } mitk::DataNode::Pointer mitk::SceneReaderV1::LoadBaseDataFromDataTag( TiXmlElement* dataElement, const std::string& workingDirectory, bool& error ) { DataNode::Pointer node; if (dataElement) { const char* filename( dataElement->Attribute("file") ); if ( filename ) { DataNodeFactory::Pointer factory = DataNodeFactory::New(); factory->SetFileName( workingDirectory + Poco::Path::separator() + filename ); try { factory->Update(); node = factory->GetOutput(); } catch (std::exception& e) { MITK_ERROR << "Error during attempt to read '" << filename << "'. Exception says: " << e.what(); error = true; } if (node.IsNull()) { MITK_ERROR << "Error during attempt to read '" << filename << "'. Factory returned NULL object."; error = true; } } } // in case there was no element we create a new empty node (for appending a propertylist later) if (node.IsNull()) { node = DataNode::New(); } return node; } bool mitk::SceneReaderV1::DecorateNodeWithProperties(DataNode* node, TiXmlElement* nodeElement, const std::string& workingDirectory) { assert(node); assert(nodeElement); bool error(false); for( TiXmlElement* properties = nodeElement->FirstChildElement("properties"); properties != NULL; properties = properties->NextSiblingElement("properties") ) { const char* propertiesfilea( properties->Attribute("file") ); std::string propertiesfile( propertiesfilea ? propertiesfilea : "" ); const char* renderwindowa( properties->Attribute("renderwindow") ); std::string renderwindow( renderwindowa ? renderwindowa : "" ); - BaseRenderer* renderer = BaseRenderer::GetByName( renderwindow ); - if (renderer || renderwindow.empty()) - { - PropertyList::Pointer propertyList = node->GetPropertyList(renderer); // DataNode implementation always returns a propertylist - // clear all properties from node that might be set by DataNodeFactory during loading - propertyList->Clear(); + PropertyList::Pointer propertyList = node->GetPropertyList(renderwindow); // DataNode implementation always returns a propertylist + // clear all properties from node that might be set by DataNodeFactory during loading + propertyList->Clear(); - // use deserializer to construct new properties - PropertyListDeserializer::Pointer deserializer = PropertyListDeserializer::New(); + // use deserializer to construct new properties + PropertyListDeserializer::Pointer deserializer = PropertyListDeserializer::New(); - deserializer->SetFilename(workingDirectory + Poco::Path::separator() + propertiesfile); - bool success = deserializer->Deserialize(); - error |= !success; - PropertyList::Pointer readProperties = deserializer->GetOutput(); + deserializer->SetFilename(workingDirectory + Poco::Path::separator() + propertiesfile); + bool success = deserializer->Deserialize(); + error |= !success; + PropertyList::Pointer readProperties = deserializer->GetOutput(); - if (readProperties.IsNotNull()) + if (readProperties.IsNotNull()) + { + //'use color' is deprecated since 2013.03 release. It was replaced by + //'Image Rendering.Mode' in bug #12056. This code is for legacy support + //of old scene files containing the property 'use color'. The code should + //be removed in one of the upcomng releases. + if(readProperties->GetProperty("Image Rendering.Mode") == NULL ) { - //'use color' is deprecated since 2013.03 release. It was replaced by - //'Image Rendering.Mode' in bug #12056. This code is for legacy support - //of old scene files containing the property 'use color'. The code should - //be removed in one of the upcomng releases. - if(readProperties->GetProperty("Image Rendering.Mode") == NULL ) + mitk::BaseProperty* useColorProperty = readProperties->GetProperty("use color"); + if(mitk::BoolProperty* boolProp = dynamic_cast(useColorProperty)) { - mitk::BaseProperty* useColorProperty = readProperties->GetProperty("use color"); - if(mitk::BoolProperty* boolProp = dynamic_cast(useColorProperty)) - { - bool useColor = boolProp->GetValue(); - readProperties->DeleteProperty("use color"); - mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); - if(useColor) - renderingMode->SetValue( mitk::RenderingModeProperty::LEVELWINDOW_COLOR ); - else - renderingMode->SetValue( mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR ); - readProperties->SetProperty("Image Rendering.Mode", renderingMode); - MITK_WARN << "The property 'use color' has been found in a scene file and was replaced by 'Image Rendering.Mode'. 'use color' is deprecated since 2013.03 release."; - } - + bool useColor = boolProp->GetValue(); + readProperties->DeleteProperty("use color"); + mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); + if(useColor) + renderingMode->SetValue( mitk::RenderingModeProperty::LEVELWINDOW_COLOR ); + else + renderingMode->SetValue( mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR ); + readProperties->SetProperty("Image Rendering.Mode", renderingMode); + MITK_WARN << "The property 'use color' has been found in a scene file and was replaced by 'Image Rendering.Mode'. 'use color' is deprecated since 2013.03 release."; } - propertyList->ConcatenatePropertyList( readProperties, true ); // true = replace - } - else - { - MITK_ERROR << "Property list reader did not return a property list. This is an implementation error. Please tell your developer."; - error = true; + } + propertyList->ConcatenatePropertyList( readProperties, true ); // true = replace } else { - MITK_ERROR << "Found properties for renderer " << renderwindow << " but there is no such renderer in current application. Ignoring those properties"; + MITK_ERROR << "Property list reader did not return a property list. This is an implementation error. Please tell your developer."; error = true; } } return !error; } bool mitk::SceneReaderV1::DecorateBaseDataWithProperties(BaseData::Pointer data, TiXmlElement *baseDataNodeElem, const std::string &workingDir) { // check given variables, initialize error variable assert(baseDataNodeElem); bool error(false); // get the file name stored in the tag const char* baseDataPropertyFile( baseDataNodeElem->Attribute("file") ); // check if the filename was found if(baseDataPropertyFile) { //PropertyList::Pointer dataPropList = data->GetPropertyList(); PropertyListDeserializer::Pointer propertyDeserializer = PropertyListDeserializer::New(); // initialize the property reader propertyDeserializer->SetFilename(workingDir + Poco::Path::separator() + baseDataPropertyFile); bool ioSuccess = propertyDeserializer->Deserialize(); error = !ioSuccess; // get the output PropertyList::Pointer inProperties = propertyDeserializer->GetOutput(); // store the read-in properties to the given node or throw error otherwise if( inProperties.IsNotNull() ) { data->SetPropertyList( inProperties ); } else { MITK_ERROR << "The property deserializer did not return a (valid) property list."; error = true; } } else { MITK_ERROR << "Function DecorateBaseDataWithProperties(...) called with false TiXmlElement. \n \t ->Given element does not contain a 'file' attribute. \n"; error = true; } return !error; } diff --git a/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h b/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h index 116fcc88a6..8c6dd19e3c 100644 --- a/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h +++ b/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h @@ -1,191 +1,190 @@ /*=================================================================== 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 MITKIRENDERWINDOWPART_H #define MITKIRENDERWINDOWPART_H #include #include #include #include #include #include #include class QmitkRenderWindow; namespace mitk { struct IRenderingManager; class SliceNavigationController; /** * \ingroup org_mitk_gui_common * * \brief Interface for a MITK Workbench Part providing a render window. * * This interface allows generic access to Workbench parts which provide some * kind of render window. The interface is intended to be implemented by * subclasses of berry::IWorkbenchPart. Usually, the interface is implemented * by a Workbench editor. * * A IRenderWindowPart provides zero or more QmitkRenderWindow instances which can * be controlled via this interface. QmitkRenderWindow instances have an associated * \e id, which is implementation specific. However, implementations should consider * to use one of the following ids for certain QmitkRenderWindow instances to maximize * reusability (they are free to map multiple ids to one QmitkRenderWindow internally): *
    - *
  • transversal (deprecated, use axial instead)
  • *
  • axial
  • *
  • sagittal
  • *
  • coronal
  • *
  • 3d
  • *
* * \see ILinkedRenderWindowPart * \see IRenderWindowPartListener * \see QmitkAbstractRenderEditor */ struct MITK_GUI_COMMON_PLUGIN IRenderWindowPart { static const QString DECORATION_BORDER; // = "border" static const QString DECORATION_LOGO; // = "logo" static const QString DECORATION_MENU; // = "menu" static const QString DECORATION_BACKGROUND; // = "background; virtual ~IRenderWindowPart(); /** * Get the currently active (focused) render window. * Focus handling is implementation specific. * * \return The active QmitkRenderWindow instance; NULL * if no render window is active. */ virtual QmitkRenderWindow* GetActiveQmitkRenderWindow() const = 0; /** * Get all render windows with their ids. * * \return A hash map mapping the render window id to the QmitkRenderWindow instance. */ virtual QHash GetQmitkRenderWindows() const = 0; /** * Get a render window with a specific id. * * \param id The render window id. * \return The QmitkRenderWindow instance for id */ virtual QmitkRenderWindow* GetQmitkRenderWindow(const QString& id) const = 0; /** * Get the rendering manager used by this render window part. * * \return The current IRenderingManager instance or NULL * if no rendering manager is used. */ virtual mitk::IRenderingManager* GetRenderingManager() const = 0; /** * Request an update of all render windows. * * \param requestType Specifies the type of render windows for which an update * will be requested. */ virtual void RequestUpdate(mitk::RenderingManager::RequestType requestType = mitk::RenderingManager::REQUEST_UPDATE_ALL) = 0; /** * Force an immediate update of all render windows. * * \param requestType Specifies the type of render windows for which an immediate update * will be requested. */ virtual void ForceImmediateUpdate(mitk::RenderingManager::RequestType requestType = mitk::RenderingManager::REQUEST_UPDATE_ALL) = 0; /** * Get the SliceNavigationController for controlling time positions. * * \return A SliceNavigationController if the render window supports this * operation; otherwise returns NULL. */ virtual mitk::SliceNavigationController* GetTimeNavigationController() const = 0; /** * Get the selected position in the render window with id id * or in the active render window if id is NULL. * * \param id The render window id. * \return The currently selected position in world coordinates. */ virtual mitk::Point3D GetSelectedPosition(const QString& id = QString()) const = 0; /** * Set the selected position in the render window with id id * or in the active render window if id is NULL. * * \param pos The position in world coordinates which should be selected. * \param id The render window id in which the selection should take place. */ virtual void SetSelectedPosition(const mitk::Point3D& pos, const QString& id = QString()) = 0; /** * Enable \e decorations like colored borders, menu widgets, logos, text annotations, etc. * * Decorations are implementation specific. A set of standardized decoration names is listed * in GetDecorations(). * * \param enable If true enable the decorations specified in decorations, * otherwise disable them. * \param decorations A list of decoration names. If empty, all supported decorations are affected. * * \see GetDecorations() */ virtual void EnableDecorations(bool enable, const QStringList& decorations = QStringList()) = 0; /** * Return if a specific decoration is enabled. * * \return true if the decoration is enabled, false if it is disabled * or unknown. * * \see GetDecorations() */ virtual bool IsDecorationEnabled(const QString& decoration) const = 0; /** * Get a list of supported decorations. * * The following decoration names are standardized and should not be used for other decoration types: *
    *
  • \e DECORATION_BORDER Any border decorations like colored rectangles, etc. *
  • \e DECORATION_MENU Menus associated with render windows *
  • \e DECORATION_BACKGROUND All kinds of backgrounds (patterns, gradients, etc.) except for solid colored backgrounds *
  • \e DECORATION_LOGO Any kind of logo overlayed on the rendered scene *
* * \return A list of supported decoration names. */ virtual QStringList GetDecorations() const = 0; }; } Q_DECLARE_INTERFACE(mitk::IRenderWindowPart, "org.mitk.ui.IRenderWindowPart") #endif // MITKIRENDERWINDOWPART_H diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp index ab59ab24c5..21ef71d7e1 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp @@ -1,461 +1,452 @@ /*=================================================================== 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 "QmitkStdMultiWidgetEditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include class QmitkStdMultiWidgetEditorPrivate { public: QmitkStdMultiWidgetEditorPrivate(); ~QmitkStdMultiWidgetEditorPrivate(); QmitkStdMultiWidget* m_StdMultiWidget; QmitkMouseModeSwitcher* m_MouseModeToolbar; std::string m_FirstBackgroundColor; std::string m_SecondBackgroundColor; bool m_MenuWidgetsEnabled; berry::IPartListener::Pointer m_PartListener; QHash m_RenderWindows; }; struct QmitkStdMultiWidgetPartListener : public berry::IPartListener { berryObjectMacro(QmitkStdMultiWidgetPartListener) QmitkStdMultiWidgetPartListener(QmitkStdMultiWidgetEditorPrivate* dd) : d(dd) {} Events::Types GetPartEventTypes() const { return Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void PartClosed (berry::IWorkbenchPartReference::Pointer partRef) { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->RemovePlanesFromDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(false); } } } void PartHidden (berry::IWorkbenchPartReference::Pointer partRef) { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->RemovePlanesFromDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(false); } } } void PartVisible (berry::IWorkbenchPartReference::Pointer partRef) { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->AddPlanesToDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(true); } } } private: QmitkStdMultiWidgetEditorPrivate* const d; }; QmitkStdMultiWidgetEditorPrivate::QmitkStdMultiWidgetEditorPrivate() : m_StdMultiWidget(0), m_MouseModeToolbar(0) , m_MenuWidgetsEnabled(false) , m_PartListener(new QmitkStdMultiWidgetPartListener(this)) {} QmitkStdMultiWidgetEditorPrivate::~QmitkStdMultiWidgetEditorPrivate() { } const std::string QmitkStdMultiWidgetEditor::EDITOR_ID = "org.mitk.editors.stdmultiwidget"; QmitkStdMultiWidgetEditor::QmitkStdMultiWidgetEditor() : d(new QmitkStdMultiWidgetEditorPrivate) { } QmitkStdMultiWidgetEditor::~QmitkStdMultiWidgetEditor() { this->GetSite()->GetPage()->RemovePartListener(d->m_PartListener); } QmitkStdMultiWidget* QmitkStdMultiWidgetEditor::GetStdMultiWidget() { return d->m_StdMultiWidget; } QmitkRenderWindow *QmitkStdMultiWidgetEditor::GetActiveQmitkRenderWindow() const { if (d->m_StdMultiWidget) return d->m_StdMultiWidget->GetRenderWindow1(); return 0; } QHash QmitkStdMultiWidgetEditor::GetQmitkRenderWindows() const { return d->m_RenderWindows; } QmitkRenderWindow *QmitkStdMultiWidgetEditor::GetQmitkRenderWindow(const QString &id) const { - static bool alreadyWarned = false; - - if(!alreadyWarned) - { - MITK_WARN(id == "transversal") << "QmitkStdMultiWidgetEditor::GetRenderWindow(\"transversal\") is deprecated. Use \"axial\" instead."; - alreadyWarned = true; - } - if (d->m_RenderWindows.contains(id)) return d->m_RenderWindows[id]; return 0; } mitk::Point3D QmitkStdMultiWidgetEditor::GetSelectedPosition(const QString & /*id*/) const { return d->m_StdMultiWidget->GetCrossPosition(); } void QmitkStdMultiWidgetEditor::SetSelectedPosition(const mitk::Point3D &pos, const QString &/*id*/) { d->m_StdMultiWidget->MoveCrossToPosition(pos); } void QmitkStdMultiWidgetEditor::EnableDecorations(bool enable, const QStringList &decorations) { if (decorations.isEmpty() || decorations.contains(DECORATION_BORDER)) { enable ? d->m_StdMultiWidget->EnableColoredRectangles() : d->m_StdMultiWidget->DisableColoredRectangles(); } if (decorations.isEmpty() || decorations.contains(DECORATION_LOGO)) { enable ? d->m_StdMultiWidget->EnableDepartmentLogo() : d->m_StdMultiWidget->DisableDepartmentLogo(); } if (decorations.isEmpty() || decorations.contains(DECORATION_MENU)) { d->m_StdMultiWidget->ActivateMenuWidget(enable); } if (decorations.isEmpty() || decorations.contains(DECORATION_BACKGROUND)) { enable ? d->m_StdMultiWidget->EnableGradientBackground() : d->m_StdMultiWidget->DisableGradientBackground(); } } bool QmitkStdMultiWidgetEditor::IsDecorationEnabled(const QString &decoration) const { if (decoration == DECORATION_BORDER) { return d->m_StdMultiWidget->IsColoredRectanglesEnabled(); } else if (decoration == DECORATION_LOGO) { return d->m_StdMultiWidget->IsColoredRectanglesEnabled(); } else if (decoration == DECORATION_MENU) { return d->m_StdMultiWidget->IsMenuWidgetEnabled(); } else if (decoration == DECORATION_BACKGROUND) { return d->m_StdMultiWidget->GetGradientBackgroundFlag(); } return false; } QStringList QmitkStdMultiWidgetEditor::GetDecorations() const { QStringList decorations; decorations << DECORATION_BORDER << DECORATION_LOGO << DECORATION_MENU << DECORATION_BACKGROUND; return decorations; } mitk::SlicesRotator* QmitkStdMultiWidgetEditor::GetSlicesRotator() const { return d->m_StdMultiWidget->GetSlicesRotator(); } mitk::SlicesSwiveller* QmitkStdMultiWidgetEditor::GetSlicesSwiveller() const { return d->m_StdMultiWidget->GetSlicesSwiveller(); } void QmitkStdMultiWidgetEditor::EnableSlicingPlanes(bool enable) { d->m_StdMultiWidget->SetWidgetPlanesVisibility(enable); } bool QmitkStdMultiWidgetEditor::IsSlicingPlanesEnabled() const { mitk::DataNode::Pointer node = this->d->m_StdMultiWidget->GetWidgetPlane1(); if (node.IsNotNull()) { bool visible = false; node->GetVisibility(visible, 0); return visible; } else { return false; } } void QmitkStdMultiWidgetEditor::EnableLinkedNavigation(bool enable) { enable ? d->m_StdMultiWidget->EnableNavigationControllerEventListening() : d->m_StdMultiWidget->DisableNavigationControllerEventListening(); } bool QmitkStdMultiWidgetEditor::IsLinkedNavigationEnabled() const { return d->m_StdMultiWidget->IsCrosshairNavigationEnabled(); } void QmitkStdMultiWidgetEditor::CreateQtPartControl(QWidget* parent) { if (d->m_StdMultiWidget == 0) { QHBoxLayout* layout = new QHBoxLayout(parent); layout->setContentsMargins(0,0,0,0); if (d->m_MouseModeToolbar == NULL) { d->m_MouseModeToolbar = new QmitkMouseModeSwitcher(parent); // delete by Qt via parent layout->addWidget(d->m_MouseModeToolbar); } d->m_StdMultiWidget = new QmitkStdMultiWidget(parent); - d->m_RenderWindows.insert("transversal", d->m_StdMultiWidget->GetRenderWindow1()); d->m_RenderWindows.insert("axial", d->m_StdMultiWidget->GetRenderWindow1()); d->m_RenderWindows.insert("sagittal", d->m_StdMultiWidget->GetRenderWindow2()); d->m_RenderWindows.insert("coronal", d->m_StdMultiWidget->GetRenderWindow3()); d->m_RenderWindows.insert("3d", d->m_StdMultiWidget->GetRenderWindow4()); d->m_MouseModeToolbar->setMouseModeSwitcher( d->m_StdMultiWidget->GetMouseModeSwitcher() ); connect( d->m_MouseModeToolbar, SIGNAL( MouseModeSelected(mitk::MouseModeSwitcher::MouseMode) ), d->m_StdMultiWidget, SLOT( MouseModeSelected(mitk::MouseModeSwitcher::MouseMode) ) ); layout->addWidget(d->m_StdMultiWidget); mitk::DataStorage::Pointer ds = this->GetDataStorage(); // Tell the multiWidget which (part of) the tree to render d->m_StdMultiWidget->SetDataStorage(ds); // Initialize views as axial, sagittal, coronar to all data objects in DataStorage // (from top-left to bottom) mitk::TimeGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); // Initialize bottom-right view as 3D view d->m_StdMultiWidget->GetRenderWindow4()->GetRenderer()->SetMapperID( mitk::BaseRenderer::Standard3D ); // Enable standard handler for levelwindow-slider d->m_StdMultiWidget->EnableStandardLevelWindow(); // Add the displayed views to the tree to see their positions // in 2D and 3D d->m_StdMultiWidget->AddDisplayPlaneSubTree(); d->m_StdMultiWidget->EnableNavigationControllerEventListening(); // Store the initial visibility status of the menu widget. d->m_MenuWidgetsEnabled = d->m_StdMultiWidget->IsMenuWidgetEnabled(); this->GetSite()->GetPage()->AddPartListener(d->m_PartListener); berry::IPreferences::Pointer prefs = this->GetPreferences(); this->OnPreferencesChanged(dynamic_cast(prefs.GetPointer())); this->RequestUpdate(); } } void QmitkStdMultiWidgetEditor::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { // Enable change of logo. If no DepartmentLogo was set explicitly, MBILogo is used. // Set new department logo by prefs->Set("DepartmentLogo", "PathToImage"); // If no logo was set for this plug-in specifically, walk the parent preference nodes // and lookup a logo value there. const berry::IPreferences* currentNode = prefs; while(currentNode) { std::vector keys = currentNode->Keys(); bool logoFound = false; for( std::size_t i = 0; i < keys.size(); ++i ) { if( keys[i] == "DepartmentLogo") { std::string departmentLogoLocation = currentNode->Get("DepartmentLogo", ""); if (departmentLogoLocation.empty()) { d->m_StdMultiWidget->DisableDepartmentLogo(); } else { // we need to disable the logo first, otherwise setting a new logo will have // no effect due to how mitkManufacturerLogo works... d->m_StdMultiWidget->DisableDepartmentLogo(); d->m_StdMultiWidget->SetDepartmentLogoPath(departmentLogoLocation.c_str()); d->m_StdMultiWidget->EnableDepartmentLogo(); } logoFound = true; break; } } if (logoFound) break; currentNode = currentNode->Parent().GetPointer(); } // preferences for gradient background float color = 255.0; QString firstColorName = QString::fromStdString (prefs->GetByteArray("first background color", "")); QColor firstColor(firstColorName); mitk::Color upper; if (firstColorName=="") // default values { upper[0] = 0.1; upper[1] = 0.1; upper[2] = 0.1; } else { upper[0] = firstColor.red() / color; upper[1] = firstColor.green() / color; upper[2] = firstColor.blue() / color; } QString secondColorName = QString::fromStdString (prefs->GetByteArray("second background color", "")); QColor secondColor(secondColorName); mitk::Color lower; if (secondColorName=="") // default values { lower[0] = 0.5; lower[1] = 0.5; lower[2] = 0.5; } else { lower[0] = secondColor.red() / color; lower[1] = secondColor.green() / color; lower[2] = secondColor.blue() / color; } d->m_StdMultiWidget->SetGradientBackgroundColors(upper, lower); d->m_StdMultiWidget->EnableGradientBackground(); // Set preferences respecting zooming and padding bool constrainedZooming = prefs->GetBool("Use constrained zooming and padding", false); mitk::RenderingManager::GetInstance()->SetConstrainedPaddingZooming(constrainedZooming); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // level window setting bool showLevelWindowWidget = prefs->GetBool("Show level/window widget", true); if (showLevelWindowWidget) { d->m_StdMultiWidget->EnableStandardLevelWindow(); } else { d->m_StdMultiWidget->DisableStandardLevelWindow(); } // mouse modes toolbar bool newMode = prefs->GetBool("PACS like mouse interaction", false); d->m_MouseModeToolbar->setVisible( newMode ); d->m_StdMultiWidget->GetMouseModeSwitcher()->SetInteractionScheme( newMode ? mitk::MouseModeSwitcher::PACS : mitk::MouseModeSwitcher::MITK ); } void QmitkStdMultiWidgetEditor::SetFocus() { if (d->m_StdMultiWidget != 0) d->m_StdMultiWidget->setFocus(); } void QmitkStdMultiWidgetEditor::RequestActivateMenuWidget(bool on) { if (d->m_StdMultiWidget) { if (on) { d->m_StdMultiWidget->ActivateMenuWidget(d->m_MenuWidgetsEnabled); } else { d->m_MenuWidgetsEnabled = d->m_StdMultiWidget->IsMenuWidgetEnabled(); d->m_StdMultiWidget->ActivateMenuWidget(false); } } }