diff --git a/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.cpp b/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.cpp index bc2d495811..cae4f3510c 100755 --- a/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.cpp +++ b/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.cpp @@ -1,353 +1,353 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkFunctionality.h" #include "internal/QmitkFunctionalityUtil.h" // other includes #include // mitk Includes #include #include // berry Includes #include #include #include // Qmitk Includes #include // Qt Includes #include #include #include QmitkFunctionality::QmitkFunctionality() : m_Parent(0) , m_Active(false) , m_Visible(false) , m_SelectionProvider(0) , m_HandlesMultipleDataStorages(false) , m_InDataStorageChanged(false) { m_PreferencesService = berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); } void QmitkFunctionality::SetHandleMultipleDataStorages(bool multiple) { m_HandlesMultipleDataStorages = multiple; } bool QmitkFunctionality::HandlesMultipleDataStorages() const { return m_HandlesMultipleDataStorages; } mitk::DataStorage::Pointer QmitkFunctionality::GetDataStorage() const { mitk::IDataStorageService::Pointer service = berry::Platform::GetServiceRegistry().GetServiceById(mitk::IDataStorageService::ID); if (service.IsNotNull()) { if (m_HandlesMultipleDataStorages) return service->GetActiveDataStorage()->GetDataStorage(); else return service->GetDefaultDataStorage()->GetDataStorage(); } return 0; } mitk::DataStorage::Pointer QmitkFunctionality::GetDefaultDataStorage() const { mitk::IDataStorageService::Pointer service = berry::Platform::GetServiceRegistry().GetServiceById(mitk::IDataStorageService::ID); return service->GetDefaultDataStorage()->GetDataStorage(); } void QmitkFunctionality::CreatePartControl(void* parent) { // scrollArea QScrollArea* scrollArea = new QScrollArea; //QVBoxLayout* scrollAreaLayout = new QVBoxLayout(scrollArea); scrollArea->setFrameShadow(QFrame::Plain); scrollArea->setFrameShape(QFrame::NoFrame); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); // m_Parent m_Parent = new QWidget; //m_Parent->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); this->CreateQtPartControl(m_Parent); //scrollAreaLayout->addWidget(m_Parent); //scrollArea->setLayout(scrollAreaLayout); // set the widget now scrollArea->setWidgetResizable(true); scrollArea->setWidget(m_Parent); // add the scroll area to the real parent (the view tabbar) QWidget* parentQWidget = static_cast(parent); QVBoxLayout* parentLayout = new QVBoxLayout(parentQWidget); parentLayout->setMargin(0); parentLayout->setSpacing(0); parentLayout->addWidget(scrollArea); // finally set the layout containing the scroll area to the parent widget (= show it) parentQWidget->setLayout(parentLayout); this->AfterCreateQtPartControl(); } void QmitkFunctionality::AfterCreateQtPartControl() { // REGISTER DATASTORAGE LISTENER this->GetDefaultDataStorage()->AddNodeEvent.AddListener( mitk::MessageDelegate1 ( this, &QmitkFunctionality::NodeAddedProxy ) ); this->GetDefaultDataStorage()->ChangedNodeEvent.AddListener( mitk::MessageDelegate1 ( this, &QmitkFunctionality::NodeChangedProxy ) ); this->GetDefaultDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1 ( this, &QmitkFunctionality::NodeRemovedProxy ) ); // REGISTER PREFERENCES LISTENER berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast(); if(prefs.IsNotNull()) prefs->OnChanged.AddListener(berry::MessageDelegate1(this, &QmitkFunctionality::OnPreferencesChanged)); // REGISTER FOR WORKBENCH SELECTION EVENTS m_BlueBerrySelectionListener = berry::ISelectionListener::Pointer(new berry::SelectionChangedAdapter(this , &QmitkFunctionality::BlueBerrySelectionChanged)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_BlueBerrySelectionListener); // REGISTER A SELECTION PROVIDER QmitkFunctionalitySelectionProvider::Pointer _SelectionProvider = QmitkFunctionalitySelectionProvider::New(this); m_SelectionProvider = _SelectionProvider.GetPointer(); this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(m_SelectionProvider)); // EMULATE INITIAL SELECTION EVENTS // by default a a multi widget is always available this->StdMultiWidgetAvailable(*this->GetActiveStdMultiWidget()); // send datamanager selection this->OnSelectionChanged(this->GetDataManagerSelection()); // send preferences changed event this->OnPreferencesChanged(this->GetPreferences().Cast().GetPointer()); } void QmitkFunctionality::ClosePart() { } void QmitkFunctionality::ClosePartProxy() { this->GetDefaultDataStorage()->AddNodeEvent.RemoveListener( mitk::MessageDelegate1 ( this, &QmitkFunctionality::NodeAddedProxy ) ); this->GetDefaultDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1 ( this, &QmitkFunctionality::NodeRemovedProxy) ); this->GetDefaultDataStorage()->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1 ( this, &QmitkFunctionality::NodeChangedProxy ) ); berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast(); if(prefs.IsNotNull()) { prefs->OnChanged.RemoveListener(berry::MessageDelegate1(this, &QmitkFunctionality::OnPreferencesChanged)); // flush the preferences here (disabled, everyone should flush them by themselves at the right moment) // prefs->Flush(); } // REMOVE SELECTION PROVIDER this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(NULL)); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) { s->RemovePostSelectionListener(m_BlueBerrySelectionListener); } this->ClosePart(); } QmitkFunctionality::~QmitkFunctionality() { this->Register(); this->ClosePartProxy(); this->UnRegister(false); } void QmitkFunctionality::OnPreferencesChanged( const berry::IBerryPreferences* ) { } void QmitkFunctionality::BlueBerrySelectionChanged(berry::IWorkbenchPart::Pointer sourcepart, berry::ISelection::ConstPointer selection) { if(sourcepart.IsNull() || sourcepart->GetSite()->GetId() != "org.mitk.views.datamanager") return; mitk::DataNodeSelection::ConstPointer _DataNodeSelection = selection.Cast(); this->OnSelectionChanged(this->DataNodeSelectionToVector(_DataNodeSelection)); } bool QmitkFunctionality::IsVisible() const { return m_Visible; } void QmitkFunctionality::SetFocus() { } void QmitkFunctionality::Activated() { } void QmitkFunctionality::Deactivated() { } void QmitkFunctionality::StdMultiWidgetAvailable( QmitkStdMultiWidget& /*stdMultiWidget*/ ) { } void QmitkFunctionality::StdMultiWidgetNotAvailable() { } void QmitkFunctionality::DataStorageChanged() { } -QmitkStdMultiWidget* QmitkFunctionality::GetActiveStdMultiWidget() +QmitkStdMultiWidget* QmitkFunctionality::GetActiveStdMultiWidget( bool reCreateWidget ) { QmitkStdMultiWidget* activeStdMultiWidget = 0; berry::IEditorPart::Pointer editor = this->GetSite()->GetPage()->GetActiveEditor(); if (editor.Cast().IsNotNull()) { activeStdMultiWidget = editor.Cast()->GetStdMultiWidget(); } - else + else if (reCreateWidget) { mitk::DataStorageEditorInput::Pointer editorInput; editorInput = new mitk::DataStorageEditorInput(); // open a new multi-widget editor, but do not give it the focus berry::IEditorPart::Pointer editor = this->GetSite()->GetPage()->OpenEditor(editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID, false); activeStdMultiWidget = editor.Cast()->GetStdMultiWidget(); } return activeStdMultiWidget; } void QmitkFunctionality::HandleException( const char* str, QWidget* parent, bool showDialog ) const { //itkGenericOutputMacro( << "Exception caught: " << str ); MITK_ERROR << str; if ( showDialog ) { QMessageBox::critical ( parent, "Exception caught!", str ); } } void QmitkFunctionality::HandleException( std::exception& e, QWidget* parent, bool showDialog ) const { HandleException( e.what(), parent, showDialog ); } void QmitkFunctionality::StdMultiWidgetClosed( QmitkStdMultiWidget& /*stdMultiWidget*/ ) { } void QmitkFunctionality::WaitCursorOn() { QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); } void QmitkFunctionality::BusyCursorOn() { QApplication::setOverrideCursor( QCursor(Qt::BusyCursor) ); } void QmitkFunctionality::WaitCursorOff() { this->RestoreOverrideCursor(); } void QmitkFunctionality::BusyCursorOff() { this->RestoreOverrideCursor(); } void QmitkFunctionality::RestoreOverrideCursor() { QApplication::restoreOverrideCursor(); } berry::IPreferences::Pointer QmitkFunctionality::GetPreferences() const { berry::IPreferencesService::Pointer prefService = m_PreferencesService.Lock(); // const_cast workaround for bad programming: const uncorrectness this->GetViewSite() should be const std::string id = "/" + (const_cast(this))->GetViewSite()->GetId(); return prefService.IsNotNull() ? prefService->GetSystemPreferences()->Node(id): berry::IPreferences::Pointer(0); } void QmitkFunctionality::Visible() { } void QmitkFunctionality::Hidden() { } bool QmitkFunctionality::IsExclusiveFunctionality() const { return true; } void QmitkFunctionality::SetVisible( bool visible ) { m_Visible = visible; } void QmitkFunctionality::SetActivated( bool activated ) { m_Active = activated; } bool QmitkFunctionality::IsActivated() const { return m_Active; } diff --git a/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.h b/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.h index 963df3a66d..924b5774de 100755 --- a/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.h +++ b/CoreUI/Bundles/org.mitk.gui.qt.common/src/QmitkFunctionality.h @@ -1,393 +1,395 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef QMITKFUNCTIONALITY_H_ #define QMITKFUNCTIONALITY_H_ #ifdef __MINGW32__ // We need to inlclude winbase.h here in order to declare // atomic intrinsics like InterlockedIncrement correctly. // Otherwhise, they would be declared wrong within qatomic_windows.h . #include #endif //# blueberry stuff #include #include #include #include //# mitk stuff #include #include "mitkDataNodeSelection.h" #include //# forward declarations class QmitkStdMultiWidget; namespace mitk { class DataNode; } namespace berry { struct IBerryPreferences; } class QmitkFunctionalitySelectionProvider; /// /// \class QmitkFunctionality /// /// \brief The base class of all MITK related blueberry views (~ in the old version of MITK, this was called "Functionality") /// /// QmitkFunctionality provides several convenience methods that eases the introduction of a new view: /// ///
    ///
  1. Access to the DataStorage (~ the shared data repository) ///
  2. Access to the StdMultiWidget (the 2x2 RenderWindow arrangement) ///
  3. Access to and update notification for the functionality/view preferences ///
  4. Access to and update notification for the current DataNode selection / to DataNode selection events send through the SelectionService ///
  5. Methods to send DataNode selections through the SelectionService ///
  6. Some events for unproblematic inter-View communication (e.g. when to add/remove interactors) ///
  7. Some minor important convenience methods (like changing the mouse cursor/exception handling) ///
/// /// Please use the Activated/Deactivated method to add/remove interactors, disabling multiwidget crosshair or anything which may /// "affect" other functionalities. For further reading please have a look at QmitkFunctionality::IsExclusiveFunctionality(). /// class MITK_QT_COMMON QmitkFunctionality : public berry::QtViewPart { //# public virtual methods which can be overwritten public: /// /// Creates smartpointer typedefs /// berryObjectMacro(QmitkFunctionality) /// /// Nothing to do in the standard ctor. Initiliaze your GUI in CreateQtPartControl(QWidget*) /// \see berry::QtViewPart::CreateQtPartControl(QWidget*) /// QmitkFunctionality(); /// /// Disconnects all standard event listeners /// virtual ~QmitkFunctionality(); /// /// Called, when the WorkbenchPart gets closed /// by the user directly or by closing the whole /// app (e.g. for removing event listeners) /// virtual void ClosePart(); /// /// Called when the selection in the workbench changed /// virtual void OnSelectionChanged(std::vector /*nodes*/); /// /// Called when the preferences object of this view changed. /// \see GetPreferences() /// virtual void OnPreferencesChanged(const berry::IBerryPreferences*); /// /// Make this view manage multiple DataStorage. If set to true GetDataStorage() /// will return the currently active DataStorage (and not the default one). /// \see GetDataStorage() /// void SetHandleMultipleDataStorages(bool multiple); /// /// \return true if this view handles multiple DataStorages, false otherwise /// bool HandlesMultipleDataStorages() const; /// /// Called when a StdMultiWidget is available. Should not be used anymore, see GetActiveStdMultiWidget() /// \see GetActiveStdMultiWidget() /// virtual void StdMultiWidgetAvailable(QmitkStdMultiWidget& stdMultiWidget); /// /// Called when a StdMultiWidget is available. Should not be used anymore, see GetActiveStdMultiWidget() /// \see GetActiveStdMultiWidget() /// virtual void StdMultiWidgetClosed(QmitkStdMultiWidget& stdMultiWidget); /// /// Called when no StdMultiWidget is available anymore. Should not be used anymore, see GetActiveStdMultiWidget() /// \see GetActiveStdMultiWidget() /// virtual void StdMultiWidgetNotAvailable(); /// /// Only called when IsExclusiveFunctionality() returns true. /// \see IsExclusiveFunctionality() /// virtual void Activated(); /// /// \return true if this view is currently activated, false otherwise /// bool IsActivated() const; /// /// Only called when IsExclusiveFunctionality() returns true. /// \see IsExclusiveFunctionality() /// virtual void Deactivated(); /// /// Some functionalities need to add special interactors, removes the crosshair from the stdmultiwidget, etc. /// In this case the functionality has to tidy up when changing to another functionality /// which also wants to change the "default configuration". In the old Qt3-based /// version of MITK, two functionalities could never be opened at the same time so that the /// methods Activated() and Deactivated() were the right place for the functionalitites to /// add/remove their interactors, etc. This is still true for the new MITK Workbench, /// but as there can be several functionalities visible at the same time, the behaviour concerning /// when Activated() and Deactivated() are called has changed: /// /// 1. Activated() and Deactivated() are only called if IsExclusiveFunctionality() returns true /// /// 2. If only one standalone functionality is or becomes visible, Activated() will be called on that functionality /// /// 3. If two or more standalone functionalities are visible, /// Activated() will be called on the functionality that receives focus, Deactivated() will be called /// on the one that looses focus, gets hidden or closed /// /// /// As a consequence of 1. if you overwrite IsExclusiveFunctionality() and let it return false, you /// signalize the MITK Workbench that this functionality does nothing to the "default configuration" /// and can easily be visible while other functionalities are also visible. /// /// By default the method returns true. /// /// \return true if this functionality is meant to work as a standalone view, false otherwise /// virtual bool IsExclusiveFunctionality() const; /// /// Informs other parts of the workbench that node is selected via the blueberry selection service. /// void FireNodeSelected(mitk::DataNode* node); /// /// Informs other parts of the workbench that the nodes are selected via the blueberry selection service. /// void FireNodesSelected(std::vector nodes); /// /// Called when this functionality becomes visible ( no matter what IsExclusiveFunctionality() returns ) /// virtual void Visible(); /// /// \return true if this view is currently visible, false otherwise /// bool IsVisible() const; /// /// Called when this functionality is hidden ( no matter what IsExclusiveFunctionality() returns ) /// virtual void Hidden(); //# protected virtual methods which can be overwritten protected: /// /// Called when a DataStorage Add event was thrown. May be reimplemented /// by deriving classes. /// virtual void NodeAdded(const mitk::DataNode* node); /// /// Called when a DataStorage Changed event was thrown. May be reimplemented /// by deriving classes. /// virtual void NodeChanged(const mitk::DataNode* /*node*/); /// /// Called when a DataStorage Remove event was thrown. May be reimplemented /// by deriving classes. /// virtual void NodeRemoved(const mitk::DataNode* node); /// /// Called when a DataStorage add *or* remove *or* change event was thrown. May be reimplemented /// by deriving classes. /// virtual void DataStorageChanged(); /// /// \return the selection of the currently active part of the workbench or an empty vector /// if nothing is selected /// std::vector GetCurrentSelection() const; /// /// Returns the current selection made in the datamanager bundle or an empty vector /// if nothing`s selected or if the bundle does not exist /// std::vector GetDataManagerSelection() const; /// /// Returns the Preferences object for this Functionality. /// Important: When refering to this preferences, e.g. in a PreferencePage: The ID /// for this preferences object is "/", e.g. "/org.mitk.views.datamanager" /// berry::IPreferences::Pointer GetPreferences() const; /// /// Returns the default or the currently active DataStorage if m_HandlesMultipleDataStorages /// is set to true /// \see SetHandleMultipleDataStorages(bool) /// \see HandlesMultipleDataStorages() /// mitk::DataStorage::Pointer GetDataStorage() const; /// /// \return always returns the default DataStorage /// mitk::DataStorage::Pointer GetDefaultDataStorage() const; /// /// Returns the default and active StdMultiWidget. - /// If there is not StdMultiWidget yet a new one is created in this method! + /// \param reCreateWidget a boolean flag to en-/disable the attept to re-create the StdWidget + /// If there is not StdMultiWidget yet a new one is + /// created in this method when called with default parameter! /// - QmitkStdMultiWidget* GetActiveStdMultiWidget(); + QmitkStdMultiWidget* GetActiveStdMultiWidget( bool reCreateWidget = true); /// /// Outputs an error message to the console and displays a message box containing /// the exception description. /// \param e the exception which should be handled /// \param showDialog controls, whether additionally a message box should be /// displayed to inform the user that something went wrong /// void HandleException( std::exception& e, QWidget* parent = NULL, bool showDialog = true ) const; /// /// Calls HandleException ( std::exception&, QWidget*, bool ) internally /// \see HandleException ( std::exception&, QWidget*, bool ) /// void HandleException( const char* str, QWidget* parent = NULL, bool showDialog = true ) const; /// /// Convenient method to set and reset a wait cursor ("hourglass") /// void WaitCursorOn(); /// /// Convenient method to restore the standard cursor /// void WaitCursorOff(); /// /// Convenient method to set and reset a busy cursor /// void BusyCursorOn(); /// /// Convenient method to restore the standard cursor /// void BusyCursorOff(); /// /// Convenient method to restore the standard cursor /// void RestoreOverrideCursor(); //# other public methods which should not be overwritten public: /// /// Creates a scroll area for this view and calls CreateQtPartControl then /// void CreatePartControl(void* parent); /// /// Called when this view receives the focus. Same as Activated() /// \see Activated() /// void SetFocus(); /// /// Called when a DataStorage Add Event was thrown. Sets /// m_InDataStorageChanged to true and calls NodeAdded afterwards. /// \see m_InDataStorageChanged /// void NodeAddedProxy(const mitk::DataNode* node); /// /// Called when a DataStorage remove event was thrown. Sets /// m_InDataStorageChanged to true and calls NodeRemoved afterwards. /// \see m_InDataStorageChanged /// void NodeRemovedProxy(const mitk::DataNode* node); /// /// Called when a DataStorage changed event was thrown. Sets /// m_InDataStorageChanged to true and calls NodeChanged afterwards. /// \see m_InDataStorageChanged /// void NodeChangedProxy(const mitk::DataNode* node); /// /// Toggles the visible flag m_Visible /// void SetVisible(bool visible); /// /// Toggles the activated flag m_Activated /// void SetActivated(bool activated); /// /// Called, when the WorkbenchPart gets closed for removing event listeners /// Internally this method calls ClosePart after it removed the listeners registered /// by QmitkFunctionality. By having this proxy method the user does not have to /// call QmitkFunctionality::ClosePart() when overwriting ClosePart() /// void ClosePartProxy(); //# other protected methods which should not be overwritten (or which are deprecated) protected: /// /// Called immediately after CreateQtPartControl(). /// Here standard event listeners for a QmitkFunctionality are registered /// void AfterCreateQtPartControl(); /// /// code to activate the last visible functionality /// void ActivateLastVisibleFunctionality(); /// /// reactions to selection events from data manager (and potential other senders) /// void BlueBerrySelectionChanged(berry::IWorkbenchPart::Pointer sourcepart, berry::ISelection::ConstPointer selection); /// /// Converts a mitk::DataNodeSelection to a std::vector (possibly empty /// std::vector DataNodeSelectionToVector(mitk::DataNodeSelection::ConstPointer currentSelection) const; //# protected fields protected: /// /// helper stuff to observe BlueBerry selections /// friend struct berry::SelectionChangedAdapter; /// /// Saves the parent of this view (this is the scrollarea created in CreatePartControl(void*) /// \see CreatePartControl(void*) /// QWidget* m_Parent; /// /// Saves if this view is the currently active one. /// bool m_Active; /// /// Saves if this view is visible /// bool m_Visible; //# private fields: private: /// /// Holds the current selection (selection made by this Functionality !!!) /// QmitkFunctionalitySelectionProvider* m_SelectionProvider; /// /// object to observe BlueBerry selections /// berry::ISelectionListener::Pointer m_BlueBerrySelectionListener; /// /// Saves if this view handles multiple datastorages /// bool m_HandlesMultipleDataStorages; /// /// Saves if this class is currently working on DataStorage changes. /// This is a protector variable to avoid recursive calls on event listener functions. bool m_InDataStorageChanged; /// /// saves all visible functionalities /// std::set m_VisibleFunctionalities; /// /// The Preferences Service to retrieve and store preferences. /// berry::IPreferencesService::WeakPtr m_PreferencesService; }; #endif /*QMITKFUNCTIONALITY_H_*/ diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp index 8819c33de7..4ca5b1f513 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp @@ -1,838 +1,842 @@ /*========================================================================= Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkIVIMView.h" #include "QmitkStdMultiWidget.h" // qt #include "qmessagebox.h" #include "qclipboard.h" // mitk #include "mitkDiffusionImage.h" #include "mitkImageCast.h" // itk #include "itkScalarImageToHistogramGenerator.h" #include "itkRegionOfInterestImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" // itk/mitk #include "itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h" #include "itkRegularizedIVIMReconstructionFilter.h" #include "mitkImageCast.h" const std::string QmitkIVIMView::VIEW_ID = "org.mitk.views.ivim"; QmitkIVIMView::QmitkIVIMView() : QmitkFunctionality() , m_Controls( 0 ) - , m_MultiWidget( NULL ), - m_Active(false) + , m_MultiWidget( NULL ) + , m_Active(false) + , m_SliceObserverTag1(0), m_SliceObserverTag2(0), m_SliceObserverTag3(0) { } QmitkIVIMView::~QmitkIVIMView() { - //unregister observers when view is destroyed - if(m_SliceObserverTag1 != 0) - { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); - slicer->RemoveObserver( m_SliceObserverTag1 ); - } - - if(m_SliceObserverTag2 != 0) + QmitkStdMultiWidget* MultiWidget = this->GetActiveStdMultiWidget(false); + if(MultiWidget) { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); - slicer->RemoveObserver( m_SliceObserverTag2 ); - } + //unregister observers when view is destroyed + if( MultiWidget->mitkWidget1 != NULL && m_SliceObserverTag1 != 0) + { + mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget1->GetSliceNavigationController(); + slicer->RemoveObserver( m_SliceObserverTag1 ); + } - if(m_SliceObserverTag3 != 0) + if( MultiWidget->mitkWidget2 != NULL && m_SliceObserverTag2 != 0) + { + mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget2->GetSliceNavigationController(); + slicer->RemoveObserver( m_SliceObserverTag2 ); + } - { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); - slicer->RemoveObserver( m_SliceObserverTag3 ); + if( MultiWidget->mitkWidget3!= NULL && m_SliceObserverTag3 != 0) + { + mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget3->GetSliceNavigationController(); + slicer->RemoveObserver( m_SliceObserverTag3 ); + } } } void QmitkIVIMView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkIVIMViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_ButtonStart, SIGNAL(clicked()), this, SLOT(FittIVIMStart()) ); connect( m_Controls->m_ButtonAutoThres, SIGNAL(clicked()), this, SLOT(AutoThreshold()) ); connect( m_Controls->m_MethodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(MethodCombo(int)) ); connect( m_Controls->m_DStarSlider, SIGNAL(valueChanged(int)), this, SLOT(DStarSlider(int)) ); connect( m_Controls->m_BThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(BThreshSlider(int)) ); connect( m_Controls->m_S0ThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(S0ThreshSlider(int)) ); connect( m_Controls->m_NumItSlider, SIGNAL(valueChanged(int)), this, SLOT(NumItsSlider(int)) ); connect( m_Controls->m_LambdaSlider, SIGNAL(valueChanged(int)), this, SLOT(LambdaSlider(int)) ); connect( m_Controls->m_DisplayResultsCheckbox, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_CheckDStar, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_CheckD, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_Checkf, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_ChooseMethod, SIGNAL(clicked()), this, SLOT(ChooseMethod()) ); connect( m_Controls->m_CurveClipboard, SIGNAL(clicked()), this, SLOT(ClipboardCurveButtonClicked()) ); connect( m_Controls->m_ValuesClipboard, SIGNAL(clicked()), this, SLOT(ClipboardStatisticsButtonClicked()) ); } QString dstar = QString::number(m_Controls->m_DStarSlider->value()/1000.0); m_Controls->m_DStarLabel->setText(dstar); QString bthresh = QString::number(m_Controls->m_BThreshSlider->value()*5.0); m_Controls->m_BThreshLabel->setText(bthresh); QString s0thresh = QString::number(m_Controls->m_S0ThreshSlider->value()*0.5); m_Controls->m_S0ThreshLabel->setText(s0thresh); QString numits = QString::number(m_Controls->m_NumItSlider->value()); m_Controls->m_NumItsLabel->setText(numits); QString lambda = QString::number(m_Controls->m_LambdaSlider->value()*.00001); m_Controls->m_LambdaLabel->setText(lambda); m_Controls->m_VisualizeResultsWidget->setVisible(m_Controls->m_DisplayResultsCheckbox->isChecked()); m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); // m_Controls->m_ADCBValues->setVisible(m_Controls->m_CheckADC->isChecked()); MethodCombo(m_Controls->m_MethodCombo->currentIndex()); } void QmitkIVIMView::Checkbox() { m_Controls->m_VisualizeResultsWidget->setVisible(m_Controls->m_DisplayResultsCheckbox->isChecked()); // m_Controls->m_ADCBValues->setVisible(m_Controls->m_CheckADC->isChecked()); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::MethodCombo(int val) { switch(val) { case 0: m_Controls->dstar->setVisible(false); m_Controls->thres->setVisible(false); m_Controls->thres_2->setVisible(true); m_Controls->m_RegFrame->setVisible(false); break; case 1: m_Controls->dstar->setVisible(true); m_Controls->thres->setVisible(false); m_Controls->thres_2->setVisible(true); m_Controls->m_RegFrame->setVisible(false); break; case 2: m_Controls->dstar->setVisible(false); m_Controls->thres->setVisible(true); m_Controls->thres_2->setVisible(true); m_Controls->m_RegFrame->setVisible(false); break; case 3: m_Controls->dstar->setVisible(false); m_Controls->thres->setVisible(true); m_Controls->thres_2->setVisible(true); m_Controls->m_RegFrame->setVisible(false); break; case 4: m_Controls->dstar->setVisible(false); m_Controls->thres->setVisible(true); m_Controls->thres_2->setVisible(true); m_Controls->m_RegFrame->setVisible(true); break; } itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::DStarSlider (int val) { QString sval = QString::number(val/1000.0); m_Controls->m_DStarLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::BThreshSlider (int val) { QString sval = QString::number(val*5.0); m_Controls->m_BThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::S0ThreshSlider (int val) { QString sval = QString::number(val*0.5); m_Controls->m_S0ThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::NumItsSlider (int val) { QString sval = QString::number(val); m_Controls->m_NumItsLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::LambdaSlider (int val) { QString sval = QString::number(val*.00001); m_Controls->m_LambdaLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } } void QmitkIVIMView::StdMultiWidgetNotAvailable() { { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag1 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag2 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag3 ); } m_MultiWidget = NULL; } void QmitkIVIMView::OnSelectionChanged( std::vector nodes ) { bool foundOneDiffusionImage = false; // iterate all selected objects, adjust warning visibility for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() ) { mitk::DiffusionImage* img = dynamic_cast*>(node->GetData()); if( img ) { if(!foundOneDiffusionImage ) { foundOneDiffusionImage = true; } else { foundOneDiffusionImage = false; } } } } // m_Controls->m_ADCBValues->setVisible( foundOneDiffusionImage && m_Controls->m_CheckADC->isChecked() ); m_Controls->m_ButtonStart->setEnabled( foundOneDiffusionImage ); m_Controls->m_ButtonAutoThres->setEnabled( foundOneDiffusionImage ); m_Controls->m_ControlsFrame->setEnabled( foundOneDiffusionImage ); m_Controls->m_BottomControlsFrame->setEnabled( foundOneDiffusionImage ); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::AutoThreshold() { std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "Please load and select a diffusion image before starting image processing."); return; } typedef mitk::DiffusionImage DiffImgType; DiffImgType* dimg = dynamic_cast(nodes.front()->GetData()); if (!dimg) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } // find bzero index int index = -1; DiffImgType::GradientDirectionContainerType::Pointer directions = dimg->GetDirections(); for(DiffImgType::GradientDirectionContainerType::ConstIterator it = directions->Begin(); it != directions->End(); ++it) { index++; DiffImgType::GradientDirectionType g = it.Value(); if(g[0] == 0 && g[1] == 0 && g[2] == 0 ) break; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = dimg->GetVectorImage(); int vecLength = vecimg->GetVectorLength(); index = index > vecLength-1 ? vecLength-1 : index; MITK_INFO << "Performing Histogram Analysis on Channel" << index; typedef itk::Image ImgType; ImgType::Pointer img = ImgType::New(); mitk::CastToItkImage(dimg, img); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); itw = itw.Begin(); itk::ImageRegionConstIterator itr (vecimg, vecimg->GetLargestPossibleRegion() ); itr = itr.Begin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(index)); ++itr; ++itw; } typedef itk::Statistics::ScalarImageToHistogramGenerator< ImgType > HistogramGeneratorType; typedef HistogramGeneratorType::HistogramType HistogramType; HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New(); histogramGenerator->SetInput( img ); histogramGenerator->SetMarginalScale( 10 ); // Defines y-margin width of histogram histogramGenerator->SetNumberOfBins( 100 ); // CT range [-1024, +2048] --> bin size 4 values histogramGenerator->SetHistogramMin( dimg->GetScalarValueMin() ); histogramGenerator->SetHistogramMax( dimg->GetScalarValueMax() * .5 ); histogramGenerator->Compute(); HistogramType::ConstIterator iter = histogramGenerator->GetOutput()->Begin(); float maxFreq = 0; float maxValue = 0; while ( iter != histogramGenerator->GetOutput()->End() ) { if(iter.GetFrequency() > maxFreq) { maxFreq = iter.GetFrequency(); maxValue = iter.GetMeasurementVector()[0]; } ++iter; } maxValue *= 2; int sliderPos = maxValue * 2; m_Controls->m_S0ThreshSlider->setValue(sliderPos); S0ThreshSlider(sliderPos); } void QmitkIVIMView::FittIVIMStart() { std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "Please load and select a diffusion image before starting image processing."); return; } mitk::DiffusionImage* img = dynamic_cast*>( nodes.front()->GetData()); if (!img) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = img->GetVectorImage(); OutImgType::IndexType dummy; FittIVIM(vecimg, img->GetDirections(), img->GetB_Value(), true, dummy); OutputToDatastorage(nodes); } void QmitkIVIMView::OnSliceChanged(const itk::EventObject& /*e*/) { if(!m_Controls) return; m_Controls->m_Warning->setVisible(false); if(!m_Active) return; m_Controls->m_VisualizeResultsWidget->setVisible(false); if(!m_Controls->m_DisplayResultsCheckbox->isChecked()) return; std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) return; if (nodes.size()>2) return; mitk::DiffusionImage* diffusionImg = 0; mitk::DiffusionImage* img1 = dynamic_cast*>( nodes.front()->GetData()); mitk::DiffusionImage* img2 = 0; mitk::Image* maskImg = 0; if(nodes.size()>1) { if(img1) { if(strcmp(nodes.at(1)->GetData()->GetNameOfClass(), "Image") != 0 ) return; maskImg = dynamic_cast( nodes.at(1)->GetData()); diffusionImg = img1; } else { if(strcmp(nodes.front()->GetData()->GetNameOfClass(), "Image") != 0 ) return; maskImg = dynamic_cast( nodes.front()->GetData()); diffusionImg = dynamic_cast*>( nodes.at(1)->GetData()); } } else { diffusionImg = img1; } if (nodes.size()==2 && (!diffusionImg || !maskImg || m_Controls->m_MethodCombo->currentIndex() == 4 )) return; if (nodes.size()==1 && !diffusionImg) return; IVIMFilterType::GradientDirectionContainerType::ConstIterator gdcit = diffusionImg->GetDirections()->Begin(); bool foundB0 = false; while( gdcit != diffusionImg->GetDirections()->End() ) { if(gdcit.Value().one_norm() <= 0.0) foundB0 = true; ++gdcit; } if(!foundB0) { m_Controls->m_Warning->setText(QString("No baseline (non diffusion-weighted) image found.. aborting:(")); m_Controls->m_Warning->setVisible(true); } else { m_Controls->m_Warning->setVisible(false); } if (!m_MultiWidget) return; m_Controls->m_VisualizeResultsWidget->setVisible(true); typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = (VecImgType*)diffusionImg->GetVectorImage().GetPointer(); VecImgType::Pointer roiImage = VecImgType::New(); if(maskImg == 0) { int roisize = 0; if(m_Controls->m_MethodCombo->currentIndex() == 4) roisize = 5; mitk::Point3D pos = m_MultiWidget->GetCrossPosition(); VecImgType::IndexType crosspos; diffusionImg->GetTimeSlicedGeometry()->WorldToIndex(pos, crosspos); VecImgType::IndexType index; index[0] = crosspos[0] - roisize; index[0] = index[0] < 0 ? 0 : index[0]; index[1] = crosspos[1] - roisize; index[1] = index[1] < 0 ? 0 : index[1]; index[2] = crosspos[2] - roisize; index[2] = index[2] < 0 ? 0 : index[2]; VecImgType::SizeType size; size[0] = roisize*2+1; size[1] = roisize*2+1; size[2] = roisize*2+1; VecImgType::SizeType maxSize = vecimg->GetLargestPossibleRegion().GetSize(); size[0] = index[0]+size[0] > maxSize[0] ? maxSize[0]-index[0] : size[0]; size[1] = index[1]+size[1] > maxSize[1] ? maxSize[1]-index[1] : size[1]; size[2] = index[2]+size[2] > maxSize[2] ? maxSize[2]-index[2] : size[2]; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); VecImgType::IndexType newstart; newstart.Fill(0); VecImgType::RegionType newregion; newregion.SetSize( size ); newregion.SetIndex( newstart ); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( newregion ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(newstart, vecimg->GetPixel(index)); FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetB_Value(), false, crosspos); } else { typedef itk::Image MaskImgType; MaskImgType::Pointer maskItk; CastToItkImage( maskImg, maskItk ); mitk::Point3D pos; pos[0] = 0; pos[1] = 0; pos[2] = 0; VecImgType::IndexType index; index[0] = 0; index[1] = 0; index[2] = 0; VecImgType::SizeType size; size[0] = 1; size[1] = 1; size[2] = 1; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); // iterators over output and input itk::ImageRegionConstIteratorWithIndex vecit(vecimg, vecimg->GetLargestPossibleRegion()); itk::VariableLengthVector avg(vecimg->GetVectorLength()); avg.Fill(0); float numPixels = 0; while ( ! vecit.IsAtEnd() ) { VecImgType::PointType point; vecimg->TransformIndexToPhysicalPoint(vecit.GetIndex(), point); MaskImgType::IndexType index; maskItk->TransformPhysicalPointToIndex(point, index); if(maskItk->GetPixel(index) != 0) { avg += vecit.Get(); numPixels += 1.0; } // update iterators ++vecit; } avg /= numPixels; m_Controls->m_Warning->setText(QString("Averaging ")+QString::number((int)numPixels)+QString(" voxels!")); m_Controls->m_Warning->setVisible(true); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( region ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(index, avg); FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetB_Value(), false, index); } vecimg->SetRegions( vecimg->GetLargestPossibleRegion() ); m_Controls->m_VisualizeResultsWidget->SetParameters(m_Snap); } void QmitkIVIMView::FittIVIM(itk::VectorImage* vecimg, DirContainerType* dirs, float bval, bool multivoxel, OutImgType::IndexType &crosspos) { IVIMFilterType::Pointer filter = IVIMFilterType::New(); filter->SetInput(vecimg); filter->SetGradientDirections(dirs); filter->SetBValue(bval); switch(m_Controls->m_MethodCombo->currentIndex()) { case 0: filter->SetMethod(IVIMFilterType::IVIM_FIT_ALL); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 1: filter->SetMethod(IVIMFilterType::IVIM_DSTAR_FIX); filter->SetDStar(m_Controls->m_DStarLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 2: filter->SetMethod(IVIMFilterType::IVIM_D_THEN_DSTAR); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 3: filter->SetMethod(IVIMFilterType::IVIM_LINEAR_D_THEN_F); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 4: filter->SetMethod(IVIMFilterType::IVIM_REGULARIZED); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetNumberIterations(m_Controls->m_NumItsLabel->text().toInt()); filter->SetLambda(m_Controls->m_LambdaLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; } if(!multivoxel) { filter->SetFitDStar(true); } filter->SetNumberOfThreads(1); filter->SetVerbose(multivoxel); filter->SetCrossPosition(crosspos); filter->Update(); m_Snap = filter->GetSnapshot(); m_DStarMap = filter->GetOutput(2); m_DMap = filter->GetOutput(1); m_fMap = filter->GetOutput(0); } void QmitkIVIMView::OutputToDatastorage(std::vector nodes) { // Outputs to Datastorage QString basename(nodes.front()->GetName().c_str()); if(m_Controls->m_CheckDStar->isChecked()) { mitk::Image::Pointer dstarimage = mitk::Image::New(); dstarimage->InitializeByItk(m_DStarMap.GetPointer()); dstarimage->SetVolume(m_DStarMap->GetBufferPointer()); QString newname2 = basename; newname2 = newname2.append("_DStarMap%1").arg(m_Controls->m_MethodCombo->currentIndex()); mitk::DataNode::Pointer node2=mitk::DataNode::New(); node2->SetData( dstarimage ); node2->SetName(newname2.toAscii()); GetDefaultDataStorage()->Add(node2); } if(m_Controls->m_CheckD->isChecked()) { mitk::Image::Pointer dimage = mitk::Image::New(); dimage->InitializeByItk(m_DMap.GetPointer()); dimage->SetVolume(m_DMap->GetBufferPointer()); QString newname1 = basename; newname1 = newname1.append("_DMap%1").arg(m_Controls->m_MethodCombo->currentIndex()); mitk::DataNode::Pointer node1=mitk::DataNode::New(); node1->SetData( dimage ); node1->SetName(newname1.toAscii()); GetDefaultDataStorage()->Add(node1); } if(m_Controls->m_Checkf->isChecked()) { mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(m_fMap.GetPointer()); image->SetVolume(m_fMap->GetBufferPointer()); QString newname0 = basename; newname0 = newname0.append("_fMap%1").arg(m_Controls->m_MethodCombo->currentIndex()); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); node->SetName(newname0.toAscii()); GetDefaultDataStorage()->Add(node); } m_MultiWidget->RequestUpdate(); } void QmitkIVIMView::ChooseMethod() { m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); } void QmitkIVIMView::ClipboardCurveButtonClicked() { if(true) { QString clipboard("Measurement Points\n"); for ( int i=0; isetText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::ClipboardStatisticsButtonClicked() { if ( true ) { QString clipboard( "f \t D \t D* \n" ); clipboard = clipboard.append( "%L1 \t %L2 \t %L3" ) .arg( m_Snap.currentF, 0, 'f', 10 ) .arg( m_Snap.currentD, 0, 'f', 10 ) .arg( m_Snap.currentDStar, 0, 'f', 10 ) ; QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::Activated() { m_Active = true; } void QmitkIVIMView::Deactivated() { m_Active = false; } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp index d2c140e8e5..8b8739ee67 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp @@ -1,207 +1,222 @@ /*========================================================================= Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkODFDetailsView.h" #include #include #include #include #include #include const std::string QmitkODFDetailsView::VIEW_ID = "org.mitk.views.odfdetails"; QmitkODFDetailsView::QmitkODFDetailsView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) { m_VtkActor = vtkActor::New(); m_VtkMapper = vtkPolyDataMapper::New(); m_Renderer = vtkRenderer::New(); m_VtkRenderWindow = vtkRenderWindow::New(); m_RenderWindowInteractor = vtkRenderWindowInteractor::New(); m_Camera = vtkCamera::New(); m_VtkRenderWindow->SetSize(300,300); } QmitkODFDetailsView::~QmitkODFDetailsView() { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); - slicer->RemoveObserver(this->m_SliceObserverTag1); + QmitkStdMultiWidget* MultiWidget = this->GetActiveStdMultiWidget(false); - slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); - slicer->RemoveObserver(this->m_SliceObserverTag2); + if(MultiWidget) + { + //unregister observers when view is destroyed + if( MultiWidget->mitkWidget1 != NULL && m_SliceObserverTag1 != 0) + { + mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget1->GetSliceNavigationController(); + slicer->RemoveObserver( m_SliceObserverTag1 ); + } + + if( MultiWidget->mitkWidget2 != NULL && m_SliceObserverTag2 != 0) + { + mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget2->GetSliceNavigationController(); + slicer->RemoveObserver( m_SliceObserverTag2 ); + } - slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); - slicer->RemoveObserver(this->m_SliceObserverTag3); + if( MultiWidget->mitkWidget3!= NULL && m_SliceObserverTag3 != 0) + { + mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget3->GetSliceNavigationController(); + slicer->RemoveObserver( m_SliceObserverTag3 ); + } + } } void QmitkODFDetailsView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkODFDetailsViewControls; m_Controls->setupUi( parent ); this->m_Controls->m_ODFValueTable->setColumnCount(QBALL_ODFSIZE); this->m_Controls->m_ODFValueTable->setRowCount(1); } } void QmitkODFDetailsView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } } void QmitkODFDetailsView::StdMultiWidgetNotAvailable() { { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag1 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag2 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag3 ); } m_MultiWidget = NULL; } void QmitkODFDetailsView::OnSliceChanged(const itk::EventObject& /*e*/) { m_Values.clear(); std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) return; if (nodes.size()>1) return; mitk::QBallImage::Pointer img = dynamic_cast( nodes.front()->GetData()); if (!img) return; if (!m_MultiWidget) return; m_TemplateOdf = itk::OrientationDistributionFunction::GetBaseMesh(); m_OdfTransform = vtkSmartPointer::New(); m_OdfTransform->Identity(); m_OdfVals = vtkSmartPointer::New(); m_OdfSource = vtkSmartPointer::New(); itk::OrientationDistributionFunction odf; mitk::Point3D world = m_MultiWidget->GetCrossPosition(); mitk::Point3D index; img->GetTimeSlicedGeometry()->WorldToIndex(world, index); OdfVectorImgType::Pointer itkQBallImage = OdfVectorImgType::New(); mitk::CastToItkImage(img, itkQBallImage); float sum = 0; float max = itk::NumericTraits::min(); float min = itk::NumericTraits::max(); std::ostringstream text; if( text.good() ) { m_Values.clear(); OdfVectorImgType::IndexType ind; ind[0] = (int)(index[0]+0.5); ind[1] = (int)(index[1]+0.5); ind[2] = (int)(index[2]+0.5); OdfVectorImgType::PixelType pixel = itkQBallImage->GetPixel(ind); for (int i=0; imax) max = pixel[i]; if (pixel[i]m_Controls->m_ODFValueTable->setItem(0,i,item); this->m_Controls->m_ODFValueTable->update(); m_Values.push_back(pixel[i]); } float mean = sum/QBALL_ODFSIZE; text.clear(); text.str(""); text << sum; this->m_Controls->m_Sum->setText(text.str().c_str()); text.clear(); text.str(""); text << mean ; this->m_Controls->m_Mean->setText(text.str().c_str()); text.clear(); text.str(""); text << ind[0] << ", " << ind[1] << ", " << ind[2]; this->m_Controls->m_Pos->setText(text.str().c_str()); text.clear(); text.str(""); text << min; this->m_Controls->m_Min->setText(text.str().c_str()); text.clear(); text.str(""); text << max; this->m_Controls->m_Max->setText(text.str().c_str()); text.clear(); text.str(""); text << odf.GetGeneralizedFractionalAnisotropy(); this->m_Controls->m_GFA->setText(text.str().c_str()); m_Controls->m_ODFDetailsWidget->SetParameters(m_Values); m_Controls->m_ODFRenderWidget->GenerateODF(m_Values); } }