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
- Increases productivity
- Creates beautiful images
- Generates PhD thesis
- Brings world peace
*/
-
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