diff --git a/.gitattributes b/.gitattributes index b3de23e58d..51a00f8038 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,65 +1,68 @@ .git* export-ignore .hooks* export-ignore .mailmap export-ignore # Set general file size limit on all files * hooks.MaxObjectKiB=1024 *.bat -crlf *.bin -crlf *.blend -crlf *.bmp -crlf *.cpt -crlf *.gif -crlf *.icns -crlf *.ico -crlf *.jpeg -crlf *.jpg -crlf *.mha -crlf *.odg -crlf *.pbxproj -crlf *.pdf -crlf *.plist -crlf *.png -crlf *.ppt -crlf *.pptx -crlf *.raw -crlf *.vtk -crlf *.xcf -crlf *.xpm -crlf -diff *.sh crlf=input *.sh.in crlf=input configure crlf=input cvsrmvend crlf=input imcp crlf=input imglob crlf=input imln crlf=input immv crlf=input imrm crlf=input imtest crlf=input install-sh crlf=input newalpha crlf=input newversion crlf=input remove_ext crlf=input vxl_doxy.pl crlf=input zap.pl crlf=input *.c whitespace=tab-in-indent,no-lf-at-eof copyright=mitk-license hooks.style=KWStyle,uncrustify *.cpp whitespace=tab-in-indent,no-lf-at-eof copyright=mitk-license hooks.style=KWStyle,uncrustify *.h whitespace=tab-in-indent,no-lf-at-eof copyright=mitk-license hooks.style=KWStyle,uncrustify *.cxx whitespace=tab-in-indent,no-lf-at-eof copyright=mitk-license hooks.style=KWStyle,uncrustify *.hxx whitespace=tab-in-indent,no-lf-at-eof copyright=mitk-license hooks.style=KWStyle,uncrustify *.txx whitespace=tab-in-indent,no-lf-at-eof copyright=mitk-license hooks.style=KWStyle,uncrustify *.txt whitespace=tab-in-indent,no-lf-at-eof *.cmake whitespace=tab-in-indent,no-lf-at-eof # The Microservices use an apache copyright Core/Code/CppMicroServices/**/*.c copyright=apache-license Core/Code/CppMicroServices/**/*.cpp copyright=apache-license Core/Code/CppMicroServices/**/*.h copyright=apache-license # There is no need to check files in the utilities directory for copyright Utilities/** -copyright +Applications/PluginGenerator/PluginTemplate/src/**/*.h -copyright +Applications/PluginGenerator/PluginTemplate/src/**/*.cpp -copyright +Applications/PluginGenerator/ProjectTemplate/Apps/TemplateApp/TemplateApp.cpp -copyright # ExternalData content links must have LF newlines *.md5 crlf=input diff --git a/Applications/PluginGenerator/LICENSE.txt b/Applications/PluginGenerator/LICENSE.txt index 8761edc246..07c13ca843 100644 --- a/Applications/PluginGenerator/LICENSE.txt +++ b/Applications/PluginGenerator/LICENSE.txt @@ -1,29 +1,29 @@ Copyright (c) 2003-2012 German Cancer Research Center, Division of Medical and Biological Informatics All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the German Cancer Research Center, nor the names of - its contributors may be used to endorse or promote products derived from + * Neither the name of the German Cancer Research Center, nor the names of + its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Applications/PluginGenerator/PluginTemplate/documentation/UserManual/Manual.dox b/Applications/PluginGenerator/PluginTemplate/documentation/UserManual/Manual.dox index c254a2ba83..56feaaae05 100755 --- a/Applications/PluginGenerator/PluginTemplate/documentation/UserManual/Manual.dox +++ b/Applications/PluginGenerator/PluginTemplate/documentation/UserManual/Manual.dox @@ -1,19 +1,18 @@ /** \page $(plugin-target) $(plugin-name) \image html icon.xpm "Icon of $(plugin-name)" Available sections: - \ref $(plugin-target)Overview \section $(plugin-target)Overview Describe the features of your awesome plugin here */ - diff --git a/Applications/PluginGenerator/PluginTemplate/documentation/doxygen/modules.dox b/Applications/PluginGenerator/PluginTemplate/documentation/doxygen/modules.dox index 4a1244f9a8..9dcb60e028 100644 --- a/Applications/PluginGenerator/PluginTemplate/documentation/doxygen/modules.dox +++ b/Applications/PluginGenerator/PluginTemplate/documentation/doxygen/modules.dox @@ -1,16 +1,16 @@ /** \defgroup $(plugin-target) $(plugin-symbolic-name) \ingroup MITKPlugins \brief Describe your plugin here. - + */ /** \defgroup $(plugin-target)_internal Internal \ingroup $(plugin-target) \brief This subcategory includes the internal classes of the $(plugin-symbolic-name) plugin. Other plugins must not rely on these classes. They contain implementation details and their interface may change at any time. We mean it. */ diff --git a/Applications/PluginGenerator/PluginTemplate/files.cmake b/Applications/PluginGenerator/PluginTemplate/files.cmake index ad0fe7df61..c1b3369574 100644 --- a/Applications/PluginGenerator/PluginTemplate/files.cmake +++ b/Applications/PluginGenerator/PluginTemplate/files.cmake @@ -1,43 +1,42 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES $(activator-file-name).cpp $(view-file-name).cpp ) set(UI_FILES src/internal/$(view-file-name)Controls.ui ) set(MOC_H_FILES src/internal/$(activator-file-name).h src/internal/$(view-file-name).h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES resources/icon.xpm plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) - diff --git a/Applications/PluginGenerator/PluginTemplate/plugin.xml b/Applications/PluginGenerator/PluginTemplate/plugin.xml index 51215b975c..edacef0b6f 100644 --- a/Applications/PluginGenerator/PluginTemplate/plugin.xml +++ b/Applications/PluginGenerator/PluginTemplate/plugin.xml @@ -1,11 +1,11 @@ - + diff --git a/Applications/PluginGenerator/PluginTemplate/src/internal/QmitkTemplateView.h b/Applications/PluginGenerator/PluginTemplate/src/internal/QmitkTemplateView.h index 40ffd7bac8..73d8c90fde 100644 --- a/Applications/PluginGenerator/PluginTemplate/src/internal/QmitkTemplateView.h +++ b/Applications/PluginGenerator/PluginTemplate/src/internal/QmitkTemplateView.h @@ -1,51 +1,50 @@ $(license) #ifndef $(view-file-name)_h #define $(view-file-name)_h #include #include #include "ui_$(view-file-name)Controls.h" -/*! +/** \brief $(view-class-name) \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. - \sa QmitkFunctionality + \sa QmitkAbstractView \ingroup ${plugin_target}_internal */ class $(view-class-name) : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; - virtual void CreateQtPartControl(QWidget *parent); - protected slots: /// \brief Called when the user clicks the GUI button void DoImageProcessing(); protected: + virtual void CreateQtPartControl(QWidget *parent); + virtual void SetFocus(); /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, const QList& nodes ); Ui::$(view-file-name)Controls m_Controls; }; #endif // $(view-file-name)_h - diff --git a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step09.dox b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step09.dox index f804f36bba..616b1d1cf0 100644 --- a/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step09.dox +++ b/Documentation/Doxygen/DeveloperManual/Starting/GettingToKnow/Tutorial/Step09.dox @@ -1,219 +1,78 @@ /** \page Step09Page MITK Tutorial - Step 9: A plug-in -MITK uses a very modular concept to maximize reusability and portability. You start an application (for example mitkWorkbench, the sample application provided by MITK). An application has several bundles (or plug-ins). A bundle can be a functionality, which in turn can be a view, each of these terms specifying certain behaviour and attributes. +MITK uses a very modular concept to maximize reusability and portability. A MITK application based on the BlueBerry +application framework (for example the MITK Workbench) consists of several bundles (or plug-ins). A bundle can contain +resources and program logic. It can also contribute so-called Views to the main application, which provide a specific +user interface for controlling the bundles functions. -The creation of a MITK plug-in is considerably facilitated by using the MITK BundleGenerator as described in \ref NewPluginPage . +The creation of a MITK plug-in is considerably facilitated by using the MITK PluginGenerator as described in \ref NewPluginPage . -The mentioned tool was used to create a plug-in QmitkRegionGrowing. -Let's first look at what files the BundleGenerator created: +The mentioned tool was used to create a plug-in called org.mitk.example.gui.regiongrowing. +Let's first look at what files the PluginGenerator created: \verbatim documentation\doxygen\ - modules.dox............................. Doxygen file for documenting your plug-in + modules.dox......................... Doxygen file for documenting your plug-in resources\ - icon.xpm................................ The icon of your plug-in. GIMP or other programs (including your text editor) - can be used to change this + icon.xpm............................ The icon of your plug-in. GIMP or other programs (including your text editor) + can be used to change this src\internal\ - QmitkMITKRegionGrowingView.cpp.......... The most important file, implementing behaviour - QmitkMITKRegionGrowingView.h............ Header file of the functionality - QmitkMITKRegionGrowingViewControls.ui... XML file of the Qt Designer, describes buttons, combo boxes, etc. of your controls + QmitkRegionGrowingView.cpp.......... The most important file, implementing behaviour + QmitkRegionGrowingView.h............ Header file of the functionality + QmitkRegionGrowingViewControls.ui... XML file of the Qt Designer, describes buttons, combo boxes, etc. of your controls -CMakeLists.txt \.......................... Build system related files for CMake +CMakeLists.txt \...................... Build system related files for CMake files.cmake / -manifest_headers.cmake.................... Information about your plug-in -plugin.xml ............................... BlueBerry integration +manifest_headers.cmake................ Information about your plug-in +plugin.xml ........................... BlueBerry integration \endverbatim If you are not familiar with Qt development, please look into -this Trolltech page describing .ui files (no, forget about the please, DO it!) +this Digia page describing .ui files (no, forget about the please, DO it!) The C++ files implement a subclass of QmitkAbstractView. In this special case of QmitkRegionGrowing, we added the ability to set some seed points and run a region grower. If you are interested in the concrete changes necessary to turn a freshly generated QmitkRegionGrowing into an integrated one: -Since an access to the StdMultiWidget is needed, manifest_headers.cmake has to be edited: -\verbatim -set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.stdmultiwidgeteditor) -\endverbatim - -To add a PointSet for the seed points: +To add a mitk::PointSet for the seed points: QmitkRegionGrowingView.h -Add includes: -\verbatim -#include "QmitkPointListWidget.h" -#include "QmitkStdMultiWidget.h" -#include "QmitkStdMultiWidgetEditor.h" -\endverbatim +Add includes and forward declarations: +\snippet QmitkRegionGrowingView.h includes -Add the point set as protected object and add Pointers for a QmitkPointListWidget and a QmitkStdMultiWidget: -\verbatim -/// \brief This is the actual seed point data object -mitk::PointSet::Pointer m_PointSet; - -QmitkPointListWidget* lstPoints; -QmitkStdMultiWidget* m_MultiWidget; -\endverbatim +Add the point set and a pointer to a QmitkPointListWidget as a private member: +\snippet QmitkRegionGrowingView.h members QmitkRegionGrowingView.cpp CreateQtPartControl(): -\verbatim -// create a QmitkPointListWidget and add it to the widget created from .ui file -lstPoints = new QmitkPointListWidget(); -m_Controls.verticalLayout->addWidget(lstPoints); - -// get access to StdMultiWidget by using RenderWindowPart -QmitkStdMultiWidgetEditor* qSMWE = dynamic_cast(GetRenderWindowPart()); -m_MultiWidget = qSMWE->GetStdMultiWidget(); - -// let the point set widget know about the multi widget (crosshair updates) -lstPoints->SetMultiWidget( m_MultiWidget ); - -// create a new DataTreeNode containing a PointSet with some interaction -m_PointSet = mitk::PointSet::New(); - -mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New(); -pointSetNode->SetData( m_PointSet ); -pointSetNode->SetName("seed points for region growing"); -pointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true) ); -pointSetNode->SetProperty("layer", mitk::IntProperty::New(1024) ); - -// add the pointset to the data tree (for rendering and access by other modules) -GetDataStorage()->Add( pointSetNode ); - -// tell the GUI widget about out point set -lstPoints->SetPointSetNode( pointSetNode ); -\endverbatim +\snippet QmitkRegionGrowingView.cpp cpp-createqtpartcontrol To use the ITK region grower: QmitkRegionGrowingView.h -Add protected method: -\verbatim -/*! -\brief ITK image processing function - This function is templated like an ITK image. The MITK-Macro AccessByItk determines the actual pixel type and dimensionality of - a given MITK image and calls this function for further processing (in our case region growing) -*/ -template < typename TPixel, unsigned int VImageDimension > - void ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Geometry3D* imageGeometry ); -\endverbatim +Add the private method: +\snippet QmitkRegionGrowingView.h itkimageprocessing QmitkRegionGrowingView.cpp Add includes: -\verbatim -// MITK -#include "mitkImageAccessByItk.h" -#include "mitkITKImageImport.h" -#include "mitkProperties.h" -#include "mitkColorProperty.h" - -// ITK -#include +\snippet QmitkRegionGrowingView.cpp cpp-includes -\endverbatim - -DoImageProcessing(); -\verbatim -// So we have an image. Let's see if the user has set some seed points already -if ( m_PointSet->GetSize() == 0 ) -{ - // no points there. Not good for region growing - QMessageBox::information( NULL, "Region growing functionality", - "Please set some seed points inside the image first.\n" - "(hold Shift key and click left mouse button inside the image.)" - ); - return; -} - -// actually perform region growing. Here we have both an image and some seed points -AccessByItk_1( image, ItkImageProcessing, image->GetGeometry() ); // some magic to call the correctly templated function -\endverbatim +DoImageProcessing(): +\snippet QmitkRegionGrowingView.cpp cpp-doimageprocessing And add the new method: -\verbatim -template < typename TPixel, unsigned int VImageDimension > -void QmitkRegionGrowingView::ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Geometry3D* imageGeometry ) -{ - typedef itk::Image< TPixel, VImageDimension > InputImageType; - typedef typename InputImageType::IndexType IndexType; - - // instantiate an ITK region growing filter, set its parameters - typedef itk::ConnectedThresholdImageFilter RegionGrowingFilterType; - typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); - regionGrower->SetInput( itkImage ); // don't forget this - - // determine a thresholding interval - IndexType seedIndex; - TPixel min( std::numeric_limits::max() ); - TPixel max( std::numeric_limits::min() ); - mitk::PointSet::PointsContainer* points = m_PointSet->GetPointSet()->GetPoints(); - for ( mitk::PointSet::PointsConstIterator pointsIterator = points->Begin(); - pointsIterator != points->End(); - ++pointsIterator ) - { - // first test if this point is inside the image at all - if ( !imageGeometry->IsInside( pointsIterator.Value()) ) - { - continue; - } - - // convert world coordinates to image indices - imageGeometry->WorldToIndex( pointsIterator.Value(), seedIndex); - - // get the pixel value at this point - TPixel currentPixelValue = itkImage->GetPixel( seedIndex ); - - // adjust minimum and maximum values - if (currentPixelValue > max) - max = currentPixelValue; - - if (currentPixelValue < min) - min = currentPixelValue; - - regionGrower->AddSeed( seedIndex ); - } - - MITK_INFO << "Values between " << min << " and " << max; - - min -= 30; - max += 30; - - // set thresholds and execute filter - regionGrower->SetLower( min ); - regionGrower->SetUpper( max ); - - regionGrower->Update(); - - mitk::Image::Pointer resultImage = mitk::ImportItkImage( regionGrower->GetOutput() ); - mitk::DataNode::Pointer newNode = mitk::DataNode::New(); - newNode->SetData( resultImage ); - - // set some properties - newNode->SetProperty("binary", mitk::BoolProperty::New(true)); - newNode->SetProperty("name", mitk::StringProperty::New("dumb segmentation")); - newNode->SetProperty("color", mitk::ColorProperty::New(1.0,0.0,0.0)); - newNode->SetProperty("volumerendering", mitk::BoolProperty::New(true)); - newNode->SetProperty("layer", mitk::IntProperty::New(1)); - newNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); - - // add result to data tree - this->GetDataStorage()->Add( newNode ); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -\endverbatim +\snippet QmitkRegionGrowingView.cpp cpp-itkimageaccess Have fun using MITK! If you meet any difficulties during your first steps, don't hesitate to ask on the MITK mailing list mitk-users@lists.sourceforge.net! People there are kind and will try to help you. \ref Step08Page "[Previous step]" \ref Step10Page "[Next Step]" \ref TutorialPage "[Main tutorial page]" */ diff --git a/Examples/Plugins/PluginList.cmake b/Examples/Plugins/PluginList.cmake index b29ba56832..ceb74aedde 100644 --- a/Examples/Plugins/PluginList.cmake +++ b/Examples/Plugins/PluginList.cmake @@ -1,14 +1,15 @@ # Plug-ins must be ordered according to their dependencies set(MITK_EXAMPLE_PLUGINS org.mitk.example.gui.minimalapplication:ON org.mitk.example.gui.customviewer:ON org.mitk.example.gui.customviewer.views:ON org.mitk.example.gui.multipleperspectives:ON org.mitk.example.gui.selectionserviceqt:ON org.mitk.example.gui.selectionservicemitk:ON org.mitk.example.gui.selectionservicemitk.views:ON org.mitk.example.gui.extensionpointdefinition:ON org.mitk.example.gui.extensionpointcontribution:ON + org.mitk.example.gui.regiongrowing:ON ) diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/CMakeLists.txt b/Examples/Plugins/org.mitk.example.gui.regiongrowing/CMakeLists.txt new file mode 100644 index 0000000000..315f17997a --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/CMakeLists.txt @@ -0,0 +1,7 @@ +project(org_mitk_example_gui_regiongrowing) + +MACRO_CREATE_MITK_CTK_PLUGIN( + EXPORT_DIRECTIVE REGIONGROWING_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDENCIES QmitkExt +) diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/UserManual/Manual.dox b/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..b81d4f1a26 --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/UserManual/Manual.dox @@ -0,0 +1,18 @@ +/** +\page org_mitk_example_gui_regiongrowing Region Grower Example + +\image html icon.xpm "Icon of Region Grower Example" + +Available sections: + - \ref org_mitk_example_gui_regiongrowingOverview + +\section org_mitk_example_gui_regiongrowingOverview +Describe the features of your awesome plugin here +
    +
  • Increases productivity +
  • Creates beautiful images +
  • Generates PhD thesis +
  • Brings world peace +
+ +*/ diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/UserManual/icon.xpm b/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/UserManual/icon.xpm new file mode 100644 index 0000000000..9057c20bc6 --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/UserManual/icon.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * icon_xpm[] = { +"16 16 2 1", +" c #FF0000", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/doxygen/modules.dox b/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..22b3a366c0 --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_example_gui_regiongrowing org.mitk.example.gui.regiongrowing + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_example_gui_regiongrowing_internal Internal + \ingroup org_mitk_example_gui_regiongrowing + + \brief This subcategory includes the internal classes of the org.mitk.example.gui.regiongrowing plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Applications/PluginGenerator/PluginTemplate/files.cmake b/Examples/Plugins/org.mitk.example.gui.regiongrowing/files.cmake similarity index 75% copy from Applications/PluginGenerator/PluginTemplate/files.cmake copy to Examples/Plugins/org.mitk.example.gui.regiongrowing/files.cmake index ad0fe7df61..527fc948cc 100644 --- a/Applications/PluginGenerator/PluginTemplate/files.cmake +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/files.cmake @@ -1,43 +1,42 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES - $(activator-file-name).cpp - $(view-file-name).cpp + org_mitk_example_gui_regiongrowing_Activator.cpp + QmitkRegionGrowingView.cpp ) set(UI_FILES - src/internal/$(view-file-name)Controls.ui + src/internal/QmitkRegionGrowingViewControls.ui ) set(MOC_H_FILES - src/internal/$(activator-file-name).h - src/internal/$(view-file-name).h + src/internal/org_mitk_example_gui_regiongrowing_Activator.h + src/internal/QmitkRegionGrowingView.h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES resources/icon.xpm plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) - diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/manifest_headers.cmake b/Examples/Plugins/org.mitk.example.gui.regiongrowing/manifest_headers.cmake new file mode 100644 index 0000000000..6698c3c0ec --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Region Grower Example") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Applications/PluginGenerator/PluginTemplate/plugin.xml b/Examples/Plugins/org.mitk.example.gui.regiongrowing/plugin.xml similarity index 55% copy from Applications/PluginGenerator/PluginTemplate/plugin.xml copy to Examples/Plugins/org.mitk.example.gui.regiongrowing/plugin.xml index 51215b975c..2ce18af7c8 100644 --- a/Applications/PluginGenerator/PluginTemplate/plugin.xml +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/plugin.xml @@ -1,11 +1,11 @@ - + - diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/resources/icon.xpm b/Examples/Plugins/org.mitk.example.gui.regiongrowing/resources/icon.xpm new file mode 100644 index 0000000000..9057c20bc6 --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/resources/icon.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * icon_xpm[] = { +"16 16 2 1", +" c #FF0000", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingView.cpp b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingView.cpp new file mode 100644 index 0000000000..fd5e271e72 --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingView.cpp @@ -0,0 +1,240 @@ +/*=================================================================== + +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. + +===================================================================*/ + + +// Blueberry +#include +#include + +// Qmitk +#include "QmitkRegionGrowingView.h" + +//! [cpp-includes] +// Qmitk +#include "QmitkPointListWidget.h" +#include "QmitkRenderWindow.h" + +// MITK +#include "mitkImageAccessByItk.h" +#include "mitkITKImageImport.h" +#include "mitkProperties.h" +#include "mitkColorProperty.h" + +// ITK +#include +//! [cpp-includes] + +// Qt +#include + + +const std::string QmitkRegionGrowingView::VIEW_ID = "org.mitk.views.example.regiongrowing"; + +QmitkRegionGrowingView::QmitkRegionGrowingView() + : m_PointListWidget(NULL) +{ +} + +void QmitkRegionGrowingView::SetFocus() +{ + m_Controls.buttonPerformImageProcessing->setFocus(); +} + +void QmitkRegionGrowingView::CreateQtPartControl( QWidget *parent ) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi( parent ); + connect( m_Controls.buttonPerformImageProcessing, SIGNAL(clicked()), this, SLOT(DoImageProcessing()) ); + + //! [cpp-createqtpartcontrol] + // create a QmitkPointListWidget and add it to the widget created from .ui file + m_PointListWidget = new QmitkPointListWidget(); + m_Controls.verticalLayout->addWidget(m_PointListWidget, 1); + + // retrieve a possibly existing IRenderWindowPart + if (mitk::IRenderWindowPart* renderWindowPart = GetRenderWindowPart()) + { + // let the point set widget know about the render window part (crosshair updates) + RenderWindowPartActivated(renderWindowPart); + } + + // create a new DataNode containing a PointSet with some interaction + m_PointSet = mitk::PointSet::New(); + mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New(); + pointSetNode->SetData( m_PointSet ); + pointSetNode->SetName("seed points for region growing"); + pointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true) ); + pointSetNode->SetProperty("layer", mitk::IntProperty::New(1024) ); + + // add the pointset to the data storage (for rendering and access by other modules) + GetDataStorage()->Add( pointSetNode ); + + // tell the GUI widget about the point set + m_PointListWidget->SetPointSetNode( pointSetNode ); + //! [cpp-createqtpartcontrol] +} + +void QmitkRegionGrowingView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes ) +{ + // iterate all selected objects, adjust warning visibility + foreach( mitk::DataNode::Pointer node, nodes ) + { + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + m_Controls.labelWarning->setVisible( false ); + m_Controls.buttonPerformImageProcessing->setEnabled( true ); + return; + } + } + + m_Controls.labelWarning->setVisible( true ); + m_Controls.buttonPerformImageProcessing->setEnabled( false ); +} + +void QmitkRegionGrowingView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) +{ + // let the point set widget know about the slice navigation controllers + // in the active render window part (crosshair updates) + foreach(QmitkRenderWindow* renderWindow, renderWindowPart->GetQmitkRenderWindows().values()) + { + m_PointListWidget->AddSliceNavigationController(renderWindow->GetSliceNavigationController()); + } +} + +void QmitkRegionGrowingView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) +{ + foreach(QmitkRenderWindow* renderWindow, renderWindowPart->GetQmitkRenderWindows().values()) + { + m_PointListWidget->RemoveSliceNavigationController(renderWindow->GetSliceNavigationController()); + } +} + +void QmitkRegionGrowingView::DoImageProcessing() +{ + QList nodes = this->GetDataManagerSelection(); + if (nodes.empty()) return; + + mitk::DataNode* node = nodes.front(); + + if (!node) + { + // Nothing selected. Inform the user and return + QMessageBox::information( NULL, "Template", "Please load and select an image before starting image processing."); + return; + } + + // here we have a valid mitk::DataNode + + // a node itself is not very useful, we need its data item (the image) + mitk::BaseData* data = node->GetData(); + if (data) + { + // test if this data item is an image or not (could also be a surface or something totally different) + mitk::Image* image = dynamic_cast( data ); + if (image) + { + //! [cpp-doimageprocessing] + // So we have an image. Let's see if the user has set some seed points already + if (m_PointSet->GetSize() == 0) + { + // no points there. Not good for region growing + QMessageBox::information( NULL, + "Region growing functionality", + "Please set some seed points inside the image first.\n" + "(hold Shift key and click left mouse button inside the image.)" + ); + return; + } + + // actually perform region growing. Here we have both an image and some seed points + AccessByItk_1( image, ItkImageProcessing, image->GetGeometry() ) // some magic to call the correctly templated function + //! [cpp-doimageprocessing] + } + } +} + +//! [cpp-itkimageaccess] +template < typename TPixel, unsigned int VImageDimension > +void QmitkRegionGrowingView::ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Geometry3D* imageGeometry ) +{ + typedef itk::Image< TPixel, VImageDimension > InputImageType; + typedef typename InputImageType::IndexType IndexType; + + // instantiate an ITK region growing filter, set its parameters + typedef itk::ConnectedThresholdImageFilter RegionGrowingFilterType; + typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); + regionGrower->SetInput( itkImage ); // don't forget this + + // determine a thresholding interval + IndexType seedIndex; + TPixel min( std::numeric_limits::max() ); + TPixel max( std::numeric_limits::min() ); + mitk::PointSet::PointsContainer* points = m_PointSet->GetPointSet()->GetPoints(); + for ( mitk::PointSet::PointsConstIterator pointsIterator = points->Begin(); + pointsIterator != points->End(); + ++pointsIterator ) + { + // first test if this point is inside the image at all + if ( !imageGeometry->IsInside( pointsIterator.Value()) ) + { + continue; + } + + // convert world coordinates to image indices + imageGeometry->WorldToIndex( pointsIterator.Value(), seedIndex); + + // get the pixel value at this point + TPixel currentPixelValue = itkImage->GetPixel( seedIndex ); + + // adjust minimum and maximum values + if (currentPixelValue > max) + max = currentPixelValue; + + if (currentPixelValue < min) + min = currentPixelValue; + + regionGrower->AddSeed( seedIndex ); + } + + MITK_INFO << "Values between " << min << " and " << max; + + min -= 30; + max += 30; + + // set thresholds and execute filter + regionGrower->SetLower( min ); + regionGrower->SetUpper( max ); + + regionGrower->Update(); + + mitk::Image::Pointer resultImage = mitk::ImportItkImage( regionGrower->GetOutput() ); + mitk::DataNode::Pointer newNode = mitk::DataNode::New(); + newNode->SetData( resultImage ); + + // set some properties + newNode->SetProperty("binary", mitk::BoolProperty::New(true)); + newNode->SetProperty("name", mitk::StringProperty::New("dumb segmentation")); + newNode->SetProperty("color", mitk::ColorProperty::New(1.0,0.0,0.0)); + newNode->SetProperty("volumerendering", mitk::BoolProperty::New(true)); + newNode->SetProperty("layer", mitk::IntProperty::New(1)); + newNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); + + // add result to data tree + this->GetDataStorage()->Add( newNode ); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} +//! [cpp-itkimageaccess] diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingView.h b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingView.h new file mode 100644 index 0000000000..2f5c998088 --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingView.h @@ -0,0 +1,97 @@ +/*=================================================================== + +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 QmitkRegionGrowingView_h +#define QmitkRegionGrowingView_h + +#include + +#include + +#include "ui_QmitkRegionGrowingViewControls.h" + +//! [includes] +#include "mitkPointSet.h" +#include "mitkIRenderWindowPartListener.h" + +class QmitkPointListWidget; +//! [includes] + +/** + \brief QmitkRegionGrowingView + + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + + \sa QmitkAbstractView + \ingroup ${plugin_target}_internal +*/ +class QmitkRegionGrowingView : public QmitkAbstractView, public mitk::IRenderWindowPartListener +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + + public: + + static const std::string VIEW_ID; + + QmitkRegionGrowingView(); + + protected slots: + + /// \brief Called when the user clicks the GUI button + void DoImageProcessing(); + + protected: + + virtual void CreateQtPartControl(QWidget *parent); + + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, + const QList& nodes ); + + //! [render-window-part-listener] + void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart); + void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart); + //! [render-window-part-listener] + + Ui::QmitkRegionGrowingViewControls m_Controls; + + private: + + //! [itkimageprocessing] + /** + \brief ITK image processing function + This function is templated like an ITK image. The MITK-Macro AccessByItk determines the actual pixel type and dimensionality of + a given MITK image and calls this function for further processing (in our case region growing) + */ + template < typename TPixel, unsigned int VImageDimension > + void ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Geometry3D* imageGeometry ); + //! [itkimageprocessing] + + //! [members] + /// \brief This is the actual seed point data object + mitk::PointSet::Pointer m_PointSet; + + QmitkPointListWidget* m_PointListWidget; + //! [members] + +}; + +#endif // QmitkRegionGrowingView_h diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui new file mode 100644 index 0000000000..af93c6a8aa --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui @@ -0,0 +1,48 @@ + + + QmitkRegionGrowingViewControls + + + + 0 + 0 + 222 + 161 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + QLabel { color: rgb(255, 0, 0) } + + + Please select an image! + + + + + + + Do image processing + + + Do Something + + + + + + + + + diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp new file mode 100644 index 0000000000..a0d3863e2e --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp @@ -0,0 +1,38 @@ +/*=================================================================== + +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 "org_mitk_example_gui_regiongrowing_Activator.h" + +#include + +#include "QmitkRegionGrowingView.h" + +namespace mitk { + +void org_mitk_example_gui_regiongrowing_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkRegionGrowingView, context) +} + +void org_mitk_example_gui_regiongrowing_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) +} + +} + +Q_EXPORT_PLUGIN2(org_mitk_example_gui_regiongrowing, mitk::org_mitk_example_gui_regiongrowing_Activator) diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h new file mode 100644 index 0000000000..29d561d6f5 --- /dev/null +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h @@ -0,0 +1,40 @@ +/*=================================================================== + +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 org_mitk_example_gui_regiongrowing_Activator_h +#define org_mitk_example_gui_regiongrowing_Activator_h + +#include + +namespace mitk { + +class org_mitk_example_gui_regiongrowing_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + +}; // org_mitk_example_gui_regiongrowing_Activator + +} + +#endif // org_mitk_example_gui_regiongrowing_Activator_h diff --git a/Modules/QmitkExt/QmitkPointListView.cpp b/Modules/QmitkExt/QmitkPointListView.cpp index fb35fe6376..6085eb1b95 100644 --- a/Modules/QmitkExt/QmitkPointListView.cpp +++ b/Modules/QmitkExt/QmitkPointListView.cpp @@ -1,443 +1,470 @@ /*=================================================================== 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 "QmitkPointListView.h" #include "QmitkPointListModel.h" #include "QmitkStdMultiWidget.h" #include "QmitkEditPointDialog.h" #include "mitkRenderingManager.h" #include #include #include #include #include QmitkPointListView::QmitkPointListView( QWidget* parent ) - :QListView( parent ), - m_PointListModel( new QmitkPointListModel() ), - m_SelfCall( false ), - m_showFading(false), - m_MultiWidget( NULL), - m_Snc1(NULL), - m_Snc2(NULL), - m_Snc3(NULL) + : QListView( parent ), + m_Snc1(NULL), + m_Snc2(NULL), + m_Snc3(NULL), + m_PointListModel( new QmitkPointListModel() ), + m_SelfCall( false ), + m_showFading(false), + m_MultiWidget( NULL) { QListView::setAlternatingRowColors( true ); // logic QListView::setSelectionBehavior( QAbstractItemView::SelectRows ); QListView::setSelectionMode( QAbstractItemView::SingleSelection ); QListView::setModel( m_PointListModel ); QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse wheel to change the timestep.\n\nTimeStep:\t%1").arg(0); QListView::setToolTip(tooltip); //m_FadeTimer = new QTimer(); this->setContextMenuPolicy(Qt::CustomContextMenu); m_TimeStepFaderLabel = new QLabel(this); QFont font("Arial", 17); m_TimeStepFaderLabel->setFont(font); //Define Size this->setMinimumHeight(40); //horizontal, vertical this->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); //connect connect( m_PointListModel, SIGNAL(SignalUpdateSelection()), this, SLOT(OnPointSetSelectionChanged()) ); connect( this, SIGNAL(doubleClicked ( const QModelIndex & )), this, SLOT(OnPointDoubleClicked( const QModelIndex & )) ); connect( QListView::selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(OnListViewSelectionChanged(const QItemSelection& , const QItemSelection&)) ); connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &))); } QmitkPointListView::~QmitkPointListView() { delete m_PointListModel; } void QmitkPointListView::SetPointSetNode( mitk::DataNode* pointSetNode ) { m_PointListModel->SetPointSetNode( pointSetNode); } const mitk::PointSet* QmitkPointListView::GetPointSet() const { return m_PointListModel->GetPointSet(); } void QmitkPointListView::SetMultiWidget( QmitkStdMultiWidget* multiWidget ) { m_MultiWidget = multiWidget; } QmitkStdMultiWidget* QmitkPointListView::GetMultiWidget() const { return m_MultiWidget; } void QmitkPointListView::OnPointDoubleClicked(const QModelIndex & index) { mitk::PointSet::PointType p; mitk::PointSet::PointIdentifier id; m_PointListModel->GetPointForModelIndex(index, p, id); QmitkEditPointDialog _EditPointDialog(this); _EditPointDialog.SetPoint(m_PointListModel->GetPointSet(), id, m_PointListModel->GetTimeStep()); _EditPointDialog.exec(); } void QmitkPointListView::OnPointSetSelectionChanged() { const mitk::PointSet* pointSet = m_PointListModel->GetPointSet(); if (pointSet == NULL) return; // update this view's selection status as a result to changes in the point set data structure m_SelfCall = true; int timeStep = m_PointListModel->GetTimeStep(); if ( pointSet->GetNumberOfSelected( timeStep ) > 1 ) { MITK_ERROR << "Point set has multiple selected points. This view is not designed for more than one selected point."; } int selectedIndex = pointSet->SearchSelectedPoint( timeStep ); if (selectedIndex == -1) // no selected point is found { m_SelfCall = false; return; } QModelIndex index; bool modelIndexOkay = m_PointListModel->GetModelIndexForPointID(selectedIndex, index); if (modelIndexOkay == true) QListView::selectionModel()->select( index , QItemSelectionModel::ClearAndSelect ); emit SignalPointSelectionChanged(); m_SelfCall = false; } void QmitkPointListView::OnListViewSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/) { if (m_SelfCall) return; mitk::PointSet* pointSet = const_cast( m_PointListModel->GetPointSet() ); if (pointSet == NULL) return; // (take care that this widget doesn't react to self-induced changes by setting m_SelfCall) m_SelfCall = true; // update selection of all points in pointset: select the one(s) that are selected in the view, deselect all others QModelIndexList selectedIndexes = selected.indexes(); for (mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->Begin(); it != pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->End(); ++it) { QModelIndex index; if (m_PointListModel->GetModelIndexForPointID(it->Index(), index)) { if (selectedIndexes.indexOf(index) != -1) // index is found in the selected indices list { pointSet->SetSelectInfo(it->Index(), true, m_PointListModel->GetTimeStep()); // Use Multiwidget or SliceNavigationControllers to set crosshair to selected point if ( m_MultiWidget != NULL) { m_MultiWidget->MoveCrossToPosition(pointSet->GetPoint(it->Index(), m_PointListModel->GetTimeStep())); } - else if ( (m_Snc1 != NULL) && (m_Snc2 != NULL) && (m_Snc3 != NULL) ) + + mitk::Point3D p = pointSet->GetPoint(it->Index(), m_PointListModel->GetTimeStep()); + + // remove the three ifs below after the SetSnc* methods have been removed + if (m_Snc1 != NULL) { - mitk::Point3D p = pointSet->GetPoint(it->Index(), m_PointListModel->GetTimeStep()); m_Snc1->SelectSliceByPoint(p); + } + if (m_Snc2 != NULL) + { m_Snc2->SelectSliceByPoint(p); + } + if (m_Snc3 != NULL) + { m_Snc3->SelectSliceByPoint(p); } + + for (std::set::const_iterator i = m_Sncs.begin(); + i != m_Sncs.end(); ++i) + { + (*i)->SelectSliceByPoint(p); + } } else { pointSet->SetSelectInfo(it->Index(), false, m_PointListModel->GetTimeStep()); } } } m_SelfCall = false; emit SignalPointSelectionChanged(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointListView::keyPressEvent( QKeyEvent * e ) { if (m_PointListModel == NULL) return; int key = e->key(); switch (key) { case Qt::Key_F2: m_PointListModel->MoveSelectedPointUp(); break; case Qt::Key_F3: m_PointListModel->MoveSelectedPointDown(); break; case Qt::Key_Delete: m_PointListModel->RemoveSelectedPoint(); break; default: break; } } void QmitkPointListView::wheelEvent(QWheelEvent *event) { if (!m_PointListModel || !m_PointListModel->GetPointSet() || (int)(m_PointListModel->GetPointSet()->GetTimeSteps()) == 1 /*|| !m_4DPointSet*/) return; int whe = event->delta(); mitk::PointSet::Pointer ps = dynamic_cast(m_PointListModel->GetPointSet()); unsigned int numberOfTS = ps->GetTimeSteps(); if(numberOfTS == 1) return; int currentTS = this->m_PointListModel->GetTimeStep(); if(whe > 0) { if((currentTS >= (int)(m_PointListModel->GetPointSet()->GetTimeSteps()))) return; this->m_PointListModel->SetTimeStep(++currentTS); } else { if((currentTS <= 0)) return; this->m_PointListModel->SetTimeStep(--currentTS); } QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse wheel to change the timestep.\n\nTimeStep:\t%1").arg(currentTS); this->setToolTip(tooltip); fadeTimeStepIn(); } void QmitkPointListView::fadeTimeStepIn() { //Setup Widget QWidget *m_TimeStepFader = new QWidget(this); QHBoxLayout *layout = new QHBoxLayout(m_TimeStepFader); int x = (int)(this->geometry().x()+this->width()*0.6); int y = (int)(this->geometry().y()+this->height()*0.8); m_TimeStepFader->move(x,y); m_TimeStepFader->resize(60, 55); m_TimeStepFader->setLayout(layout); m_TimeStepFader->setAttribute(Qt::WA_DeleteOnClose); //setup Label // QLabel *label = new QLabel(QString("%1").arg(this->m_PointListModel->GetTimeStep())); layout->addWidget(m_TimeStepFaderLabel); m_TimeStepFaderLabel->setAlignment(Qt::AlignCenter); m_TimeStepFaderLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); m_TimeStepFaderLabel->setLineWidth(2); m_TimeStepFaderLabel->setText(QString("%1").arg(this->m_PointListModel->GetTimeStep())); //give the widget opacity and some colour QPalette pal = m_TimeStepFaderLabel->palette(); QColor semiTransparentColor(139, 192, 223, 50); QColor labelTransparentColor(0,0,0,200); pal.setColor(m_TimeStepFaderLabel->backgroundRole(), semiTransparentColor); pal.setColor(m_TimeStepFaderLabel->foregroundRole(), labelTransparentColor); m_TimeStepFaderLabel->setAutoFillBackground(true); m_TimeStepFaderLabel->setPalette(pal); //show the widget m_TimeStepFader->show(); //and start the timer m_TimeStepFaderLabel->setVisible(true); QTimer::singleShot(2000, this, SLOT(fadeTimeStepOut())); } void QmitkPointListView::fadeTimeStepOut() { m_TimeStepFaderLabel->hide(); } void QmitkPointListView::ctxMenu(const QPoint &pos) { QMenu *menu = new QMenu; // menu->setStyle(); // menu->addAction(tr("Test Item"), this, SLOT(test_slot())); //add Fading check QAction *showFading = new QAction(this); showFading->setCheckable(false); //TODO: reset when fading is working showFading->setEnabled(false); //TODO: reset when fading is working showFading->setText("Fade TimeStep"); connect(showFading, SIGNAL(triggered(bool)), this, SLOT(SetFading(bool))); menu->addAction(showFading); //add Clear action QAction *clearList = new QAction(this); clearList->setText("Clear List"); connect(clearList, SIGNAL(triggered()), this, SLOT(ClearPointList())); menu->addAction(clearList); //add Clear TimeStep action QAction *clearTS = new QAction(this); clearTS->setText("Clear current time step"); connect(clearTS, SIGNAL(triggered()), this, SLOT(ClearPointListTS())); menu->addAction(clearTS); // //add "show time step in list" option // QAction *viewTS = new QAction(this); // viewTS->setText("Show time step in list"); // viewTS->setCheckable(true); // viewTS->setChecked(false); // connect(viewTS, SIGNAL(triggered(bool)), this, SLOT(ClearPointList(bool))); // menu->addAction(viewTS); menu->exec(this->mapToGlobal(pos)); } void QmitkPointListView::SetFading(bool onOff) { m_showFading = onOff; } void QmitkPointListView::ClearPointList() { if(!m_PointListModel->GetPointSet()) return; mitk::PointSet::Pointer curPS = m_PointListModel->GetPointSet(); if ( curPS->GetSize() == 0) return; switch( QMessageBox::question( this, tr("Clear Points"), tr("Remove all points from the displayed list?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { case QMessageBox::Yes: { // m_PointListModel->ClearList(); // /* // if (curPS) // { // curPS->Clear(); // } // */ // mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // break; mitk::PointSet::PointsIterator it; mitk::PointSet::PointsContainer *curPsPoints; while( !curPS->IsEmptyTimeStep(0)) { curPsPoints = curPS->GetPointSet()->GetPoints(); it = curPsPoints->Begin(); curPS->SetSelectInfo(it->Index(),true); m_PointListModel->RemoveSelectedPoint(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); break; } case QMessageBox::No: default: break; } // emit PointListChanged(); } void QmitkPointListView::ClearPointListTS() { // mitk::PointSet* /*::Pointer*/ curPS = m_PointListModel->GetPointSet(); // if ( curPS->GetSize() == 0) // return; // int ts = this->m_PointListModel->GetTimeStep(); // switch( QMessageBox::question( this, tr("Clear Points in Timestep"), // tr("Remove all points from the list with the timestep %1?").arg(ts), // QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) // { // case QMessageBox::Yes: // if (curPS) // { // mitk::PointSet::DataType::Pointer curPSwithTS = curPS->GetPointSet(ts); // //curPSwithTS->Clear(); // } // mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // break; // case QMessageBox::No: // default: // break; // } // // emit PointListChanged(); } void QmitkPointListView::SetSnc1(mitk::SliceNavigationController* snc) { m_Snc1 = snc; } void QmitkPointListView::SetSnc2(mitk::SliceNavigationController* snc) { m_Snc2 = snc; } void QmitkPointListView::SetSnc3(mitk::SliceNavigationController* snc) { m_Snc3 = snc; -} \ No newline at end of file +} + +void QmitkPointListView::AddSliceNavigationController(mitk::SliceNavigationController* snc) +{ + if (snc == NULL) return; + m_Sncs.insert(snc); +} + +void QmitkPointListView::RemoveSliceNavigationController(mitk::SliceNavigationController* snc) +{ + if (snc == NULL) return; + m_Sncs.erase(snc); +} diff --git a/Modules/QmitkExt/QmitkPointListView.h b/Modules/QmitkExt/QmitkPointListView.h index 6c142c380f..68f5c4a2e3 100644 --- a/Modules/QmitkExt/QmitkPointListView.h +++ b/Modules/QmitkExt/QmitkPointListView.h @@ -1,131 +1,153 @@ /*=================================================================== 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 QMITK_POINTLIST_VIEW_H_INCLUDED #define QMITK_POINTLIST_VIEW_H_INCLUDED #include #include #include "QmitkExtExports.h" #include #include "QmitkPointListModel.h" class QmitkStdMultiWidget; /*! * \brief GUI widget for handling mitk::PointSet * * Displays all the points in a mitk::PointSet graphically. * Reacts automatically to changes in the PointSet's selection status. * Updates PointSet's selection status when this list's selection changes. * * If a QmitkStdMultiWidget is assigned via SetMultiWidget(), the * crosshair of the QmitkStdMultiWidget is moved to the currently selected * point. * */ class QmitkExt_EXPORT QmitkPointListView : public QListView { Q_OBJECT public: QmitkPointListView( QWidget* parent = 0 ); ~QmitkPointListView(); /// assign a point set for observation void SetPointSetNode( mitk::DataNode* pointSetNode ); /// which point set to work on const mitk::PointSet* GetPointSet() const; /** * \brief If Multiwidget is set, the crosshair is automatically centering to the selected point * As an alternative, if you dont have a multiwidget, you can call SetSnc1, SetSnc2, SetSnc3 to set the * SliceNavigationControllers directly to enable the focussing feature. */ void SetMultiWidget( QmitkStdMultiWidget* multiWidget ); QmitkStdMultiWidget* GetMultiWidget() const; ///< return the QmitkStdMultiWidget that is used for updating render window crosshair void SetTimesStep(int i); ///< which time step to display/model ///@{ /** * \brief Sets the SliceNavigationController of the three 2D Renderwindows. * If they are defined, they can be used to automatically set the crosshair to the selected point + * + * \deprecatedSince{2013_03} Use AddSliceNavigationController and RemoveSliceNavigationController instead. */ - void SetSnc1(mitk::SliceNavigationController* snc); - void SetSnc2(mitk::SliceNavigationController* snc); - void SetSnc3(mitk::SliceNavigationController* snc); + DEPRECATED( void SetSnc1(mitk::SliceNavigationController* snc) ); + DEPRECATED( void SetSnc2(mitk::SliceNavigationController* snc) ); + DEPRECATED( void SetSnc3(mitk::SliceNavigationController* snc) ); ///@} + /** + * @brief Add a mitk::SliceNavigationController instance. + * @param snc The mitk::SliceNavigationController instance. + * + * This method adds \c snc to the set of slice navigation controllers which are + * used to navigate to the selected point. + */ + void AddSliceNavigationController(mitk::SliceNavigationController* snc); + + /** + * @brief Remove a mitk::SliceNavigationController instance. + * @param snc The mitk::SliceNavigationController instance. + * + * This method removes \c snc from the set of slice navigation controllers which are + * used to navigate to the selected point. + */ + void RemoveSliceNavigationController(mitk::SliceNavigationController* snc); + signals: void SignalPointSelectionChanged(); ///< this signal is emmitted, if the selection of a point in the pointset is changed protected slots: /// Filtering double click event for editing point coordinates via a dialog void OnPointDoubleClicked(const QModelIndex & index); /// called when the point set data structure changes void OnPointSetSelectionChanged(); /// called when the selection of the view widget changes void OnListViewSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); /// fade the shown timestep out void fadeTimeStepOut(); /// open ContextMenu void ctxMenu(const QPoint &pos); /// Turn TimeStep Fading On/Off void SetFading(bool onOff); /// Delete all points in the list void ClearPointList(); /// delete all points in the list in the current timestep void ClearPointListTS(); protected: void keyPressEvent( QKeyEvent * e ); ///< react to F2, F3 and DEL keys void wheelEvent( QWheelEvent* event); ///< change timestep of the current pointset by mouse wheel void fadeTimeStepIn(); ///< fade a label with the currently shown timestep in mitk::SliceNavigationController* m_Snc1; mitk::SliceNavigationController* m_Snc2; mitk::SliceNavigationController* m_Snc3; + std::set m_Sncs; + QmitkPointListModel* m_PointListModel; bool m_SelfCall; bool m_showFading; /// used to position the planes on a selected point QmitkStdMultiWidget* m_MultiWidget; QLabel* m_TimeStepFaderLabel; }; #endif diff --git a/Modules/QmitkExt/QmitkPointListWidget.cpp b/Modules/QmitkExt/QmitkPointListWidget.cpp index 8b07f95800..ff6e60b88e 100644 --- a/Modules/QmitkExt/QmitkPointListWidget.cpp +++ b/Modules/QmitkExt/QmitkPointListWidget.cpp @@ -1,471 +1,506 @@ /*=================================================================== 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 "QmitkPointListWidget.h" #include #include #include #include #include #include #include #include #include "btnLoad.xpm" #include "btnSave.xpm" #include "btnClear.xpm" #include "btnSetPoints.xpm" #include "btnSetPointsManually.xpm" #include "btnUp.xpm" #include "btnDown.xpm" QmitkPointListWidget::QmitkPointListWidget(QWidget *parent, int orientation): QWidget(parent), m_PointListView(NULL), m_MultiWidget(NULL), m_PointSetNode(NULL), m_Orientation(0), m_MovePointUpBtn(NULL), m_MovePointDownBtn(NULL), m_RemovePointBtn(NULL), m_SavePointsBtn(NULL), m_LoadPointsBtn(NULL), m_ToggleAddPoint(NULL), - m_AddPoint(NULL), m_Interactor(NULL), m_TimeStep(0), m_EditAllowed(true), m_NodeObserverTag(0), + m_AddPoint(NULL), m_Snc1(NULL), m_Snc2(NULL), - m_Snc3(NULL) + m_Snc3(NULL), + m_Interactor(NULL), + m_TimeStep(0), + m_EditAllowed(true), + m_NodeObserverTag(0) { m_PointListView = new QmitkPointListView(); if(orientation != 0) m_Orientation = orientation; SetupUi(); SetupConnections(); ObserveNewNode(NULL); } QmitkPointListWidget::~QmitkPointListWidget() { if (m_Interactor) mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor ); m_Interactor = NULL; if(m_PointSetNode && m_NodeObserverTag) { m_PointSetNode->RemoveObserver(m_NodeObserverTag); m_NodeObserverTag = 0; } m_MultiWidget = NULL; delete m_PointListView; } void QmitkPointListWidget::SetupConnections() { //m_PointListView->setModel(m_PointListModel); connect(this->m_LoadPointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnLoadPoints())); connect(this->m_SavePointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnSavePoints())); connect(this->m_MovePointUpBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointUp())); connect(this->m_MovePointDownBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointDown())); connect(this->m_RemovePointBtn, SIGNAL(clicked()), this, SLOT(RemoveSelectedPoint())); connect(this->m_ToggleAddPoint, SIGNAL(toggled(bool)), this, SLOT(OnBtnAddPoint(bool))); connect(this->m_AddPoint, SIGNAL(clicked()), this, SLOT(OnBtnAddPointManually())); connect(this->m_PointListView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnListDoubleClick())); connect(this->m_PointListView, SIGNAL(SignalPointSelectionChanged()), this, SLOT(OnPointSelectionChanged())); } void QmitkPointListWidget::SetupUi() { //Setup the buttons m_ToggleAddPoint = new QPushButton();//iconSetPoints, "", this); m_ToggleAddPoint->setMaximumSize(25,25); m_ToggleAddPoint->setCheckable(true); m_ToggleAddPoint->setToolTip("Toggle point editing (use SHIFT + Left Mouse Button to add Points)"); QIcon iconAdd(btnSetPoints_xpm); m_ToggleAddPoint->setIcon(iconAdd); m_AddPoint = new QPushButton();//iconSetPoints, "", this); m_AddPoint->setMaximumSize(25,25); m_AddPoint->setToolTip("Manually add point"); QIcon iconAddManually(btnSetPointsManually_xpm); m_AddPoint->setIcon(iconAddManually); m_RemovePointBtn = new QPushButton(); m_RemovePointBtn->setMaximumSize(25, 25); const QIcon iconDel(btnClear_xpm); m_RemovePointBtn->setIcon(iconDel); m_RemovePointBtn->setToolTip("Erase one point from list (Hotkey: DEL)"); m_MovePointUpBtn = new QPushButton(); m_MovePointUpBtn->setMaximumSize(25, 25); const QIcon iconUp(btnUp_xpm); m_MovePointUpBtn->setIcon(iconUp); m_MovePointUpBtn->setToolTip("Swap selected point upwards (Hotkey: F2)"); m_MovePointDownBtn = new QPushButton(); m_MovePointDownBtn->setMaximumSize(25, 25); const QIcon iconDown(btnDown_xpm); m_MovePointDownBtn->setIcon(iconDown); m_MovePointDownBtn->setToolTip("Swap selected point downwards (Hotkey: F3)"); m_SavePointsBtn = new QPushButton(); m_SavePointsBtn->setMaximumSize(25, 25); QIcon iconSave(btnSave_xpm); m_SavePointsBtn->setIcon(iconSave); m_SavePointsBtn->setToolTip("Save points to file"); m_LoadPointsBtn = new QPushButton(); m_LoadPointsBtn->setMaximumSize(25, 25); QIcon iconLoad(btnLoad_xpm); m_LoadPointsBtn->setIcon(iconLoad); m_LoadPointsBtn->setToolTip("Load list of points from file (REPLACES current content)"); int i; QBoxLayout* lay1; QBoxLayout* lay2; switch (m_Orientation) { case 0: lay1 = new QVBoxLayout(this); lay2 = new QHBoxLayout(); i = 0; break; case 1: lay1 = new QHBoxLayout(this); lay2 = new QVBoxLayout(); i=-1; break; case 2: lay1 = new QHBoxLayout(this); lay2 = new QVBoxLayout(); i=0; break; default: lay1 = new QVBoxLayout(this); lay2 = new QHBoxLayout(); i=-1; break; } //setup Layouts this->setLayout(lay1); lay1->addLayout(lay2); lay2->stretch(true); lay2->addWidget(m_ToggleAddPoint); lay2->addWidget(m_AddPoint); lay2->addWidget(m_RemovePointBtn); lay2->addWidget(m_MovePointUpBtn); lay2->addWidget(m_MovePointDownBtn); lay2->addWidget(m_SavePointsBtn); lay2->addWidget(m_LoadPointsBtn); //lay2->addSpacing();; lay1->insertWidget(i,m_PointListView); this->setLayout(lay1); } void QmitkPointListWidget::SetPointSet(mitk::PointSet* newPs) { if(newPs == NULL) return; this->m_PointSetNode->SetData(newPs); dynamic_cast(this->m_PointListView->model())->SetPointSetNode(m_PointSetNode); ObserveNewNode(m_PointSetNode); } void QmitkPointListWidget::SetPointSetNode(mitk::DataNode *newNode) { ObserveNewNode(newNode); dynamic_cast(this->m_PointListView->model())->SetPointSetNode(newNode); } void QmitkPointListWidget::OnBtnSavePoints() { if ((dynamic_cast(m_PointSetNode->GetData())) == NULL) return; // don't write empty point sets. If application logic requires something else then do something else. if ((dynamic_cast(m_PointSetNode->GetData()))->GetSize() == 0) return; // let the user choose a file std::string name(""); QString fileNameProposal = QString("/PointSet.mps");//.arg(m_PointSetNode->GetName().c_str()); //"PointSet.mps"; QString aFilename = QFileDialog::getSaveFileName( NULL, "Save point set", QDir::currentPath() + fileNameProposal, "MITK Pointset (*.mps)" ); if ( aFilename.isEmpty() ) return; try { // instantiate the writer and add the point-sets to write mitk::PointSetWriter::Pointer writer = mitk::PointSetWriter::New(); writer->SetInput( dynamic_cast(m_PointSetNode->GetData()) ); writer->SetFileName( aFilename.toLatin1() ); writer->Update(); } catch(...) { QMessageBox::warning( this, "Save point set", QString("File writer reported problems writing %1\n\n" "PLEASE CHECK output file!").arg(aFilename) ); } } void QmitkPointListWidget::OnBtnLoadPoints() { // get the name of the file to load QString filename = QFileDialog::getOpenFileName( NULL, "Open MITK Pointset", "", "MITK Point Sets (*.mps)"); if ( filename.isEmpty() ) return; // attempt to load file try { mitk::PointSetReader::Pointer reader = mitk::PointSetReader::New(); reader->SetFileName( filename.toLatin1() ); reader->Update(); mitk::PointSet::Pointer pointSet = reader->GetOutput(); if ( pointSet.IsNull() ) { QMessageBox::warning( this, "Load point set", QString("File reader could not read %1").arg(filename) ); return; } // loading successful // bool interactionOn( m_Interactor.IsNotNull() ); // if (interactionOn) // { // OnEditPointSetButtonToggled(false); // } // this->SetPointSet(pointSet); // if (interactionOn) // { // OnEditPointSetButtonToggled(true); // } } catch(...) { QMessageBox::warning( this, "Load point set", QString("File reader collapsed while reading %1").arg(filename) ); } emit PointListChanged(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } mitk::PointSet* QmitkPointListWidget::GetPointSet() { return dynamic_cast(m_PointSetNode->GetData()); } mitk::DataNode* QmitkPointListWidget::GetPointSetNode() { return m_PointSetNode; } void QmitkPointListWidget::SetMultiWidget(QmitkStdMultiWidget *multiWidget) { this->m_MultiWidget = multiWidget; m_PointListView->SetMultiWidget(multiWidget); } void QmitkPointListWidget::RemoveSelectedPoint() { if (!m_PointSetNode) return; mitk::PointSet* pointSet = dynamic_cast( m_PointSetNode->GetData() ); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel* pointListModel = dynamic_cast( m_PointListView->model() ); pointListModel->RemoveSelectedPoint(); emit PointListChanged(); } void QmitkPointListWidget::MoveSelectedPointDown() { if (!m_PointSetNode) return; mitk::PointSet* pointSet = dynamic_cast( m_PointSetNode->GetData() ); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel* pointListModel = dynamic_cast( m_PointListView->model() ); pointListModel->MoveSelectedPointDown(); emit PointListChanged(); } void QmitkPointListWidget::MoveSelectedPointUp() { if (!m_PointSetNode) return; mitk::PointSet* pointSet = dynamic_cast( m_PointSetNode->GetData() ); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel* pointListModel = dynamic_cast( m_PointListView->model() ); pointListModel->MoveSelectedPointUp(); emit PointListChanged(); } void QmitkPointListWidget::OnBtnAddPoint(bool checked) { if (m_PointSetNode) { if (checked) { m_Interactor = dynamic_cast(m_PointSetNode->GetInteractor()); if (m_Interactor.IsNull())//if not present, instanciate one m_Interactor = mitk::PointSetInteractor::New("pointsetinteractor", m_PointSetNode); //add it to global interaction to activate it mitk::GlobalInteraction::GetInstance()->AddInteractor( m_Interactor ); } else if ( m_Interactor ) { mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor ); m_Interactor = NULL; } emit EditPointSets(checked); } } void QmitkPointListWidget::OnBtnAddPointManually() { mitk::PointSet* pointSet = this->GetPointSet(); int currentPosition = pointSet->GetSize(); QmitkEditPointDialog editPointDialog(this); editPointDialog.SetPoint(pointSet, currentPosition, m_TimeStep); editPointDialog.exec(); } void QmitkPointListWidget::OnListDoubleClick() { ; } void QmitkPointListWidget::OnPointSelectionChanged() { emit this->PointSelectionChanged(); } void QmitkPointListWidget::DeactivateInteractor(bool /*deactivate*/) { ; } void QmitkPointListWidget::EnableEditButton( bool enabled ) { m_EditAllowed = enabled; if (enabled == false) m_ToggleAddPoint->setEnabled(false); else m_ToggleAddPoint->setEnabled(true); OnBtnAddPoint(enabled); } void QmitkPointListWidget::ObserveNewNode( mitk::DataNode* node ) { // remove old observer if ( m_PointSetNode ) { if (m_Interactor) { mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor ); m_Interactor = NULL; m_ToggleAddPoint->setChecked( false ); } m_PointSetNode->RemoveObserver( m_NodeObserverTag ); m_NodeObserverTag = 0; } m_PointSetNode = node; // add new observer if necessary if ( m_PointSetNode ) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkPointListWidget::OnNodeDeleted ); m_NodeObserverTag = m_PointSetNode->AddObserver( itk::DeleteEvent(), command ); } else { m_NodeObserverTag = 0; } if (m_EditAllowed == true) m_ToggleAddPoint->setEnabled( m_PointSetNode ); else m_ToggleAddPoint->setEnabled( false ); m_RemovePointBtn->setEnabled( m_PointSetNode ); m_LoadPointsBtn->setEnabled( m_PointSetNode ); m_SavePointsBtn->setEnabled(m_PointSetNode); m_AddPoint->setEnabled(m_PointSetNode); } void QmitkPointListWidget::OnNodeDeleted( const itk::EventObject & /*e*/ ) { if(m_PointSetNode.IsNotNull() && ! m_NodeObserverTag) m_PointSetNode->RemoveObserver( m_NodeObserverTag ); m_NodeObserverTag = 0; m_PointSetNode = NULL; m_PointListView->SetPointSetNode(NULL); m_ToggleAddPoint->setEnabled(false); m_RemovePointBtn->setEnabled( false ); m_LoadPointsBtn->setEnabled( false ); m_SavePointsBtn->setEnabled(false); m_AddPoint->setEnabled(false); } void QmitkPointListWidget::SetSnc1(mitk::SliceNavigationController* snc) { - m_Snc1 = snc; - m_PointListView->SetSnc1(snc); + if (snc == NULL) + { + m_PointListView->RemoveSliceNavigationController(m_Snc1); + } + else + { + m_PointListView->AddSliceNavigationController(snc); + } + m_Snc1 = snc; } void QmitkPointListWidget::SetSnc2(mitk::SliceNavigationController* snc) { - m_Snc2 = snc; - m_PointListView->SetSnc2(snc); + if (snc == NULL) + { + m_PointListView->RemoveSliceNavigationController(m_Snc2); + } + else + { + m_PointListView->AddSliceNavigationController(snc); + } + m_Snc2 = snc; } void QmitkPointListWidget::SetSnc3(mitk::SliceNavigationController* snc) { - m_Snc3 = snc; - m_PointListView->SetSnc3(snc); + if (snc == NULL) + { + m_PointListView->RemoveSliceNavigationController(m_Snc3); + } + else + { + m_PointListView->AddSliceNavigationController(snc); + } + m_Snc3 = snc; +} + +void QmitkPointListWidget::AddSliceNavigationController(mitk::SliceNavigationController* snc) +{ + m_PointListView->AddSliceNavigationController(snc); +} + +void QmitkPointListWidget::RemoveSliceNavigationController(mitk::SliceNavigationController* snc) +{ + m_PointListView->RemoveSliceNavigationController(snc); } void QmitkPointListWidget::UnselectEditButton() { m_ToggleAddPoint->setChecked(false); -} \ No newline at end of file +} diff --git a/Modules/QmitkExt/QmitkPointListWidget.h b/Modules/QmitkExt/QmitkPointListWidget.h index e63094a587..67ef291627 100644 --- a/Modules/QmitkExt/QmitkPointListWidget.h +++ b/Modules/QmitkExt/QmitkPointListWidget.h @@ -1,153 +1,171 @@ /*=================================================================== 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 QmitkPointListWidget_H #define QmitkPointListWidget_H #include #include #include "QmitkExtExports.h" #include #include #include #include #include #include /*! * \brief Widget for regular operations on point sets * * Displays a list of point coordinates and a couple of * buttons which * * \li enable point set interaction * \li clear all points from a set * \li load points from file * \li save points to file * * The user/application module of this widget needs to * assign a mitk::PointSet object to this widget. The user * also has to decide whether it wants to put the point set * into (a) DataStorage. This widget will not add/remove * point sets to DataStorage. * * If the render window crosshair should be moved to the * currently selected point, the widget user has to provide * a QmitkStdMultiWidget object. */ class QmitkExt_EXPORT QmitkPointListWidget : public QWidget { Q_OBJECT public: QmitkPointListWidget(QWidget *parent = 0, int orientation = 0); ~QmitkPointListWidget(); void SetupConnections(); ///@{ /** * \brief Sets the SliceNavigationController of the three 2D Renderwindows. * If they are defined, they can be used to automatically set the crosshair to the selected point + * \deprecatedSince{2013_03} Use AddSliceNavigationController and RemoveSliceNavigationController instead. */ - void SetSnc1(mitk::SliceNavigationController* snc); - void SetSnc2(mitk::SliceNavigationController* snc); - void SetSnc3(mitk::SliceNavigationController* snc); + DEPRECATED( void SetSnc1(mitk::SliceNavigationController* snc) ); + DEPRECATED( void SetSnc2(mitk::SliceNavigationController* snc) ); + DEPRECATED( void SetSnc3(mitk::SliceNavigationController* snc) ); ///@} + /** + * @brief Add a mitk::SliceNavigationController instance. + * @param snc The mitk::SliceNavigationController instance. + * + * This method adds \c snc to the set of slice navigation controllers which are + * used to navigate to the selected point. + */ + void AddSliceNavigationController(mitk::SliceNavigationController* snc); + + /** + * @brief Remove a mitk::SliceNavigationController instance. + * @param snc The mitk::SliceNavigationController instance. + * + * This method removes \c snc from the set of slice navigation controllers which are + * used to navigate to the selected point. + */ + void RemoveSliceNavigationController(mitk::SliceNavigationController* snc); /** @brief assign a point set (contained in a node of DataStorage) for observation */ void SetPointSet(mitk::PointSet* newPs); mitk::PointSet* GetPointSet(); /** @brief assign a point set (contained in a node of DataStorage) for observation */ void SetPointSetNode(mitk::DataNode* newNode); mitk::DataNode* GetPointSetNode(); /** @brief assign a QmitkStdMultiWidget for updating render window crosshair */ void SetMultiWidget(QmitkStdMultiWidget* multiWidget); /** @brief itk observer for node "delete" events */ void OnNodeDeleted( const itk::EventObject & e ); /** @brief Unselects the edit button if it is selected. */ void UnselectEditButton(); public slots: void DeactivateInteractor(bool deactivate); void EnableEditButton(bool enabled); signals: /** @brief signal to inform about the state of the EditPointSetButton, whether an interactor for setting points is active or not */ void EditPointSets(bool active); /// signal to inform that the selection of a point in the pointset has changed void PointSelectionChanged(); /// signal to inform about cleared or loaded point sets void PointListChanged(); protected slots: void OnBtnSavePoints(); void OnBtnLoadPoints(); void RemoveSelectedPoint(); void MoveSelectedPointDown(); void MoveSelectedPointUp(); void OnBtnAddPoint(bool checked); void OnBtnAddPointManually(); //void OnBtnSetPointsMode(bool checked); /*! \brief pass through signal from PointListView that point selection has changed */ void OnPointSelectionChanged(); void OnListDoubleClick(); protected: void SetupUi(); void ObserveNewNode(mitk::DataNode* node); QmitkPointListView* m_PointListView; QmitkStdMultiWidget* m_MultiWidget; mitk::DataNode::Pointer m_PointSetNode; int m_Orientation; QPushButton* m_MovePointUpBtn; QPushButton* m_MovePointDownBtn; QPushButton* m_RemovePointBtn; QPushButton* m_SavePointsBtn; QPushButton* m_LoadPointsBtn; QPushButton* m_ToggleAddPoint; QPushButton* m_AddPoint; mitk::SliceNavigationController* m_Snc1; mitk::SliceNavigationController* m_Snc2; mitk::SliceNavigationController* m_Snc3; mitk::PointSetInteractor::Pointer m_Interactor; int m_TimeStep; bool m_EditAllowed; unsigned long m_NodeObserverTag; }; #endif diff --git a/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h b/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h index 03cf2f2182..0c94464f52 100644 --- a/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h +++ b/Plugins/org.mitk.gui.common/src/mitkIRenderWindowPart.h @@ -1,230 +1,230 @@ /*=================================================================== 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. * - * \deprecated The method is deprecated, use the IRenderWindowPart::GetActiveQmitkRenderWindow() instead + * \deprecatedSince{2012_09} The method is deprecated, use the IRenderWindowPart::GetActiveQmitkRenderWindow() instead */ DEPRECATED( virtual QmitkRenderWindow* GetActiveRenderWindow() const) { return GetActiveQmitkRenderWindow(); } /** * Get all render windows with their ids. * * \return A hash map mapping the render window id to the QmitkRenderWindow instance. * - * \deprecated The method is deprecated, use the IRenderWindowPart::GetQmitkRenderWindows() instead + * \deprecatedSince{2012_09} The method is deprecated, use the IRenderWindowPart::GetQmitkRenderWindows() instead */ DEPRECATED( virtual QHash GetRenderWindows() const ) { return GetQmitkRenderWindows(); } /** * Get a render window with a specific id. * * \param id The render window id. * \return The QmitkRenderWindow instance for id * - * \deprecated The method is deprecated, use the IRenderWindowPart::GetQmitkRenderWindow(const QString& id) instead + * \deprecatedSince{2012_09} The method is deprecated, use the IRenderWindowPart::GetQmitkRenderWindow(const QString& id) instead */ DEPRECATED( virtual QmitkRenderWindow* GetRenderWindow(const QString& id) const ) { return GetQmitkRenderWindow( id ); } /** * 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