diff --git a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp
index 3a0fc9455b..7c569071d6 100644
--- a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp
+++ b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp
@@ -1,376 +1,475 @@
/*===================================================================
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 "mitkWorkbenchUtil.h"
#include
#include
#include
#include
#include
#include
#include "mitkIDataStorageService.h"
#include "mitkDataStorageEditorInput.h"
#include "mitkRenderingManager.h"
-#include "mitkIRenderWindowPart.h"
#include "mitkIRenderingManager.h"
#include "mitkProperties.h"
#include "mitkNodePredicateData.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateProperty.h"
#include "mitkCoreObjectFactory.h"
#include "QmitkIOUtil.h"
#include
#include
#include
#include "internal/org_mitk_gui_common_Activator.h"
namespace mitk {
-struct WorkbenchUtilPrivate {
-
- /**
- * Get the editor descriptor for a given name using the editorDescriptor
- * passed in as a default as a starting point.
- *
- * @param name
- * The name of the element to open.
- * @param editorReg
- * The editor registry to do the lookups from.
- * @param defaultDescriptor
- * IEditorDescriptor or null
- * @return IEditorDescriptor
- * @throws PartInitException
- * if no valid editor can be found
- */
- static berry::IEditorDescriptor::Pointer GetEditorDescriptor(const QString& name,
- berry::IEditorRegistry* editorReg,
- berry::IEditorDescriptor::Pointer defaultDescriptor)
- {
-
- if (defaultDescriptor.IsNotNull())
+ struct WorkbenchUtilPrivate {
+
+ /**
+ * Get the editor descriptor for a given name using the editorDescriptor
+ * passed in as a default as a starting point.
+ *
+ * @param name
+ * The name of the element to open.
+ * @param editorReg
+ * The editor registry to do the lookups from.
+ * @param defaultDescriptor
+ * IEditorDescriptor or null
+ * @return IEditorDescriptor
+ * @throws PartInitException
+ * if no valid editor can be found
+ */
+ static berry::IEditorDescriptor::Pointer GetEditorDescriptor(const QString& name, berry::IEditorRegistry* editorReg, berry::IEditorDescriptor::Pointer defaultDescriptor)
{
- return defaultDescriptor;
- }
+ if (defaultDescriptor.IsNotNull())
+ {
+ return defaultDescriptor;
+ }
- berry::IEditorDescriptor::Pointer editorDesc = defaultDescriptor;
+ berry::IEditorDescriptor::Pointer editorDesc = defaultDescriptor;
- // next check the OS for in-place editor (OLE on Win32)
- if (editorReg->IsSystemInPlaceEditorAvailable(name))
- {
- editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_INPLACE_EDITOR_ID);
- }
+ // next check the OS for in-place editor (OLE on Win32)
+ if (editorReg->IsSystemInPlaceEditorAvailable(name))
+ {
+ editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_INPLACE_EDITOR_ID);
+ }
- // next check with the OS for an external editor
- if (editorDesc.IsNull() && editorReg->IsSystemExternalEditorAvailable(name))
- {
- editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_EXTERNAL_EDITOR_ID);
+ // next check with the OS for an external editor
+ if (editorDesc.IsNull() && editorReg->IsSystemExternalEditorAvailable(name))
+ {
+ editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_EXTERNAL_EDITOR_ID);
+ }
+
+ // if no valid editor found, bail out
+ if (editorDesc.IsNull())
+ {
+ throw berry::PartInitException("No editor found");
+ }
+
+ return editorDesc;
}
- // if no valid editor found, bail out
- if (editorDesc.IsNull())
+ static mitk::IDataStorageReference::Pointer GetDataStorageReference()
{
- throw berry::PartInitException("No editor found");
- }
+ ctkPluginContext* context = mitk::PluginActivator::GetContext();
+ mitk::IDataStorageService* dss = nullptr;
+ ctkServiceReference dsRef = context->getServiceReference();
+ if (dsRef)
+ {
+ dss = context->getService(dsRef);
+ }
- return editorDesc;
- }
-};
-// //! [UtilLoadFiles]
-void WorkbenchUtil::LoadFiles(const QStringList &fileNames, berry::IWorkbenchWindow::Pointer window, bool openEditor)
-// //! [UtilLoadFiles]
-{
- if (fileNames.empty())
- return;
+ if (nullptr == dss)
+ {
+ QString msg = "IDataStorageService service not available. Unable to open files.";
+ MITK_WARN << msg.toStdString();
+ QMessageBox::warning(QApplication::activeWindow(), "Unable to open files", msg);
+ return mitk::IDataStorageReference::Pointer(nullptr);
+ }
- mitk::IDataStorageReference::Pointer dataStorageRef;
+ // Get the active data storage (or the default one, if none is active)
+ mitk::IDataStorageReference::Pointer dataStorageRef = dss->GetDataStorage();
+ context->ungetService(dsRef);
+ return dataStorageRef;
+ }
+
+ }; // end struct WorkbenchUtilPrivate
+
+ void WorkbenchUtil::LoadFiles(const QStringList &fileNames, berry::IWorkbenchWindow::Pointer window, bool openEditor)
{
- ctkPluginContext* context = mitk::PluginActivator::GetContext();
- mitk::IDataStorageService* dss = nullptr;
- ctkServiceReference dsRef = context->getServiceReference();
- if (dsRef)
+ if (fileNames.empty())
{
- dss = context->getService(dsRef);
+ return;
}
- if (!dss)
+ mitk::IDataStorageReference::Pointer dataStorageReference = WorkbenchUtilPrivate::GetDataStorageReference();
+ if (nullptr == dataStorageReference)
{
- QString msg = "IDataStorageService service not available. Unable to open files.";
- MITK_WARN << msg.toStdString();
- QMessageBox::warning(QApplication::activeWindow(), "Unable to open files", msg);
return;
}
+ mitk::DataStorage::Pointer dataStorage = dataStorageReference->GetDataStorage();
- // Get the active data storage (or the default one, if none is active)
- dataStorageRef = dss->GetDataStorage();
- context->ungetService(dsRef);
- }
-
- mitk::DataStorage::Pointer dataStorage = dataStorageRef->GetDataStorage();
-
- // Do the actual work of loading the data into the data storage
-
- // Turn off ASSERT
- #if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
- int lastCrtReportType = _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG );
- #endif
+ // Turn off ASSERT
+#if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
+ int lastCrtReportType = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
+#endif
- DataStorage::SetOfObjects::Pointer data;
- try
- {
- data = QmitkIOUtil::Load(fileNames, *dataStorage);
- }
- catch (const mitk::Exception& e)
- {
- MITK_INFO << e;
- return;
- }
- const bool dsmodified = !data->empty();
+ // Do the actual work of loading the data into the data storage
+ DataStorage::SetOfObjects::Pointer data;
+ try
+ {
+ data = QmitkIOUtil::Load(fileNames, *dataStorage);
+ }
+ catch (const mitk::Exception& e)
+ {
+ MITK_INFO << e;
+ return;
+ }
+ const bool dsmodified = !data->empty();
- // Set ASSERT status back to previous status.
- #if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
+ // Set ASSERT status back to previous status.
+#if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
if (lastCrtReportType)
- _CrtSetReportMode( _CRT_ASSERT, lastCrtReportType );
- #endif
+ _CrtSetReportMode(_CRT_ASSERT, lastCrtReportType);
+#endif
- // Check if there is an open perspective. If not, open the default perspective.
- if (window->GetActivePage().IsNull())
- {
- QString defaultPerspId = window->GetWorkbench()->GetPerspectiveRegistry()->GetDefaultPerspective();
- window->GetWorkbench()->ShowPerspective(defaultPerspId, window);
- }
+ // Check if there is an open perspective. If not, open the default perspective.
+ if (window->GetActivePage().IsNull())
+ {
+ QString defaultPerspId = window->GetWorkbench()->GetPerspectiveRegistry()->GetDefaultPerspective();
+ window->GetWorkbench()->ShowPerspective(defaultPerspId, window);
+ }
- bool globalReinitOnNodeAdded = true;
- berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService();
- if (prefService != nullptr)
- {
+ bool globalReinitOnNodeAdded = true;
+ berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService();
+ if (prefService != nullptr)
+ {
berry::IPreferences::Pointer prefs
- = prefService->GetSystemPreferences()->Node("org.mitk.views.datamanager");
- if(prefs.IsNotNull())
+ = prefService->GetSystemPreferences()->Node("org.mitk.views.datamanager");
+ if (prefs.IsNotNull())
{
globalReinitOnNodeAdded = prefs->GetBool("Call global reinit if node is added", true);
}
- }
+ }
- if (openEditor && globalReinitOnNodeAdded)
- {
- try
+ if (openEditor && globalReinitOnNodeAdded)
{
- // Activate the editor using the same data storage or open the default editor
- mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(dataStorageRef));
- berry::IEditorPart::Pointer editor = mitk::WorkbenchUtil::OpenEditor(window->GetActivePage(), input, true);
- mitk::IRenderWindowPart* renderEditor = dynamic_cast(editor.GetPointer());
- mitk::IRenderingManager* renderingManager = renderEditor == nullptr ? nullptr : renderEditor->GetRenderingManager();
-
- if(dsmodified && renderingManager)
+ try
{
- mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage);
+ // Activate the editor using the same data storage or open the default editor
+ mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(dataStorageReference));
+ berry::IEditorPart::Pointer editor = mitk::WorkbenchUtil::OpenEditor(window->GetActivePage(), input, true);
+ mitk::IRenderWindowPart* renderEditor = dynamic_cast(editor.GetPointer());
+ mitk::IRenderingManager* renderingManager = renderEditor == nullptr ? nullptr : renderEditor->GetRenderingManager();
+
+ if (dsmodified && renderingManager)
+ {
+ mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage);
+ }
+ }
+ catch (const berry::PartInitException& e)
+ {
+ QString msg = "An error occurred when displaying the file(s): %1";
+ QMessageBox::warning(QApplication::activeWindow(), "Error displaying file",
+ msg.arg(e.message()));
}
- }
- catch (const berry::PartInitException& e)
- {
- QString msg = "An error occurred when displaying the file(s): %1";
- QMessageBox::warning(QApplication::activeWindow(), "Error displaying file",
- msg.arg(e.message()));
}
}
-}
-
-berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page,
- berry::IEditorInput::Pointer input,
- const QString &editorId, bool activate)
-{
- // sanity checks
- if (page.IsNull())
+
+ berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page, berry::IEditorInput::Pointer input, const QString &editorId, bool activate)
{
- throw std::invalid_argument("page argument must not be nullptr");
+ // sanity checks
+ if (page.IsNull())
+ {
+ throw std::invalid_argument("page argument must not be nullptr");
+ }
+
+ // open the editor on the input
+ return page->OpenEditor(input, editorId, activate);
}
- // open the editor on the input
- return page->OpenEditor(input, editorId, activate);
-}
-
-berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page,
- mitk::DataStorageEditorInput::Pointer input,
- bool activate,
- bool determineContentType)
-{
- // sanity checks
- if (page.IsNull())
+ berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page, mitk::DataStorageEditorInput::Pointer input, bool activate, bool determineContentType)
{
- throw std::invalid_argument("page argument must not be nullptr");
+ // sanity checks
+ if (page.IsNull())
+ {
+ throw std::invalid_argument("page argument must not be nullptr");
+ }
+
+ // open the editor on the data storage
+ QString name = input->GetName() + ".mitk";
+ berry::IEditorDescriptor::Pointer editorDesc = WorkbenchUtilPrivate::GetEditorDescriptor(name,
+ berry::PlatformUI::GetWorkbench()->GetEditorRegistry(),
+ GetDefaultEditor(name, determineContentType));
+
+ return page->OpenEditor(input, editorDesc->GetId(), activate);
}
- // open the editor on the data storage
- QString name = input->GetName() + ".mitk";
- berry::IEditorDescriptor::Pointer editorDesc =
- WorkbenchUtilPrivate::GetEditorDescriptor(name,
- berry::PlatformUI::GetWorkbench()->GetEditorRegistry(),
- GetDefaultEditor(name, determineContentType));
- return page->OpenEditor(input, editorDesc->GetId(), activate);
-}
-
-berry::IEditorDescriptor::Pointer WorkbenchUtil::GetEditorDescriptor(
- const QString& name, bool /*inferContentType*/)
-{
- if (name.isEmpty())
+ berry::IEditorDescriptor::Pointer WorkbenchUtil::GetEditorDescriptor(const QString& name, bool /*inferContentType*/)
{
- throw std::invalid_argument("name argument must not be empty");
- }
+ if (name.isEmpty())
+ {
+ throw std::invalid_argument("name argument must not be empty");
+ }
- // no used for now
- //IContentType contentType = inferContentType ? Platform
- // .getContentTypeManager().findContentTypeFor(name) : null;
+ // no used for now
+ //IContentType contentType = inferContentType ? Platform
+ // .getContentTypeManager().findContentTypeFor(name) : null;
- berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry();
+ berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry();
- return WorkbenchUtilPrivate::GetEditorDescriptor(name, editorReg,
- editorReg->GetDefaultEditor(name /*, contentType*/));
-}
+ return WorkbenchUtilPrivate::GetEditorDescriptor(name, editorReg, editorReg->GetDefaultEditor(name /*, contentType*/));
+ }
-berry::IEditorDescriptor::Pointer WorkbenchUtil::GetDefaultEditor(const QString& name,
- bool /*determineContentType*/)
-{
- // Try file specific editor.
- berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry();
- try
+ berry::IEditorDescriptor::Pointer WorkbenchUtil::GetDefaultEditor(const QString& name, bool /*determineContentType*/)
{
- QString editorID; // = file.getPersistentProperty(EDITOR_KEY);
- if (!editorID.isEmpty())
+ // Try file specific editor.
+ berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry();
+ try
{
- berry::IEditorDescriptor::Pointer desc = editorReg->FindEditor(editorID);
- if (desc.IsNotNull())
+ QString editorID; // = file.getPersistentProperty(EDITOR_KEY);
+ if (!editorID.isEmpty())
{
- return desc;
+ berry::IEditorDescriptor::Pointer desc = editorReg->FindEditor(editorID);
+ if (desc.IsNotNull())
+ {
+ return desc;
+ }
}
}
- }
- catch (const berry::CoreException&)
- {
- // do nothing
- }
+ catch (const berry::CoreException&)
+ {
+ // do nothing
+ }
-// IContentType contentType = null;
-// if (determineContentType)
-// {
-// contentType = getContentType(file);
-// }
+ // IContentType contentType = null;
+ // if (determineContentType)
+ // {
+ // contentType = getContentType(file);
+ // }
- // Try lookup with filename
- return editorReg->GetDefaultEditor(name); //, contentType);
-}
+ // Try lookup with filename
+ return editorReg->GetDefaultEditor(name); //, contentType);
+ }
-bool WorkbenchUtil::SetDepartmentLogoPreference(const QString &logoResource, ctkPluginContext *context)
-{
- if (context == nullptr)
+ mitk::IRenderWindowPart* WorkbenchUtil::GetRenderWindowPart(berry::IWorkbenchPage::Pointer page, IRenderWindowPartStrategies strategies)
{
- BERRY_WARN << "Plugin context invalid, unable to set custom logo.";
- return false;
- }
+ // Return the active editor if it implements mitk::IRenderWindowPart
+ mitk::IRenderWindowPart* renderWindowPart = dynamic_cast(page->GetActiveEditor().GetPointer());
+ if (renderWindowPart)
+ {
+ return renderWindowPart;
+ }
- // The logo must be available in the local filesystem. We check if we have not already extracted the
- // logo from the plug-in or if this plug-ins timestamp is newer then the already extracted logo timestamp.
- // If one of the conditions is true, extract it and write it to the plug-in specific storage location.
- const QString logoFileName = logoResource.mid(logoResource.lastIndexOf('/')+1);
+ // No suitable active editor found, check visible editors
+ QList editors = page->GetEditorReferences();
+ for (QList::iterator i = editors.begin(); i != editors.end(); ++i)
+ {
+ berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false);
+ if (page->IsPartVisible(part))
+ {
+ renderWindowPart = dynamic_cast(part.GetPointer());
+ if (renderWindowPart)
+ {
+ return renderWindowPart;
+ }
+ }
+ }
- if (logoFileName.isEmpty())
- {
- BERRY_WARN << "Logo file name empty, unable to set custom logo.";
- return false;
- }
+ // No suitable visible editor found, check visible views
+ QList views = page->GetViewReferences();
+ for (QList::iterator i = views.begin(); i != views.end(); ++i)
+ {
+ berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false);
+ if (page->IsPartVisible(part))
+ {
+ renderWindowPart = dynamic_cast(part.GetPointer());
+ if (renderWindowPart)
+ {
+ return renderWindowPart;
+ }
+ }
+ }
- const QString logoPath = context->getDataFile("").absoluteFilePath();
+ // No strategies given
+ if (strategies == NONE)
+ {
+ return nullptr;
+ }
- bool extractLogo = true;
- QFileInfo logoFileInfo(logoPath + "/" + logoFileName);
+ mitk::IDataStorageReference::Pointer dataStorageReference = WorkbenchUtilPrivate::GetDataStorageReference();
+ if (nullptr == dataStorageReference)
+ {
+ return nullptr;
+ }
- if (logoFileInfo.exists())
- {
- // The logo has been extracted previously. Check if the plugin timestamp is newer, which
- // means it might contain an updated logo.
- QString pluginLocation = QUrl(context->getPlugin()->getLocation()).toLocalFile();
- if (!pluginLocation.isEmpty())
+ mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(dataStorageReference));
+
+ bool activate = false;
+ if (strategies & ACTIVATE)
+ {
+ activate = true;
+ }
+
+ berry::IEditorPart::Pointer editorPart;
+ if (strategies & OPEN)
{
- QFileInfo pluginFileInfo(pluginLocation);
- if (logoFileInfo.lastModified() > pluginFileInfo.lastModified())
+ // This will create a default editor for the given input. If an editor
+ // with that input is already open, the editor is brought to the front.
+ try
{
- extractLogo = false;
+ editorPart = mitk::WorkbenchUtil::OpenEditor(page, input, activate);
+ }
+ catch (const berry::PartInitException&)
+ {
+ // There is no editor registered which can handle the given input.
+ }
+ }
+ else if (activate || (strategies & BRING_TO_FRONT))
+ {
+ // check if a suitable editor is already opened
+ editorPart = page->FindEditor(input);
+ if (editorPart)
+ {
+ if (activate)
+ {
+ page->Activate(editorPart);
+ }
+ else
+ {
+ page->BringToTop(editorPart);
+ }
}
}
+
+ return dynamic_cast(editorPart.GetPointer());
}
- if (extractLogo)
+ mitk::IRenderWindowPart* WorkbenchUtil::OpenRenderWindowPart(berry::IWorkbenchPage::Pointer page, bool activatedEditor/* = true*/)
{
- // Extract the logo from the shared library and write it to disk.
- QFile logo(logoResource);
+ if (activatedEditor)
+ {
+ return GetRenderWindowPart(page, ACTIVATE | OPEN);
+ }
+ else
+ {
+ return GetRenderWindowPart(page, BRING_TO_FRONT | OPEN);
+ }
+ }
- if (!logo.exists())
+ bool WorkbenchUtil::SetDepartmentLogoPreference(const QString &logoResource, ctkPluginContext *context)
+ {
+ if (context == nullptr)
{
- BERRY_WARN << "Custom logo '" << logoResource << "' does not exist.";
+ BERRY_WARN << "Plugin context invalid, unable to set custom logo.";
return false;
}
- if (logo.open(QIODevice::ReadOnly))
+ // The logo must be available in the local filesystem. We check if we have not already extracted the
+ // logo from the plug-in or if this plug-ins timestamp is newer then the already extracted logo timestamp.
+ // If one of the conditions is true, extract it and write it to the plug-in specific storage location.
+ const QString logoFileName = logoResource.mid(logoResource.lastIndexOf('/') + 1);
+
+ if (logoFileName.isEmpty())
{
- QFile localLogo(logoPath + "/" + logoFileName);
+ BERRY_WARN << "Logo file name empty, unable to set custom logo.";
+ return false;
+ }
- if (localLogo.open(QIODevice::WriteOnly))
+ const QString logoPath = context->getDataFile("").absoluteFilePath();
+
+ bool extractLogo = true;
+ QFileInfo logoFileInfo(logoPath + "/" + logoFileName);
+
+ if (logoFileInfo.exists())
+ {
+ // The logo has been extracted previously. Check if the plugin timestamp is newer, which
+ // means it might contain an updated logo.
+ QString pluginLocation = QUrl(context->getPlugin()->getLocation()).toLocalFile();
+ if (!pluginLocation.isEmpty())
{
- localLogo.write(logo.readAll());
- localLogo.flush();
+ QFileInfo pluginFileInfo(pluginLocation);
+ if (logoFileInfo.lastModified() > pluginFileInfo.lastModified())
+ {
+ extractLogo = false;
+ }
}
}
- }
- logoFileInfo.refresh();
-
- if (logoFileInfo.exists())
- {
- // Get the preferences service
- ctkServiceReference prefServiceRef = context->getServiceReference();
- berry::IPreferencesService* prefService = nullptr;
- if (prefServiceRef)
+ if (extractLogo)
{
- prefService = context->getService(prefServiceRef);
+ // Extract the logo from the shared library and write it to disk.
+ QFile logo(logoResource);
+
+ if (!logo.exists())
+ {
+ BERRY_WARN << "Custom logo '" << logoResource << "' does not exist.";
+ return false;
+ }
+
+ if (logo.open(QIODevice::ReadOnly))
+ {
+ QFile localLogo(logoPath + "/" + logoFileName);
+
+ if (localLogo.open(QIODevice::WriteOnly))
+ {
+ localLogo.write(logo.readAll());
+ localLogo.flush();
+ }
+ }
}
- if (prefService)
+ logoFileInfo.refresh();
+
+ if (logoFileInfo.exists())
{
- prefService->GetSystemPreferences()->Put("DepartmentLogo", qPrintable(logoFileInfo.absoluteFilePath()));
+ // Get the preferences service
+ ctkServiceReference prefServiceRef = context->getServiceReference();
+ berry::IPreferencesService* prefService = nullptr;
+ if (prefServiceRef)
+ {
+ prefService = context->getService(prefServiceRef);
+ }
+
+ if (prefService)
+ {
+ prefService->GetSystemPreferences()->Put("DepartmentLogo", qPrintable(logoFileInfo.absoluteFilePath()));
+ }
+ else
+ {
+ BERRY_WARN << "Preferences service not available, unable to set custom logo.";
+ return false;
+ }
}
else
{
- BERRY_WARN << "Preferences service not available, unable to set custom logo.";
+ BERRY_WARN << "Custom logo at '" << logoFileInfo.absoluteFilePath().toStdString() << "' does not exist.";
return false;
}
- }
- else
- {
- BERRY_WARN << "Custom logo at '" << logoFileInfo.absoluteFilePath().toStdString() << "' does not exist.";
- return false;
- }
- return true;
-}
+ return true;
+ }
} // namespace mitk
diff --git a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h
index b3dc8a8e86..238d8fc94d 100644
--- a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h
+++ b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h
@@ -1,189 +1,214 @@
/*===================================================================
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 MITKWORKBENCHUTIL_H
#define MITKWORKBENCHUTIL_H
#include
#include "mitkDataStorageEditorInput.h"
+#include "mitkIRenderWindowPart.h"
+
#include
#include
class ctkPluginContext;
namespace mitk {
-
-/**
- * @ingroup org_mitk_gui_common
- *
- * @brief Utility class for loading data, opening editors and other tasks in a MITK Workbench.
- *
- * @note Infering the content type is not yet supported (ignore the comments about it
- * in the method documentation).
- */
-struct MITK_GUI_COMMON_PLUGIN WorkbenchUtil
-{
-
/**
- * Loads the set of given files into the active data storage of the given Workbench window.
- *
- * If the window already has an editor open on the active datastorage then that editor
- * is activated; otherwise the default editor for the "mitk" extension is activated.
+ * @ingroup org_mitk_gui_common
*
- * @param fileNames
- * A list of file names with absolute path.
- * @param wnd
- * The Workbench window in which the data will be loaded.
- * @param openEditor
- * Whether an Editor is to be opened on file loading (for cases there is none).
+ * @brief Utility class for loading data, opening editors and other tasks in a MITK Workbench.
*
- * @see mitk::IOUtil
+ * @note Inferring the content type is not yet supported (ignore the comments about it
+ * in the method documentation).
*/
- static void LoadFiles(const QStringList& fileNames, berry::IWorkbenchWindow::Pointer wnd, bool openEditor = true);
-
- /**
+ struct MITK_GUI_COMMON_PLUGIN WorkbenchUtil
+ {
+ /**
+ * Describes the strategies to be used for getting an mitk::IRenderWindowPart instance.
+ */
+ enum IRenderWindowPartStrategy {
+
+ // Do nothing.
+ NONE = 0x00000000,
+ // Bring the most recently activated mitk::IRenderWindowPart instance to the front.
+ BRING_TO_FRONT = 0x00000001,
+ // Activate an mitk::IRenderWindowPart part (implies bringing it to the front).
+ ACTIVATE = 0x00000002,
+ // Create an mitk::IRenderWindowPart if none is alredy opened.
+ OPEN = 0x00000004
+ };
+
+ Q_DECLARE_FLAGS(IRenderWindowPartStrategies, IRenderWindowPartStrategy)
+
+ /**
+ * Loads the set of given files into the active data storage of the given Workbench window.
+ *
+ * If the window already has an editor open on the active datastorage then that editor
+ * is activated; otherwise the default editor for the "mitk" extension is activated.
+ *
+ * @param fileNames
+ * A list of file names with absolute path.
+ * @param wnd
+ * The Workbench window in which the data will be loaded.
+ * @param openEditor
+ * Whether an Editor is to be opened on file loading (for cases there is none).
+ *
+ * @see mitk::IOUtil
+ */
+ static void LoadFiles(const QStringList& fileNames, berry::IWorkbenchWindow::Pointer wnd, bool openEditor = true);
+ /**
* Opens an editor on the given object.
*
* If the page already has an editor open on the target object then that
* editor is brought to front; otherwise, a new editor is opened. If
* activate == true
the editor will be activated.
*
*
* @param page
* the page in which the editor will be opened
* @param input
* the editor input
* @param editorId
* the id of the editor extension to use
* @param activate
* if true
the editor will be activated
* @return an open editor or null
if an external editor was
* opened
* @exception PartInitException
* if the editor could not be initialized
* @see IWorkbenchPage#OpenEditor(IEditorInput::Pointer, std::string, bool)
*/
- static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page,
- berry::IEditorInput::Pointer input,
- const QString& editorId, bool activate = false);
-
- /**
+ static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page, berry::IEditorInput::Pointer input, const QString& editorId, bool activate = false);
+ /**
* Opens an editor on the given file resource. This method will attempt to
* resolve the editor based on content-type bindings as well as traditional
* name/extension bindings if determineContentType
is
* true
.
*
* If the page already has an editor open on the target object then that
* editor is brought to front; otherwise, a new editor is opened. If
* activate == true
the editor will be activated.
*
*
* @param page
* the page in which the editor will be opened
* @param input
* the editor input
* @param activate
* if true
the editor will be activated
* @param determineContentType
* attempt to resolve the content type for this file
* @return an open editor or null
if an external editor was
* opened
* @exception PartInitException
* if the editor could not be initialized
* @see IWorkbenchPage#OpenEditor(IEditorInput::Pointer,std::string,bool)
*/
- static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page,
- mitk::DataStorageEditorInput::Pointer input,
- bool activate = false,
- bool determineContentType = false);
-
- /**
+ static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page, DataStorageEditorInput::Pointer input, bool activate = false, bool determineContentType = false);
+ /**
* Returns an editor descriptor appropriate for opening a file resource with
* the given name.
*
* The editor descriptor is determined using a multi-step process. This
* method will attempt to infer the content type of the file if
* inferContentType
is true
.
*
*
* - The file is consulted for a persistent property named
*
IDE.EDITOR_KEY
containing the preferred editor id to be
* used.
* - The workbench editor registry is consulted to determine if an editor
* extension has been registered for the file type. If so, an instance of
* the editor extension is opened on the file. See
*
IEditorRegistry#GetDefaultEditor(std::string)
.
* - The operating system is consulted to determine if an in-place
* component editor is available (e.g. OLE editor on Win32 platforms).
* - The operating system is consulted to determine if an external editor
* is available.
*
*
*
* @param name
* the file name
* @param inferContentType
* attempt to infer the content type from the file name if this
* is true
* @return an editor descriptor, appropriate for opening the file
* @throws PartInitException
* if no editor can be found
*/
- static berry::IEditorDescriptor::Pointer GetEditorDescriptor(
- const QString& name, bool inferContentType = true);
-
- /**
+ static berry::IEditorDescriptor::Pointer GetEditorDescriptor(const QString& name, bool inferContentType = true);
+ /**
* Returns the default editor for a given file. This method will attempt to
* resolve the editor based on content-type bindings as well as traditional
* name/extension bindings if determineContentType
is
* true
.
*
* A default editor id may be registered for a specific file using
* setDefaultEditor
. If the given file has a registered
* default editor id the default editor will derived from it. If not, the
* default editor is determined by taking the file name for the file and
* obtaining the default editor for that name.
*
*
* @param file
* the file
* @param determineContentType
* determine the content type for the given file
* @return the descriptor of the default editor, or null
if
* not found
*/
- static berry::IEditorDescriptor::Pointer GetDefaultEditor(const QString& file,
- bool determineContentType);
- /**
- * Set the "DepartmentLogo" preference using a Qt resource path.
- *
- * This is a convenience method to set the preference for a "deparment" logo which is usually
- * shown in render windows in the MITK workbench.
- *
- * @param logoResource A Qt resource path to the logo, e.g. ":/MyLogo.png".
- * @param context The plugin context of the plug-in containing the logo resource.
- * @return \c true if the preference was set successfully, \c false otherwise.
- */
- static bool SetDepartmentLogoPreference(const QString& logoResource, ctkPluginContext* context);
-
-};
-
+ static berry::IEditorDescriptor::Pointer GetDefaultEditor(const QString& file, bool determineContentType);
+ /**
+ * @brief Returns the currently active mitk::IRenderWindowPart.
+ *
+ * @param page The page in which the editor will be opened.
+ * @param strategies Strategies for returning a mitk::IRenderWindowPart instance if there
+ * is currently no active one.
+ * @return The active mitk::IRenderWindowPart.
+ */
+ static IRenderWindowPart* GetRenderWindowPart(berry::IWorkbenchPage::Pointer page, IRenderWindowPartStrategies strategies);
+ /**
+ * @brief Uses 'GetRenderWindowPart' to open the a render window part with a certain strategy:
+ * Calls 'GetRenderWindowPart' with strategy "ACTIVATE | OPEN" if the bool argument is true.
+ * Calls 'GetRenderWindowPart' with strategy "BRING_TO_FRONT | OPEN" if the bool argument is false.
+ *
+ * @param page The page in which the editor will be opened.
+ * @param activatedEditor Determine if the render window part should be activated or just brought to front.
+ * @return The active and opened mitk::IRenderWindowPart.
+ */
+ static IRenderWindowPart* OpenRenderWindowPart(berry::IWorkbenchPage::Pointer page, bool activatedEditor = true);
+ /**
+ * Set the "DepartmentLogo" preference using a Qt resource path.
+ *
+ * This is a convenience method to set the preference for a "department" logo which is usually
+ * shown in render windows in the MITK workbench.
+ *
+ * @param logoResource A Qt resource path to the logo, e.g. ":/MyLogo.png".
+ * @param context The plugin context of the plug-in containing the logo resource.
+ * @return \c true if the preference was set successfully, \c false otherwise.
+ */
+ static bool SetDepartmentLogoPreference(const QString& logoResource, ctkPluginContext* context);
+ };
}
+Q_DECLARE_OPERATORS_FOR_FLAGS(mitk::WorkbenchUtil::IRenderWindowPartStrategies)
+
#endif // MITKWORKBENCHUTIL_H
diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp
index 33c8bf4dd2..fc92092b26 100644
--- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp
+++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp
@@ -1,602 +1,526 @@
/*===================================================================
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 "QmitkAbstractView.h"
#include "QmitkDataNodeSelectionProvider.h"
#include "internal/QmitkCommonActivator.h"
#include "internal/QmitkDataNodeItemModel.h"
// mitk Includes
#include
#include
#include
-#include
#include
#include
// berry Includes
#include
#include
#include
#include
#include
// CTK Includes
#include
// Qt Includes
#include
#include
#include
#include
#include
class QmitkAbstractViewPrivate
{
public:
QmitkAbstractViewPrivate(QmitkAbstractView* qq)
: q(qq)
, m_PrefServiceTracker(QmitkCommonActivator::GetContext())
, m_DataStorageServiceTracker(QmitkCommonActivator::GetContext())
, m_Parent(nullptr)
, m_DataNodeItemModel(new QmitkDataNodeItemModel)
, m_DataNodeSelectionModel(new QItemSelectionModel(m_DataNodeItemModel))
, m_InDataStorageChanged(false)
{
m_PrefServiceTracker.open();
m_DataStorageServiceTracker.open();
}
~QmitkAbstractViewPrivate()
{
delete m_DataNodeSelectionModel;
delete m_DataNodeItemModel;
m_PrefServiceTracker.close();
m_DataStorageServiceTracker.close();
}
/**
* Called when a DataStorage Add Event was thrown. Sets
* m_InDataStorageChanged to true and calls NodeAdded afterwards.
* \see m_InDataStorageChanged
*/
void NodeAddedProxy(const mitk::DataNode* node)
{
// garantuee no recursions when a new node event is thrown in NodeAdded()
if(!m_InDataStorageChanged)
{
m_InDataStorageChanged = true;
q->NodeAdded(node);
q->DataStorageModified();
m_InDataStorageChanged = false;
}
}
/**
* Called when a DataStorage remove event was thrown. Sets
* m_InDataStorageChanged to true and calls NodeRemoved afterwards.
* \see m_InDataStorageChanged
*/
void NodeRemovedProxy(const mitk::DataNode* node)
{
// garantuee no recursions when a new node event is thrown in NodeAdded()
if(!m_InDataStorageChanged)
{
m_InDataStorageChanged = true;
q->NodeRemoved(node);
q->DataStorageModified();
m_InDataStorageChanged = false;
}
}
/**
* Called when a DataStorage changed event was thrown. Sets
* m_InDataStorageChanged to true and calls NodeChanged afterwards.
* \see m_InDataStorageChanged
*/
void NodeChangedProxy(const mitk::DataNode* node)
{
// garantuee no recursions when a new node event is thrown in NodeAdded()
if(!m_InDataStorageChanged)
{
m_InDataStorageChanged = true;
q->NodeChanged(node);
q->DataStorageModified();
m_InDataStorageChanged = false;
}
}
/**
* reactions to selection events from views
*/
void BlueBerrySelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart,
const berry::ISelection::ConstPointer& selection)
{
if(sourcepart.IsNull() || sourcepart.GetPointer() == static_cast(q))
return;
if(selection.IsNull())
{
q->OnNullSelection(sourcepart);
return;
}
mitk::DataNodeSelection::ConstPointer _DataNodeSelection
= selection.Cast();
q->OnSelectionChanged(sourcepart, this->DataNodeSelectionToQList(_DataNodeSelection));
}
/**
* Converts a mitk::DataNodeSelection to a QList (possibly empty)
*/
QList DataNodeSelectionToQList(mitk::DataNodeSelection::ConstPointer currentSelection) const;
QmitkAbstractView* const q;
ctkServiceTracker m_PrefServiceTracker;
ctkServiceTracker m_DataStorageServiceTracker;
/**
* Saves the parent of this view (this is the scrollarea created in CreatePartControl(QWidget*)
* \see CreatePartControl(QWidget*)
*/
QWidget* m_Parent;
/**
* Holds the current selection (selection made by this View !!!)
*/
QmitkDataNodeSelectionProvider::Pointer m_SelectionProvider;
/**
* Holds a helper model for firing selection events.
*/
QmitkDataNodeItemModel* m_DataNodeItemModel;
/**
* The selection model for the QmitkDataNodeItemModel;
*/
QItemSelectionModel* m_DataNodeSelectionModel;
/**
* object to observe BlueBerry selections
*/
QScopedPointer m_BlueBerrySelectionListener;
/**
* Saves if this class is currently working on DataStorage changes.
* This is a protector variable to avoid recursive calls on event listener functions.
*/
bool m_InDataStorageChanged;
};
QmitkAbstractView::QmitkAbstractView()
: d(new QmitkAbstractViewPrivate(this))
{
}
void QmitkAbstractView::CreatePartControl(QWidget* parent)
{
// scrollArea
auto scrollArea = new QScrollArea;
//QVBoxLayout* scrollAreaLayout = new QVBoxLayout(scrollArea);
scrollArea->setFrameShadow(QFrame::Plain);
scrollArea->setFrameShape(QFrame::NoFrame);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
// m_Parent
d->m_Parent = new QWidget;
//m_Parent->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
this->CreateQtPartControl(d->m_Parent);
//scrollAreaLayout->addWidget(m_Parent);
//scrollArea->setLayout(scrollAreaLayout);
// set the widget now
scrollArea->setWidgetResizable(true);
scrollArea->setWidget(d->m_Parent);
// add the scroll area to the real parent (the view tabbar)
QWidget* parentQWidget = static_cast(parent);
auto parentLayout = new QVBoxLayout(parentQWidget);
parentLayout->setMargin(0);
parentLayout->setSpacing(0);
parentLayout->addWidget(scrollArea);
// finally set the layout containing the scroll area to the parent widget (= show it)
parentQWidget->setLayout(parentLayout);
this->AfterCreateQtPartControl();
}
void QmitkAbstractView::AfterCreateQtPartControl()
{
this->SetSelectionProvider();
// REGISTER DATASTORAGE LISTENER
this->GetDataStorage()->AddNodeEvent.AddListener( mitk::MessageDelegate1
( d.data(), &QmitkAbstractViewPrivate::NodeAddedProxy ) );
this->GetDataStorage()->ChangedNodeEvent.AddListener( mitk::MessageDelegate1
( d.data(), &QmitkAbstractViewPrivate::NodeChangedProxy ) );
this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1
( d.data(), &QmitkAbstractViewPrivate::NodeRemovedProxy ) );
// REGISTER PREFERENCES LISTENER
berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast();
if(prefs.IsNotNull())
prefs->OnChanged.AddListener(
berry::MessageDelegate1(this,
&QmitkAbstractView::OnPreferencesChanged));
// REGISTER FOR WORKBENCH SELECTION EVENTS
d->m_BlueBerrySelectionListener.reset(new berry::NullSelectionChangedAdapter(
d.data(), &QmitkAbstractViewPrivate::BlueBerrySelectionChanged));
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(d->m_BlueBerrySelectionListener.data());
// EMULATE INITIAL SELECTION EVENTS
// send the current selection
berry::IWorkbenchPart::Pointer activePart = this->GetSite()->GetPage()->GetActivePart();
if (activePart.IsNotNull())
{
this->OnSelectionChanged(activePart, this->GetCurrentSelection());
}
// send preferences changed event
this->OnPreferencesChanged(this->GetPreferences().Cast().GetPointer());
}
QmitkAbstractView::~QmitkAbstractView()
{
this->Register();
this->GetDataStorage()->AddNodeEvent.RemoveListener( mitk::MessageDelegate1
( d.data(), &QmitkAbstractViewPrivate::NodeAddedProxy ) );
this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1
( d.data(), &QmitkAbstractViewPrivate::NodeRemovedProxy) );
this->GetDataStorage()->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1
( d.data(), &QmitkAbstractViewPrivate::NodeChangedProxy ) );
berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast();
if(prefs.IsNotNull())
{
prefs->OnChanged.RemoveListener(
berry::MessageDelegate1(this,
&QmitkAbstractView::OnPreferencesChanged));
// flush the preferences here (disabled, everyone should flush them by themselves at the right moment)
// prefs->Flush();
}
// REMOVE SELECTION PROVIDER
this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(nullptr));
berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
if(s)
{
s->RemovePostSelectionListener(d->m_BlueBerrySelectionListener.data());
}
this->UnRegister(false);
}
void QmitkAbstractView::SetSelectionProvider()
{
// REGISTER A SELECTION PROVIDER
d->m_SelectionProvider = QmitkDataNodeSelectionProvider::Pointer(new QmitkDataNodeSelectionProvider);
d->m_SelectionProvider->SetItemSelectionModel(GetDataNodeSelectionModel());
this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(d->m_SelectionProvider));
}
QItemSelectionModel *QmitkAbstractView::GetDataNodeSelectionModel() const
{
return nullptr;
}
void QmitkAbstractView::OnPreferencesChanged( const berry::IBerryPreferences* )
{
}
void QmitkAbstractView::DataStorageModified()
{
}
void QmitkAbstractView::DataStorageChanged(mitk::IDataStorageReference::Pointer /*dsRef*/)
{
}
-mitk::IRenderWindowPart* QmitkAbstractView::GetRenderWindowPart( IRenderWindowPartStrategies strategies ) const
+mitk::IRenderWindowPart* QmitkAbstractView::GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategies strategies) const
{
- berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage();
-
- // Return the active editor if it implements mitk::IRenderWindowPart
- mitk::IRenderWindowPart* renderPart =
- dynamic_cast(page->GetActiveEditor().GetPointer());
- if (renderPart) return renderPart;
-
- // No suitable active editor found, check visible editors
- QList editors = page->GetEditorReferences();
- for (QList::iterator i = editors.begin();
- i != editors.end(); ++i)
- {
- berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false);
- if (page->IsPartVisible(part))
- {
- renderPart = dynamic_cast(part.GetPointer());
- if (renderPart) return renderPart;
- }
- }
-
- // No suitable visible editor found, check visible views
- QList views = page->GetViewReferences();
- for(QList::iterator i = views.begin();
- i != views.end(); ++i)
- {
- berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false);
- if (page->IsPartVisible(part))
- {
- renderPart = dynamic_cast(part.GetPointer());
- if (renderPart) return renderPart;
- }
- }
-
- // No strategies given
- if (strategies == NONE) return nullptr;
-
- mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(GetDataStorageReference()));
-
- bool activate = false;
- if(strategies & ACTIVATE)
- {
- activate = true;
- }
-
- berry::IEditorPart::Pointer editorPart;
-
- if(strategies & OPEN)
- {
- // This will create a default editor for the given input. If an editor
- // with that input is already open, the editor is brought to the front.
- try
- {
- editorPart = mitk::WorkbenchUtil::OpenEditor(page, input, activate);
- }
- catch (const berry::PartInitException&)
- {
- // There is no editor registered which can handle the given input.
- }
- }
- else if (activate || (strategies & BRING_TO_FRONT))
- {
- // check if a suitable editor is already opened
- editorPart = page->FindEditor(input);
- if (editorPart)
- {
- if (activate)
- {
- page->Activate(editorPart);
- }
- else
- {
- page->BringToTop(editorPart);
- }
- }
- }
-
- return dynamic_cast(editorPart.GetPointer());
+ berry::IWorkbenchPage::Pointer page = GetSite()->GetPage();
+ return mitk::WorkbenchUtil::GetRenderWindowPart(page, strategies);
}
void QmitkAbstractView::RequestRenderWindowUpdate(mitk::RenderingManager::RequestType requestType)
{
mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart();
if (renderPart == nullptr) return;
if (mitk::IRenderingManager* renderingManager = renderPart->GetRenderingManager())
{
renderingManager->RequestUpdateAll(requestType);
}
else
{
renderPart->RequestUpdate(requestType);
}
}
void QmitkAbstractView::HandleException( const char* str, QWidget* parent, bool showDialog ) const
{
//itkGenericOutputMacro( << "Exception caught: " << str );
MITK_ERROR << str;
if ( showDialog )
{
QMessageBox::critical ( parent, "Exception caught!", str );
}
}
void QmitkAbstractView::HandleException( std::exception& e, QWidget* parent, bool showDialog ) const
{
HandleException( e.what(), parent, showDialog );
}
void QmitkAbstractView::WaitCursorOn()
{
QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
}
void QmitkAbstractView::BusyCursorOn()
{
QApplication::setOverrideCursor( QCursor(Qt::BusyCursor) );
}
void QmitkAbstractView::WaitCursorOff()
{
this->RestoreOverrideCursor();
}
void QmitkAbstractView::BusyCursorOff()
{
this->RestoreOverrideCursor();
}
void QmitkAbstractView::RestoreOverrideCursor()
{
QApplication::restoreOverrideCursor();
}
berry::IPreferences::Pointer QmitkAbstractView::GetPreferences() const
{
berry::IPreferencesService* prefService = d->m_PrefServiceTracker.getService();
// const_cast workaround for bad programming: const uncorrectness this->GetViewSite() should be const
QString id = "/" + (const_cast(this))->GetViewSite()->GetId();
return prefService ? prefService->GetSystemPreferences()->Node(id): berry::IPreferences::Pointer(nullptr);
}
mitk::DataStorage::Pointer
QmitkAbstractView::GetDataStorage() const
{
mitk::IDataStorageService* dsService = d->m_DataStorageServiceTracker.getService();
if (dsService != nullptr)
{
return dsService->GetDataStorage()->GetDataStorage();
}
return nullptr;
}
mitk::IDataStorageReference::Pointer QmitkAbstractView::GetDataStorageReference() const
{
mitk::IDataStorageService* dsService = d->m_DataStorageServiceTracker.getService();
if (dsService != nullptr)
{
return dsService->GetDataStorage();
}
return mitk::IDataStorageReference::Pointer(nullptr);
}
QList QmitkAbstractView::GetCurrentSelection() const
{
berry::ISelection::ConstPointer selection( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection());
mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast();
return d->DataNodeSelectionToQList(currentSelection);
}
bool QmitkAbstractView::IsCurrentSelectionValid() const
{
return this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection();
}
QList QmitkAbstractView::GetDataManagerSelection() const
{
berry::ISelection::ConstPointer selection( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast();
return d->DataNodeSelectionToQList(currentSelection);
}
bool QmitkAbstractView::IsDataManagerSelectionValid() const
{
return this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager");
}
void QmitkAbstractView::SetDataManagerSelection(const berry::ISelection::ConstPointer &selection,
QItemSelectionModel::SelectionFlags flags) const
{
berry::IViewPart::Pointer datamanagerView = this->GetSite()->GetWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.datamanager");
if (datamanagerView.IsNull()) return;
datamanagerView->GetSite()->GetSelectionProvider().Cast()->SetSelection(selection, flags);
}
void QmitkAbstractView::SynchronizeDataManagerSelection() const
{
berry::ISelection::ConstPointer currentSelection = this->GetSite()->GetSelectionProvider()->GetSelection();
if (currentSelection.IsNull()) return;
SetDataManagerSelection(currentSelection);
}
void QmitkAbstractView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/,
const QList& /*nodes*/)
{
}
void QmitkAbstractView::OnNullSelection(berry::IWorkbenchPart::Pointer /*part*/)
{
}
QList QmitkAbstractViewPrivate::DataNodeSelectionToQList(mitk::DataNodeSelection::ConstPointer currentSelection) const
{
if (currentSelection.IsNull()) return QList();
return QList::fromStdList(currentSelection->GetSelectedDataNodes());
}
void QmitkAbstractView::NodeAdded( const mitk::DataNode* /*node*/ )
{
}
void QmitkAbstractView::NodeRemoved( const mitk::DataNode* /*node*/ )
{
}
void QmitkAbstractView::NodeChanged( const mitk::DataNode* /*node*/ )
{
}
void QmitkAbstractView::FireNodeSelected( mitk::DataNode::Pointer node )
{
QList nodes;
nodes << node;
this->FireNodesSelected(nodes);
}
void QmitkAbstractView::FireNodesSelected( const QList& nodes )
{
// if this is the first call to FireNodesSelected and the selection provider has no QItemSelectiomMode
// yet, set our helper model
if (d->m_SelectionProvider->GetItemSelectionModel() == nullptr)
{
d->m_SelectionProvider->SetItemSelectionModel(d->m_DataNodeSelectionModel);
}
else if (d->m_SelectionProvider->GetItemSelectionModel() != d->m_DataNodeSelectionModel)
{
MITK_WARN << "A custom data node selection model has been set. Ignoring call to FireNodesSelected().";
return;
}
if (nodes.empty())
{
d->m_DataNodeSelectionModel->clearSelection();
d->m_DataNodeItemModel->clear();
}
else
{
// The helper data node model is just used for sending selection events.
// We add the to be selected nodes and set the selection range to everything.
d->m_DataNodeItemModel->clear();
foreach(mitk::DataNode::Pointer node, nodes)
{
d->m_DataNodeItemModel->AddDataNode(node);
}
d->m_DataNodeSelectionModel->select(QItemSelection(d->m_DataNodeItemModel->index(0,0), d->m_DataNodeItemModel->index(nodes.size()-1, 0)),
QItemSelectionModel::ClearAndSelect);
}
}
diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h
index d92f6560ad..75fff11011 100644
--- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h
+++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h
@@ -1,384 +1,366 @@
/*===================================================================
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 QMITKABSTRACTVIEW_H_
#define QMITKABSTRACTVIEW_H_
//# blueberry stuff
#include
#include
#include
#include
//# mitk stuff
#include
#include "mitkDataNodeSelection.h"
#include "mitkIRenderWindowPart.h"
+#include
+
#include
#include
#include
#include
namespace mitk {
class DataNode;
}
namespace berry {
struct IBerryPreferences;
}
class QmitkAbstractViewPrivate;
class QmitkAbstractViewSelectionProvider;
/**
* \ingroup org_mitk_gui_qt_common
*
* \brief A convenient base class for MITK related BlueBerry Views.
*
* QmitkAbstractView provides several convenience methods that ease the introduction of a new view:
*
*
* - Access to the DataStorage (~ the shared data repository)
*
- Access to the active IRenderWindowPart
*
- Access to and update notification for the view's preferences
*
- Access to and update notification for the current DataNode selection / to DataNode selection events send through the SelectionService
*
- Access to and update notification for DataNode events (added/removed/modified)
*
- Methods to send DataNode selections through the SelectionService
*
- Some minor important convenience methods (like changing the mouse cursor/exception handling)
*
*
* Usually all MITK Views inherit from QmitkAbstractView to achieve a consistent Workbench behavior.
*
* When inheriting from QmitkAbstractView, you must implement the following methods:
*
* - void CreateQtPartControl(QWidget* parent)
*
- void SetFocus()
*
*
* You may reimplement the following private virtual methods to customize your View's behavior:
*
* - void SetSelectionProvider()
*
- QItemSelectionModel* GetDataNodeSelectionModel() const
*
*
* You may reimplement the following private virtual methods to be notified about certain changes:
*
* - void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &nodes)
*
- void OnNullSelection(berry::IWorkbenchPart::Pointer part)
*
- void OnPreferencesChanged(const berry::IBerryPreferences*)
*
- void NodeAdded(const mitk::DataNode* node)
*
- void NodeChanged(const mitk::DataNode* node)
*
- void NodeRemoved(const mitk::DataNode* node)
*
- void DataStorageModified()
*
- void DataStorageChanged(mitk::IDataStorageReference::Pointer dsRef)
*
*
* \see mitk::ILifecycleAwarePart
* \see mitk::IZombieViewPart
* \see mitk::IRenderWindowPartListener
*/
class MITK_QT_COMMON QmitkAbstractView : public berry::QtViewPart
{
public:
- /**
- * Describes the strategies to be used for getting a mitk::IRenderWindowPart
- * instance.
- */
- enum IRenderWindowPartStrategy {
-
- /** Do nothing. */
- NONE = 0x00000000,
- /** Bring the most recently activated mitk::IRenderWindowPart instance to the front. */
- BRING_TO_FRONT = 0x00000001,
- /** Activate a mitk::IRenderWindowPart part (implies bringing it to the front). */
- ACTIVATE = 0x00000002,
- /** Create a mitk::IRenderWindowPart if none is alredy opened. */
- OPEN = 0x00000004
- };
-
- Q_DECLARE_FLAGS(IRenderWindowPartStrategies, IRenderWindowPartStrategy)
-
/**
* Creates smartpointer typedefs
*/
berryObjectMacro(QmitkAbstractView);
/**
* Nothing to do in the standard ctor. Initiliaze your GUI in CreateQtPartControl(QWidget*)
* \see berry::QtViewPart::CreateQtPartControl(QWidget*)
*/
QmitkAbstractView();
/**
* Disconnects all standard event listeners
*/
~QmitkAbstractView() override;
protected:
/**
* Informs other parts of the workbench that node is selected via the blueberry selection service.
*
* \note This method should not be used if you have set your own selection provider via
* SetSelectionProvider() or your own QItemSelectionModel via GetDataNodeSelectionModel().
*/
void FireNodeSelected(mitk::DataNode::Pointer node);
/**
* Informs other parts of the workbench that the nodes are selected via the blueberry selection service.
*
* \note This method should not be used if you have set your own selection provider via
* SetSelectionProvider() or your own QItemSelectionModel via GetDataNodeSelectionModel().
*/
virtual void FireNodesSelected(const QList& nodes);
/**
* \return The selection of the currently active part of the workbench or an empty list
* if there is no selection or if it is empty.
*
* \see IsCurrentSelectionValid
*/
QList GetCurrentSelection() const;
/**
* Queries the state of the current selection.
*
* \return If the current selection is nullptr
, this method returns
* false
and true
otherwise.
*/
bool IsCurrentSelectionValid() const;
/**
* Returns the current selection made in the datamanager bundle or an empty list
* if there is no selection or if it is empty.
*
* \see IsDataManagerSelectionValid
*/
QList GetDataManagerSelection() const;
/**
* Queries the state of the current selection of the data manager view.
*
* \return If the current data manager selection is nullptr
, this method returns
* false
and true
otherwise.
*/
bool IsDataManagerSelectionValid() const;
/**
* Sets the selection of the data manager view if available.
*
* \param selection The new selection for the data manager.
* \param flags The Qt selection flags for controlling the way how the selection is updated.
*/
void SetDataManagerSelection(const berry::ISelection::ConstPointer& selection,
QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::ClearAndSelect) const;
/**
* Takes the current selection and sets it on the data manager. Only matching nodes in the
* data manager view will be selected.
*/
void SynchronizeDataManagerSelection() const;
/**
* Returns the Preferences object for this View.
* Important: When refering to this preferences, e.g. in a PreferencePage: The ID
* for this preferences object is "/", e.g. "/org.mitk.views.datamanager"
*/
berry::IPreferences::Pointer GetPreferences() const;
/**
* Returns a reference to the currently active DataStorage.
*/
mitk::IDataStorageReference::Pointer GetDataStorageReference() const;
/**
* Returns the currently active DataStorage.
*/
mitk::DataStorage::Pointer GetDataStorage() const;
/**
* Returns the currently active mitk::IRenderWindowPart.
*
* \param strategies Strategies for returning a mitk::IRenderWindowPart instance if there
* is currently no active one.
* \return The active mitk::IRenderWindowPart.
*/
- mitk::IRenderWindowPart* GetRenderWindowPart(IRenderWindowPartStrategies strategies = NONE) const;
+ mitk::IRenderWindowPart* GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategies strategies = mitk::WorkbenchUtil::NONE) const;
/**
* Request an update of all render windows of the currently active IRenderWindowPart.
*
* \param requestType Specifies the type of render windows for which an update
* will be requested.
*/
void RequestRenderWindowUpdate(mitk::RenderingManager::RequestType requestType = mitk::RenderingManager::REQUEST_UPDATE_ALL);
/**
* Outputs an error message to the console and displays a message box containing
* the exception description.
* \param e the exception which should be handled
* \param showDialog controls, whether additionally a message box should be
* displayed to inform the user that something went wrong
*/
void HandleException( std::exception& e, QWidget* parent = nullptr, bool showDialog = true ) const;
/**
* Calls HandleException ( std::exception&, QWidget*, bool ) internally
* \see HandleException ( std::exception&, QWidget*, bool )
*/
void HandleException( const char* str, QWidget* parent = nullptr, bool showDialog = true ) const;
/**
* Convenient method to set and reset a wait cursor ("hourglass")
*/
void WaitCursorOn();
/**
* Convenient method to restore the standard cursor
*/
void WaitCursorOff();
/**
* Convenient method to set and reset a busy cursor
*/
void BusyCursorOn();
/**
* Convenient method to restore the standard cursor
*/
void BusyCursorOff();
/**
* Convenient method to restore the standard cursor
*/
void RestoreOverrideCursor();
private:
/**
* Reimplement this method to set a custom selection provider. This method is
* called once after CreateQtPartControl().
*
* The default implementation registers a QmitkDataNodeSelectionProvider with
* a QItemSelectionModel returned by GetDataNodeSelectionModel().
*/
virtual void SetSelectionProvider();
/**
* Reimplement this method to supply a custom Qt selection model. The custom
* model will be used with the default selection provider QmitkDataNodeSelectionProvider
* to inform the MITK Workbench about selection changes.
*
* If you reimplement this method, the methods FireNodeSelected() and FireNodesSelected()
* will have no effect. Use your custom selection model to notify the MITK Workbench
* about selection changes.
*
* The Qt item model used with the custom selection model must return mitk::DataNode::Pointer
* objects for model indexes when the role is QmitkDataNodeRole.
*/
virtual QItemSelectionModel* GetDataNodeSelectionModel() const;
/**
* Called when the selection in the workbench changed.
* May be reimplemented by deriving classes.
*
* \param part The source part responsible for the selection change.
* \param nodes A list of selected nodes.
*
* \see OnNullSelection
*/
virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &nodes);
/**
* Called when a nullptr
selection occurs.
*
* \param part The source part responsible for the selection change.
*/
virtual void OnNullSelection(berry::IWorkbenchPart::Pointer part);
/**
* Called when the preferences object of this view changed.
* May be reimplemented by deriving classes.
*
* \see GetPreferences()
*/
virtual void OnPreferencesChanged(const berry::IBerryPreferences*);
/**
* Called when a DataStorage Add event was thrown. May be reimplemented
* by deriving classes.
*/
virtual void NodeAdded(const mitk::DataNode* node);
/**
* Called when a DataStorage Changed event was thrown. May be reimplemented
* by deriving classes.
*/
virtual void NodeChanged(const mitk::DataNode* node);
/**
* Called when a DataStorage Remove event was thrown. May be reimplemented
* by deriving classes.
*/
virtual void NodeRemoved(const mitk::DataNode* node);
/**
* Called when a DataStorage add *or* remove *or* change event from the currently active
* data storage is thrown.
*
* May be reimplemented by deriving classes.
*/
virtual void DataStorageModified();
/**
* Called when the currently active DataStorage changed.
* May be reimplemented by deriving classes.
*
* \param dsRef A reference to the new active DataStorage.
*/
virtual void DataStorageChanged(mitk::IDataStorageReference::Pointer dsRef);
/**
* Creates a scroll area for this view and calls CreateQtPartControl then
*/
void CreatePartControl(QWidget* parent) override;
/**
* Called immediately after CreateQtPartControl().
* Here standard event listeners for a QmitkAbstractView are registered
*/
void AfterCreateQtPartControl();
private:
friend class QmitkAbstractViewPrivate;
friend class QmitkViewCoordinator;
Q_DISABLE_COPY(QmitkAbstractView)
const QScopedPointer d;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QmitkAbstractView::IRenderWindowPartStrategies)
-
#endif /*QMITKABSTRACTVIEW_H_*/
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
index 499f2adfe5..94f448a606 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
@@ -1,308 +1,296 @@
/*===================================================================
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 "QmitkDataManagerView.h"
// mitk gui qt datamanager
#include "src/internal/QmitkNodeTableViewKeyFilter.h"
#include "src/internal/QmitkInfoDialog.h"
#include "src/internal/QmitkDataManagerItemDelegate.h"
// mitk core
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// mitk core services plugin
#include
#include
// qt widgets module
#include
#include
#include
#include
#include
// beery plugins
#include
#include
#include
#include
#include
#include
#include
#include
#include
// mitk gui qt application plugin
#include
// qt
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// mitk gui common plugin
#include
#include
#include
// mitk gui qt common plugin
#include
const QString QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager";
QmitkDataManagerView::QmitkDataManagerView()
: m_GlobalReinitOnNodeDelete(true)
, m_GlobalReinitOnNodeVisibilityChanged(false)
, m_ItemDelegate(nullptr)
{
}
QmitkDataManagerView::~QmitkDataManagerView()
{
// nothing here
}
void QmitkDataManagerView::CreateQtPartControl(QWidget* parent)
{
m_CurrentRowCount = 0;
m_Parent = parent;
//# Preferences
berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService();
berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(VIEW_ID)).Cast();
assert(prefs);
prefs->OnChanged.AddListener(berry::MessageDelegate1(this, &QmitkDataManagerView::OnPreferencesChanged));
//# GUI
m_NodeTreeModel = new QmitkDataStorageTreeModel(GetDataStorage(), prefs->GetBool("Place new nodes on top", true));
m_NodeTreeModel->setParent(parent);
m_NodeTreeModel->SetAllowHierarchyChange(prefs->GetBool("Allow changing of parent node", false));
m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false);
// Prepare filters
m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New(
mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)),
mitk::NodePredicateProperty::New("hidden object", mitk::BoolProperty::New(true)));
m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(nullptr);
m_FilterModel = new QmitkDataStorageFilterProxyModel();
m_FilterModel->setSourceModel(m_NodeTreeModel);
m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate);
m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate);
//# Tree View (experimental)
m_NodeTreeView = new QTreeView;
m_NodeTreeView->setHeaderHidden(true);
m_NodeTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_NodeTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_NodeTreeView->setAlternatingRowColors(true);
m_NodeTreeView->setDragEnabled(true);
m_NodeTreeView->setDropIndicatorShown(true);
m_NodeTreeView->setAcceptDrops(true);
m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
m_NodeTreeView->setModel(m_FilterModel);
m_NodeTreeView->setTextElideMode(Qt::ElideMiddle);
m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this));
m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView);
m_NodeTreeView->setItemDelegate(m_ItemDelegate);
connect(m_NodeTreeModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(NodeTreeViewRowsInserted(const QModelIndex&, int, int)));
connect(m_NodeTreeModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(NodeTreeViewRowsRemoved(const QModelIndex&, int, int)));
connect(m_NodeTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(NodeSelectionChanged(const QItemSelection &, const QItemSelection &)));
connect(m_NodeTreeModel, &QmitkDataStorageTreeModel::nodeVisibilityChanged, this, &QmitkDataManagerView::OnNodeVisibilityChanged);
// data node context menu and menu actions
m_DataNodeContextMenu = new QmitkDataNodeContextMenu(GetSite(), m_NodeTreeView);
m_DataNodeContextMenu->SetDataStorage(GetDataStorage());
m_DataNodeContextMenu->SetSurfaceDecimation(m_SurfaceDecimation);
connect(m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)), m_DataNodeContextMenu, SLOT(OnContextMenuRequested(const QPoint&)));
berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry();
QList editors = editorRegistry->GetEditors("*.mitk");
if (editors.size() > 1)
{
m_ShowInMapper = new QSignalMapper(this);
foreach(berry::IEditorDescriptor::Pointer descriptor, editors)
{
QAction* action = new QAction(descriptor->GetLabel(), this);
m_ShowInActions << action;
m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map()));
m_ShowInMapper->setMapping(action, descriptor->GetId());
}
connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString)));
}
QGridLayout* dndFrameWidgetLayout = new QGridLayout;
dndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0);
dndFrameWidgetLayout->setContentsMargins(0, 0, 0, 0);
m_DnDFrameWidget = new QmitkDnDFrameWidget(m_Parent);
m_DnDFrameWidget->setLayout(dndFrameWidgetLayout);
QVBoxLayout* layout = new QVBoxLayout(parent);
layout->addWidget(m_DnDFrameWidget);
layout->setContentsMargins(0, 0, 0, 0);
m_Parent->setLayout(layout);
}
void QmitkDataManagerView::SetFocus()
{
}
void QmitkDataManagerView::NodeChanged(const mitk::DataNode* /*node*/)
{
// m_FilterModel->invalidate();
// fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014
QMetaObject::invokeMethod(m_FilterModel, "invalidate", Qt::QueuedConnection);
}
void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
{
if (m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true))
{
m_NodeTreeModel->SetPlaceNewNodesOnTop(!m_NodeTreeModel->GetPlaceNewNodesOnTopFlag());
}
bool hideHelperObjects = !prefs->GetBool("Show helper objects", false);
if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects)
{
if (hideHelperObjects)
{
m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate);
}
else
{
m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate);
}
}
bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false);
if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData)
{
if (hideNodesWithNoData)
{
m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate);
}
else
{
m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate);
}
}
m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true);
m_GlobalReinitOnNodeVisibilityChanged = prefs->GetBool("Call global reinit if node visibility is changed", false);
m_NodeTreeView->expandAll();
m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false);
m_DataNodeContextMenu->SetSurfaceDecimation(m_SurfaceDecimation);
m_NodeTreeModel->SetAllowHierarchyChange(prefs->GetBool("Allow changing of parent node", false));
GlobalReinitAction::Run(GetSite(), GetDataStorage());
}
//////////////////////////////////////////////////////////////////////////
// Node tree modification
//////////////////////////////////////////////////////////////////////////
void QmitkDataManagerView::NodeTreeViewRowsInserted(const QModelIndex& parent, int /*start*/, int /*end*/)
{
QModelIndex viewIndex = m_FilterModel->mapFromSource(parent);
m_NodeTreeView->setExpanded(viewIndex, true);
// a new row was inserted
if (m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1)
{
- OpenRenderWindowPart();
+ mitk::WorkbenchUtil::OpenRenderWindowPart(GetSite()->GetPage());
m_CurrentRowCount = m_NodeTreeModel->rowCount();
}
}
void QmitkDataManagerView::NodeTreeViewRowsRemoved(const QModelIndex& /*parent*/, int /*start*/, int /*end*/)
{
m_CurrentRowCount = m_NodeTreeModel->rowCount();
}
void QmitkDataManagerView::NodeSelectionChanged(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/)
{
auto selectedNodes = GetCurrentSelection();
auto nodeSet = m_NodeTreeModel->GetNodeSet();
for (auto node : nodeSet)
{
if (node.IsNotNull())
{
node->SetSelected(selectedNodes.contains(node));
}
}
}
void QmitkDataManagerView::OnNodeVisibilityChanged()
{
if (m_GlobalReinitOnNodeVisibilityChanged)
{
GlobalReinitAction::Run(GetSite(), GetDataStorage());
}
else
{
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkDataManagerView::ShowIn(const QString& editorId)
{
berry::IWorkbenchPage::Pointer page = GetSite()->GetPage();
berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(GetDataStorageReference()));
page->OpenEditor(input, editorId, false, berry::IWorkbenchPage::MATCH_ID);
}
QItemSelectionModel* QmitkDataManagerView::GetDataNodeSelectionModel() const
{
return m_NodeTreeView->selectionModel();
}
-
-mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor/* = true*/)
-{
- if (activatedEditor)
- {
- return GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN);
- }
- else
- {
- return GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN);
- }
-}
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
index fc6920db54..a60490e122 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
@@ -1,149 +1,146 @@
/*===================================================================
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 QMITKDATAMANAGERVIEW_H_
#define QMITKDATAMANAGERVIEW_H_
#include
// mitk core
#include
// berry plugin
#include
// mitk gui qt common plugin
#include
// mitk gui qt application
#include
// qt
#include
// forward declarations
class QAction;
class QModelIndex;
class QTreeView;
class QSignalMapper;
class QmitkDnDFrameWidget;
class QmitkDataStorageTreeModel;
class QmitkDataManagerItemDelegate;
class QmitkDataStorageFilterProxyModel;
/**
* @brief A view that shows all data nodes of the data storage in a qt tree view.
*
*/
class MITK_QT_DATAMANAGER QmitkDataManagerView : public QmitkAbstractView
{
Q_OBJECT
public:
static const QString VIEW_ID; // = "org.mitk.views.datamanager"
QmitkDataManagerView();
~QmitkDataManagerView() override;
public Q_SLOTS:
// invoked when the berry preferences were changed
void OnPreferencesChanged(const berry::IBerryPreferences* prefs) override;
//////////////////////////////////////////////////////////////////////////
// Slots for Qt node tree signals
//////////////////////////////////////////////////////////////////////////
/// When rows are inserted auto expand them
void NodeTreeViewRowsInserted(const QModelIndex& parent, int start, int end);
/// will setup m_CurrentRowCount
void NodeTreeViewRowsRemoved(const QModelIndex& parent, int start, int end);
/// Whenever the selection changes set the "selected" property respectively
void NodeSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
void OnNodeVisibilityChanged();
/// Opens the editor with the given id using the current data storage
void ShowIn(const QString& editorId);
protected:
void CreateQtPartControl(QWidget* parent) override;
void SetFocus() override;
///
/// React to node changes. Overridden from QmitkAbstractView.
///
void NodeChanged(const mitk::DataNode* node) override;
protected:
QWidget* m_Parent;
QmitkDnDFrameWidget* m_DnDFrameWidget;
///
/// \brief A plain widget as the base pane.
///
QmitkDataStorageTreeModel* m_NodeTreeModel;
QmitkDataStorageFilterProxyModel* m_FilterModel;
mitk::NodePredicateBase::Pointer m_HelperObjectFilterPredicate;
mitk::NodePredicateBase::Pointer m_NodeWithNoDataFilterPredicate;
///
/// Holds the preferences for the data manager.
///
berry::IBerryPreferences::Pointer m_DataManagerPreferencesNode;
///
/// \brief The Table view to show the selected nodes.
///
QTreeView* m_NodeTreeView;
///
/// \brief The context menu that shows up when right clicking on a node.
///
QmitkDataNodeContextMenu* m_DataNodeContextMenu;
///
/// \brief flag indicating whether a surface created from a selected decimation is decimated with vtkQuadricDecimation or not
///
bool m_SurfaceDecimation;
/// Maps "Show in" actions to editor ids
QSignalMapper* m_ShowInMapper;
/// A list of "Show in" actions
QList m_ShowInActions;
/// saves the current amount of rows shown in the data manager
size_t m_CurrentRowCount;
/// if true, GlobalReinit() is called if a node is deleted
bool m_GlobalReinitOnNodeDelete;
bool m_GlobalReinitOnNodeVisibilityChanged;
QmitkDataManagerItemDelegate* m_ItemDelegate;
private:
QItemSelectionModel* GetDataNodeSelectionModel() const override;
- /// Reopen multi widget editor if it has been closed
- mitk::IRenderWindowPart *OpenRenderWindowPart(bool activatedEditor = true);
-
};
#endif // QMITKDATAMANAGERVIEW_H_
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
index 38476db4cc..e3a88a5d86 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
@@ -1,1127 +1,1125 @@
/*===================================================================
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
#include "mitkProperties.h"
#include "mitkSegTool2D.h"
#include "mitkStatusBar.h"
#include "QmitkNewSegmentationDialog.h"
#include
#include
#include
#include "QmitkSegmentationView.h"
#include
#include "mitkVtkResliceInterpolationProperty.h"
#include "mitkApplicationCursor.h"
#include "mitkSegmentationObjectFactory.h"
#include "mitkPluginActivator.h"
#include "mitkCameraController.h"
#include "mitkLabelSetImage.h"
#include
#include "usModuleResource.h"
#include "usModuleResourceStream.h"
//micro service to get the ToolManager instance
#include "mitkToolManagerProvider.h"
+#include
+
const std::string QmitkSegmentationView::VIEW_ID = "org.mitk.views.segmentation";
QmitkSegmentationView::QmitkSegmentationView()
: m_Parent(nullptr)
, m_Controls(nullptr)
, m_RenderWindowPart(nullptr)
, m_MouseCursorSet(false)
, m_DataSelectionChanged(false)
, m_AutoSelectionEnabled(false)
{
mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New();
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage");
auto isSegment = mitk::NodePredicateDataType::New("Segment");
mitk::NodePredicateOr::Pointer validImages = mitk::NodePredicateOr::New();
validImages->AddPredicate(mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isSegment)));
validImages->AddPredicate(isDwi);
validImages->AddPredicate(isDti);
validImages->AddPredicate(isOdf);
mitk::NodePredicateNot::Pointer isNotAHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)));
m_IsOfTypeImagePredicate = mitk::NodePredicateAnd::New(validImages, isNotAHelperObject);
mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
mitk::NodePredicateNot::Pointer isNotBinaryPredicate = mitk::NodePredicateNot::New(isBinaryPredicate);
mitk::NodePredicateAnd::Pointer isABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isBinaryPredicate);
mitk::NodePredicateAnd::Pointer isNotABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isNotBinaryPredicate);
m_IsASegmentationImagePredicate = mitk::NodePredicateOr::New(isABinaryImagePredicate, mitk::TNodePredicateDataType::New());
m_IsAPatientImagePredicate = mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, mitk::NodePredicateNot::New(mitk::TNodePredicateDataType::New()));
}
QmitkSegmentationView::~QmitkSegmentationView()
{
if (m_Controls)
{
SetToolSelectionBoxesEnabled(false);
// deactivate all tools
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
// removing all observers
for (NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter)
{
(*dataIter).first->GetProperty("visible")->RemoveObserver((*dataIter).second);
}
m_WorkingDataObserverTags.clear();
for (NodeTagMapType::iterator dataIter = m_BinaryPropertyObserverTags.begin(); dataIter != m_BinaryPropertyObserverTags.end(); ++dataIter)
{
(*dataIter).first->GetProperty("binary")->RemoveObserver((*dataIter).second);
}
m_BinaryPropertyObserverTags.clear();
mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderingManagerObserverTag);
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference();
mitk::PlanePositionManagerService* service = context->getService(ppmRef);
service->RemoveAllPlanePositions();
context->ungetService(ppmRef);
SetToolManagerSelection(0, 0);
}
delete m_Controls;
}
void QmitkSegmentationView::NewNodesGenerated()
{
MITK_WARN << "Use of deprecated function: NewNodesGenerated!! This function is empty and will be removed in the next time!";
}
void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes)
{
if (!nodes) return;
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
if (!toolManager) return;
for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter)
{
this->FireNodeSelected( *iter );
// only last iteration meaningful, multiple generated objects are not taken into account here
}
}
void QmitkSegmentationView::Visible()
{
}
void QmitkSegmentationView::Hidden()
{
}
void QmitkSegmentationView::Activated()
{
}
void QmitkSegmentationView::Deactivated()
{
}
void QmitkSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
if (m_RenderWindowPart != renderWindowPart)
{
m_RenderWindowPart = renderWindowPart;
}
if (m_Parent)
{
m_Parent->setEnabled(true);
}
// tell the interpolation about tool manager, data storage and render window part
if (m_Controls)
{
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
m_Controls->m_SlicesInterpolator->SetDataStorage(this->GetDataStorage());
QList controllers;
controllers.push_back(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController());
controllers.push_back(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController());
controllers.push_back(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController());
m_Controls->m_SlicesInterpolator->Initialize(toolManager, controllers);
}
}
void QmitkSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/)
{
m_RenderWindowPart = nullptr;
if (m_Parent)
{
m_Parent->setEnabled(false);
}
}
void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
{
if (m_Controls != nullptr)
{
bool slimView = prefs->GetBool("slim view", false);
m_Controls->m_ManualToolSelectionBox2D->SetShowNames(!slimView);
m_Controls->m_ManualToolSelectionBox3D->SetShowNames(!slimView);
m_Controls->btnNewSegmentation->setToolButtonStyle(slimView
? Qt::ToolButtonIconOnly
: Qt::ToolButtonTextOnly);
}
m_AutoSelectionEnabled = prefs->GetBool("auto selection", false);
this->ForceDisplayPreferencesUponAllImages();
}
void QmitkSegmentationView::CreateNewSegmentation()
{
mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
if (node.IsNotNull())
{
mitk::Image::Pointer image = dynamic_cast(node->GetData());
if (image.IsNotNull())
{
if (image->GetDimension() > 1)
{
// ask about the name and organ type of the new segmentation
QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog(m_Parent); // needs a QWidget as parent, "this" is not QWidget
QStringList organColors = mitk::OrganNamesHandling::GetDefaultOrganColorString();;
dialog->SetSuggestionList(organColors);
int dialogReturnValue = dialog->exec();
if (dialogReturnValue == QDialog::Rejected)
{
// user clicked cancel or pressed Esc or something similar
return;
}
// ask the user about an organ type and name, add this information to the image's (!) propertylist
// create a new image of the same dimensions and smallest possible pixel type
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
mitk::Tool* firstTool = toolManager->GetToolById(0);
if (firstTool)
{
try
{
std::string newNodeName = dialog->GetSegmentationName().toStdString();
if (newNodeName.empty())
{
newNodeName = "no_name";
}
mitk::DataNode::Pointer emptySegmentation = firstTool->CreateEmptySegmentationNode(image, newNodeName, dialog->GetColor());
// initialize showVolume to false to prevent recalculating the volume while working on the segmentation
emptySegmentation->SetProperty("showVolume", mitk::BoolProperty::New(false));
if (!emptySegmentation)
{
return; // could be aborted by user
}
mitk::OrganNamesHandling::UpdateOrganList(organColors, dialog->GetSegmentationName(), dialog->GetColor());
// escape ';' here (replace by '\;'), see longer comment above
QString stringForStorage = organColors.replaceInStrings(";", "\\;").join(";");
MITK_DEBUG << "Will store: " << stringForStorage;
this->GetPreferences()->Put("Organ-Color-List", stringForStorage);
this->GetPreferences()->Flush();
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0))
{
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)->SetSelected(false);
}
emptySegmentation->SetSelected(true);
this->GetDataStorage()->Add(emptySegmentation, node); // add as a child, because the segmentation "derives" from the original
this->FireNodeSelected(emptySegmentation);
this->OnSelectionChanged(emptySegmentation);
m_Controls->segImageSelector->SetSelectedNode(emptySegmentation);
mitk::RenderingManager::GetInstance()->InitializeViews(emptySegmentation->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
}
catch (std::bad_alloc)
{
QMessageBox::warning(nullptr, tr("Create new segmentation"), tr("Could not allocate memory for new segmentation"));
}
}
}
else
{
QMessageBox::information(nullptr, tr("Segmentation"), tr("Segmentation is currently not supported for 2D images"));
}
}
}
else
{
MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected...";
}
}
void QmitkSegmentationView::OnVisiblePropertyChanged()
{
mitk::DataNode* selectedNode = m_Controls->segImageSelector->GetSelectedNode();
if ( !selectedNode )
{
this->SetToolSelectionBoxesEnabled(false);
return;
}
mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
bool selectedNodeIsVisible = renderWindowPart && selectedNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer());
if (!selectedNodeIsVisible)
{
this->SetToolSelectionBoxesEnabled(false);
this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!"));
}
else
{
this->SetToolSelectionBoxesEnabled(true);
this->UpdateWarningLabel("");
}
}
void QmitkSegmentationView::OnBinaryPropertyChanged()
{
mitk::DataStorage::SetOfObjects::ConstPointer patImages = m_Controls->patImageSelector->GetNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = patImages->Begin(); it != patImages->End(); ++it)
{
const mitk::DataNode* node = it->Value();
if(m_IsASegmentationImagePredicate->CheckNode(node))
{
m_Controls->patImageSelector->RemoveNode(node);
m_Controls->segImageSelector->AddNode(node);
this->SetToolManagerSelection(nullptr,nullptr);
return;
}
}
mitk::DataStorage::SetOfObjects::ConstPointer segImages = m_Controls->segImageSelector->GetNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = segImages->Begin(); it != segImages->End(); ++it)
{
const mitk::DataNode* node = it->Value();
if(!m_IsASegmentationImagePredicate->CheckNode(node))
{
m_Controls->segImageSelector->RemoveNode(node);
m_Controls->patImageSelector->AddNode(node);
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node)
{
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->SetWorkingData(nullptr);
}
return;
}
}
}
void QmitkSegmentationView::NodeAdded(const mitk::DataNode *node)
{
if (!m_IsOfTypeImagePredicate->CheckNode(node))
{
return;
}
itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged);
m_WorkingDataObserverTags.insert(std::pair(const_cast(node), node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command)));
itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New();
command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged);
m_BinaryPropertyObserverTags.insert(std::pair(const_cast(node), node->GetProperty("binary")->AddObserver(itk::ModifiedEvent(), command2)));
ApplyDisplayOptions(const_cast(node));
}
void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node)
{
if (m_IsASegmentationImagePredicate->CheckNode(node))
{
//First of all remove all possible contour markers of the segmentation
mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(node, mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)));
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference();
mitk::PlanePositionManagerService* service = context->getService(ppmRef);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it)
{
std::string nodeName = node->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1;
service->RemovePlanePosition(id);
this->GetDataStorage()->Remove(it->Value());
}
context->ungetService(ppmRef);
service = nullptr;
if ((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull())
{
this->SetToolManagerSelection(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0), nullptr);
this->UpdateWarningLabel(tr("Select or create a segmentation"));
}
mitk::Image* image = dynamic_cast(node->GetData());
mitk::SurfaceInterpolationController::GetInstance()->RemoveInterpolationSession(image);
}
mitk::DataNode* tempNode = const_cast(node);
//Since the binary property could be changed during runtime by the user
if (m_IsOfTypeImagePredicate->CheckNode(node))
{
node->GetProperty("visible")->RemoveObserver(m_WorkingDataObserverTags[tempNode]);
m_WorkingDataObserverTags.erase(tempNode);
node->GetProperty("binary")->RemoveObserver(m_BinaryPropertyObserverTags[tempNode]);
m_BinaryPropertyObserverTags.erase(tempNode);
}
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) == node)
{
//as we don't know which node was actually removed e.g. our reference node, disable 'New Segmentation' button.
//consider the case that there is no more image in the datastorage
this->SetToolManagerSelection(nullptr, nullptr);
this->SetToolSelectionBoxesEnabled(false);
}
}
void QmitkSegmentationView::OnPatientComboBoxSelectionChanged( const mitk::DataNode* node )
{
//mitk::DataNode* selectedNode = const_cast(node);
if( node != nullptr )
{
this->UpdateWarningLabel("");
mitk::DataNode* segNode = m_Controls->segImageSelector->GetSelectedNode();
if (segNode)
{
mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDataStorage()->GetSources(segNode, m_IsAPatientImagePredicate);
bool isSourceNode(false);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = possibleParents->Begin(); it != possibleParents->End(); it++)
{
if (it.Value() == node)
isSourceNode = true;
}
if ( !isSourceNode && (!this->CheckForSameGeometry(segNode, node) || possibleParents->Size() > 0 ))
{
this->SetToolManagerSelection(node, nullptr);
this->SetToolSelectionBoxesEnabled( false );
this->UpdateWarningLabel(tr("The selected patient image does not match with the selected segmentation!"));
}
else if ((!isSourceNode && this->CheckForSameGeometry(segNode, node)) || isSourceNode )
{
this->SetToolManagerSelection(node, segNode);
//Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are
//loaded separately
int layer(10);
node->GetIntProperty("layer", layer);
layer++;
segNode->SetProperty("layer", mitk::IntProperty::New(layer));
//this->UpdateWarningLabel("");
RenderingManagerReinitialized();
}
}
else
{
this->SetToolManagerSelection(node, nullptr);
this->SetToolSelectionBoxesEnabled( false );
this->UpdateWarningLabel(tr("Select or create a segmentation"));
}
}
else
{
this->UpdateWarningLabel(tr("Please load an image!"));
this->SetToolSelectionBoxesEnabled( false );
}
}
void QmitkSegmentationView::OnSegmentationComboBoxSelectionChanged(const mitk::DataNode *node)
{
if (node == nullptr)
{
this->UpdateWarningLabel(tr("Select or create a segmentation"));
this->SetToolSelectionBoxesEnabled( false );
return;
}
mitk::DataNode* refNode = m_Controls->patImageSelector->GetSelectedNode();
RenderingManagerReinitialized();
if ( m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further
return;
if (m_AutoSelectionEnabled)
{
this->OnSelectionChanged(const_cast(node));
}
else
{
mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDataStorage()->GetSources(node, m_IsAPatientImagePredicate);
if ( possibleParents->Size() == 1 )
{
mitk::DataNode* parentNode = possibleParents->ElementAt(0);
if (parentNode != refNode)
{
this->UpdateWarningLabel(tr("The selected segmentation does not match with the selected patient image!"));
this->SetToolSelectionBoxesEnabled( false );
this->SetToolManagerSelection(nullptr, node);
}
else
{
this->UpdateWarningLabel("");
this->SetToolManagerSelection(refNode, node);
}
}
else if (refNode && this->CheckForSameGeometry(node, refNode))
{
this->UpdateWarningLabel("");
this->SetToolManagerSelection(refNode, node);
}
else if (!refNode || !this->CheckForSameGeometry(node, refNode))
{
this->UpdateWarningLabel(tr("Please select or load the according patient image!"));
}
}
mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
if (!renderWindowPart || !node->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()))
{
this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!"));
this->SetToolSelectionBoxesEnabled( false );
}
}
void QmitkSegmentationView::OnShowMarkerNodes (bool state)
{
mitk::SegTool2D::Pointer manualSegmentationTool;
unsigned int numberOfExistingTools = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetTools().size();
for(unsigned int i = 0; i < numberOfExistingTools; i++)
{
manualSegmentationTool = dynamic_cast(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetToolById(i));
if (manualSegmentationTool)
{
if(state == true)
{
manualSegmentationTool->SetShowMarkerNodes( true );
}
else
{
manualSegmentationTool->SetShowMarkerNodes( false );
}
}
}
}
void QmitkSegmentationView::OnSelectionChanged(mitk::DataNode* node)
{
berry::IWorkbenchPart::Pointer nullPart;
QList nodes;
nodes.push_back(node);
this->OnSelectionChanged(nullPart, nodes);
}
void QmitkSegmentationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes)
{
if (nodes.size() != 0)
{
std::string markerName = "Position";
unsigned int numberOfNodes = nodes.size();
std::string nodeName = nodes.at(0)->GetName();
if ((numberOfNodes == 1) && (nodeName.find(markerName) == 0))
{
OnContourMarkerSelected(nodes.at(0));
return;
}
}
if (m_AutoSelectionEnabled)
{
if (nodes.size() == 0 && m_Controls->patImageSelector->GetSelectedNode().IsNull())
{
SetToolManagerSelection(nullptr, nullptr);
}
else if (nodes.size() == 1)
{
mitk::DataNode::Pointer selectedNode = nodes.at(0);
if (selectedNode.IsNull())
{
return;
}
mitk::Image::Pointer selectedImage = dynamic_cast(selectedNode->GetData());
if (selectedImage.IsNull())
{
SetToolManagerSelection(nullptr, nullptr);
return;
}
if (m_IsASegmentationImagePredicate->CheckNode(selectedNode))
{
// set all nodes to invisible
mitk::DataStorage::SetOfObjects::ConstPointer allImages = GetDataStorage()->GetSubset(m_IsOfTypeImagePredicate);
for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter)
{
(*iter)->SetVisibility(false);
}
// if a segmentation is selected find a possible patient image
mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(selectedNode, m_IsAPatientImagePredicate);
mitk::DataNode::Pointer refNode;
if (sources->Size() != 0)
{
// found one or more sources - use the first one
refNode = sources->ElementAt(0);
refNode->SetVisibility(true);
selectedNode->SetVisibility(true);
SetToolManagerSelection(refNode, selectedNode);
}
else
{
// did not find a source / patient image, check all images and compare geometry
mitk::DataStorage::SetOfObjects::ConstPointer possiblePatientImages = GetDataStorage()->GetSubset(m_IsAPatientImagePredicate);
for (mitk::DataStorage::SetOfObjects::ConstIterator iter = possiblePatientImages->Begin(); iter != possiblePatientImages->End(); ++iter)
{
refNode = iter->Value();
if (CheckForSameGeometry(selectedNode, iter->Value()))
{
refNode->SetVisibility(true);
selectedNode->SetVisibility(true);
SetToolManagerSelection(refNode, selectedNode);
// doing this we can assure that the segmentation is always visible if the segmentation and the patient image are at the
// same level in the data manager
int layer(10);
refNode->GetIntProperty("layer", layer);
layer++;
selectedNode->SetProperty("layer", mitk::IntProperty::New(layer));
return;
}
}
// did not find a source / patient image with the same geometry
SetToolManagerSelection(nullptr, selectedNode);
}
mitk::RenderingManager::GetInstance()->InitializeViews(selectedNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
}
else
{
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) != selectedNode)
{
SetToolManagerSelection(selectedNode, nullptr);
// may be a bug in the selection services. A node which is deselected will be passed as selected node to the OnSelectionChanged function
mitk::IRenderWindowPart* renderWindowPart = GetRenderWindowPart();
if (renderWindowPart && !selectedNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()))
{
selectedNode->SetVisibility(true);
}
UpdateWarningLabel(tr("The selected patient image does not match with the selected segmentation!"));
SetToolSelectionBoxesEnabled(false);
}
}
}
if (m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further
{
return;
}
RenderingManagerReinitialized();
}
}
void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node)
{
QmitkRenderWindow* selectedRenderWindow = 0;
- QmitkRenderWindow* axialRenderWindow =
- this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("axial");
- QmitkRenderWindow* sagittalRenderWindow =
- this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("sagittal");
- QmitkRenderWindow* coronalRenderWindow =
- this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("coronal");
- QmitkRenderWindow* _3DRenderWindow =
- this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("3d");
+ QmitkRenderWindow* axialRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("axial");
+ QmitkRenderWindow* sagittalRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("sagittal");
+ QmitkRenderWindow* coronalRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("coronal");
+ QmitkRenderWindow* _3DRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("3d");
bool PlanarFigureInitializedWindow = false;
// find initialized renderwindow
if (node->GetBoolProperty("PlanarFigureInitializedWindow",
PlanarFigureInitializedWindow, axialRenderWindow->GetRenderer()))
{
selectedRenderWindow = axialRenderWindow;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
sagittalRenderWindow->GetRenderer()))
{
selectedRenderWindow = sagittalRenderWindow;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
coronalRenderWindow->GetRenderer()))
{
selectedRenderWindow = coronalRenderWindow;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
_3DRenderWindow->GetRenderer()))
{
selectedRenderWindow = _3DRenderWindow;
}
// make node visible
if (selectedRenderWindow)
{
std::string nodeName = node->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int id = atof(nodeName.substr(t+1).c_str())-1;
{
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference();
mitk::PlanePositionManagerService* service = context->getService(ppmRef);
selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id));
context->ungetService(ppmRef);
}
selectedRenderWindow->GetRenderer()->GetCameraController()->Fit();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkSegmentationView::OnTabWidgetChanged(int id)
{
//always disable tools on tab changed
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
//2D Tab ID = 0
//3D Tab ID = 1
if (id == 0)
{
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox3D->hide();
m_Controls->m_ManualToolSelectionBox2D->show();
//Deactivate possible active tool
//TODO Remove possible visible interpolations -> Maybe changes in SlicesInterpolator
}
else
{
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox2D->hide();
m_Controls->m_ManualToolSelectionBox3D->show();
//Deactivate possible active tool
}
}
void QmitkSegmentationView::InitToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData)
{
// initial tool manager selection, called from 'CreateQtPartControl'
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
toolManager->SetReferenceData(const_cast(referenceData));
toolManager->SetWorkingData(const_cast(workingData));
// check original image
m_Controls->btnNewSegmentation->setEnabled(referenceData != nullptr);
if (referenceData)
{
UpdateWarningLabel("");
}
}
void QmitkSegmentationView::SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData)
{
// called as a result of new BlueBerry selections
// tells the ToolManager for manual segmentation about new selections
// updates GUI information about what the user should select
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
toolManager->SetReferenceData(const_cast(referenceData));
toolManager->SetWorkingData(const_cast(workingData));
// check original image
m_Controls->btnNewSegmentation->setEnabled(referenceData != nullptr);
if (referenceData)
{
UpdateWarningLabel("");
disconnect(m_Controls->patImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnPatientComboBoxSelectionChanged(const mitk::DataNode*)));
m_Controls->patImageSelector->setCurrentIndex(m_Controls->patImageSelector->Find(referenceData));
connect(m_Controls->patImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnPatientComboBoxSelectionChanged(const mitk::DataNode*)));
// check segmentation
if (workingData)
{
//FireNodeSelected(const_cast(workingData));
disconnect(m_Controls->segImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*)));
m_Controls->segImageSelector->setCurrentIndex(m_Controls->segImageSelector->Find(workingData));
connect(m_Controls->segImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*)));
}
}
}
void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages()
{
if (!m_Parent)
{
return;
}
// check all images and segmentations in DataStorage:
// (items in brackets are implicitly done by previous steps)
// 1.
// if a reference image is selected,
// show the reference image
// and hide all other images (orignal and segmentation),
// (and hide all segmentations of the other original images)
// and show all the reference's segmentations
// if no reference image is selected, do do nothing
//
// 2.
// if a segmentation is selected,
// show it
// (and hide all all its siblings (childs of the same parent, incl, nullptr parent))
// if no segmentation is selected, do nothing
if (!m_Controls)
{
return; // might happen on initialization (preferences loaded)
}
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
mitk::DataNode::Pointer referenceData = toolManager->GetReferenceData(0);
mitk::DataNode::Pointer workingData = toolManager->GetWorkingData(0);
// 1.
if (referenceData.IsNotNull())
{
// iterate all images
mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDataStorage()->GetSubset(m_IsASegmentationImagePredicate);
for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
// apply display preferences
ApplyDisplayOptions(node);
// set visibility
node->SetVisibility(node == referenceData);
}
}
// 2.
if (workingData.IsNotNull())
workingData->SetVisibility(true);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node)
{
if (!node)
{
return;
}
mitk::BoolProperty::Pointer drawOutline = mitk::BoolProperty::New(GetPreferences()->GetBool("draw outline", true));
mitk::BoolProperty::Pointer volumeRendering = mitk::BoolProperty::New(GetPreferences()->GetBool("volume rendering", false));
mitk::LabelSetImage* labelSetImage = dynamic_cast(node->GetData());
if (nullptr != labelSetImage)
{
// node is actually a multi label segmentation,
// but its outline property can be set in the 'single label' segmentation preference page as well
node->SetProperty("labelset.contour.active", drawOutline);
node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
node->SetProperty("volumerendering", volumeRendering);
// force render window update to show outline
node->GetData()->Modified();
}
else
{
// node is a 'single label' segmentation
bool isBinary = false;
node->GetBoolProperty("binary", isBinary);
if (isBinary)
{
node->SetProperty("outline binary", drawOutline);
node->SetProperty("outline width", mitk::FloatProperty::New(2.0));
node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
node->SetProperty("volumerendering", volumeRendering);
// force render window update to show outline
node->GetData()->Modified();
}
}
}
void QmitkSegmentationView::RenderingManagerReinitialized()
{
if (!this->GetRenderWindowPart())
{
return;
}
/*
* Here we check whether the geometry of the selected segmentation image if aligned with the worldgeometry
* At the moment it is not supported to use a geometry different from the selected image for reslicing.
* For further information see Bug 16063
*/
mitk::DataNode* workingNode = m_Controls->segImageSelector->GetSelectedNode();
const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D();
if (workingNode && worldGeo)
{
const mitk::BaseGeometry* workingNodeGeo = workingNode->GetData()->GetGeometry();
const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D();
if (mitk::Equal(*workingNodeGeo->GetBoundingBox(), *worldGeo->GetBoundingBox(), mitk::eps, true))
{
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), workingNode);
this->SetToolSelectionBoxesEnabled(true);
this->UpdateWarningLabel("");
}
else
{
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), nullptr);
this->SetToolSelectionBoxesEnabled(false);
this->UpdateWarningLabel(tr("Please perform a reinit on the segmentation image!"));
}
}
}
bool QmitkSegmentationView::CheckForSameGeometry(const mitk::DataNode *node1, const mitk::DataNode *node2) const
{
bool isSameGeometry(true);
mitk::Image* image1 = dynamic_cast(node1->GetData());
mitk::Image* image2 = dynamic_cast(node2->GetData());
if (image1 && image2)
{
mitk::BaseGeometry* geo1 = image1->GetGeometry();
mitk::BaseGeometry* geo2 = image2->GetGeometry();
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetOrigin(), geo2->GetOrigin());
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(0), geo2->GetExtent(0));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(1), geo2->GetExtent(1));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(2), geo2->GetExtent(2));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetSpacing(), geo2->GetSpacing());
isSameGeometry = isSameGeometry && mitk::MatrixEqualElementWise(geo1->GetIndexToWorldTransform()->GetMatrix(), geo2->GetIndexToWorldTransform()->GetMatrix());
return isSameGeometry;
}
else
{
return false;
}
}
void QmitkSegmentationView::UpdateWarningLabel(QString text)
{
if (text.size() == 0)
m_Controls->lblSegmentationWarnings->hide();
else
m_Controls->lblSegmentationWarnings->show();
m_Controls->lblSegmentationWarnings->setText(text);
}
void QmitkSegmentationView::CreateQtPartControl(QWidget* parent)
{
// setup the basic GUI of this view
m_Parent = parent;
m_Controls = new Ui::QmitkSegmentationControls;
m_Controls->setupUi(parent);
m_Controls->patImageSelector->SetDataStorage(GetDataStorage());
m_Controls->patImageSelector->SetPredicate(m_IsAPatientImagePredicate);
UpdateWarningLabel(tr("Please load an image"));
if (m_Controls->patImageSelector->GetSelectedNode().IsNotNull())
{
UpdateWarningLabel(tr("Select or create a new segmentation"));
}
m_Controls->segImageSelector->SetDataStorage(GetDataStorage());
m_Controls->segImageSelector->SetPredicate(m_IsASegmentationImagePredicate);
if (m_Controls->segImageSelector->GetSelectedNode().IsNotNull())
{
UpdateWarningLabel("");
}
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
assert(toolManager);
toolManager->SetDataStorage(*(GetDataStorage()));
toolManager->InitializeTools();
// all part of open source MITK
m_Controls->m_ManualToolSelectionBox2D->setEnabled(true);
m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true);
m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer2D );
m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups(tr("Add Subtract Correction Paint Wipe 'Region Growing' Fill Erase 'Live Wire' '2D Fast Marching'").toStdString());
m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3);
m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible );
connect( m_Controls->m_ManualToolSelectionBox2D, SIGNAL(ToolSelected(int)), this, SLOT(OnManualTool2DSelected(int)) );
//setup 3D Tools
m_Controls->m_ManualToolSelectionBox3D->setEnabled(true);
m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true);
m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer3D );
//specify tools to be added to 3D Tool area
m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups(tr("Threshold 'UL Threshold' Otsu 'Fast Marching 3D' 'Region Growing 3D' Watershed Picking").toStdString());
m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3);
m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible );
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox3D->hide();
m_Controls->m_ManualToolSelectionBox2D->show();
// update the list of segmentations
toolManager->NewNodesGenerated += mitk::MessageDelegate(this, &QmitkSegmentationView::NewNodesGenerated);
// update the list of segmentations
toolManager->NewNodeObjectsGenerated += mitk::MessageDelegate1(this, &QmitkSegmentationView::NewNodeObjectsGenerated);
// create signal/slot connections
connect(m_Controls->patImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnPatientComboBoxSelectionChanged(const mitk::DataNode*)));
connect(m_Controls->segImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*)));
connect( m_Controls->btnNewSegmentation, SIGNAL(clicked()), this, SLOT(CreateNewSegmentation()) );
// connect( m_Controls->CreateSegmentationFromSurface, SIGNAL(clicked()), this, SLOT(CreateSegmentationFromSurface()) );
// connect( m_Controls->widgetStack, SIGNAL(currentChanged(int)), this, SLOT(ToolboxStackPageChanged(int)) );
connect( m_Controls->tabWidgetSegmentationTools, SIGNAL(currentChanged(int)), this, SLOT(OnTabWidgetChanged(int)));
// connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
// this, SLOT( OnSurfaceSelectionChanged( ) ) );
connect(m_Controls->m_SlicesInterpolator, SIGNAL(SignalShowMarkerNodes(bool)), this, SLOT(OnShowMarkerNodes(bool)));
// m_Controls->MaskSurfaces->SetDataStorage(this->GetDataStorage());
// m_Controls->MaskSurfaces->SetPredicate(mitk::NodePredicateDataType::New("Surface"));
mitk::DataStorage::SetOfObjects::ConstPointer patientImages = GetDataStorage()->GetSubset(m_IsAPatientImagePredicate);
if (!patientImages->empty())
{
OnSelectionChanged(*patientImages->begin());
}
// set callback function for already existing nodes (images & segmentations)
mitk::DataStorage::SetOfObjects::ConstPointer allImages = GetDataStorage()->GetSubset(m_IsOfTypeImagePredicate);
for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged);
m_WorkingDataObserverTags.insert(std::pair(node, node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command)));
itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New();
command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged);
m_BinaryPropertyObserverTags.insert(std::pair(node, node->GetProperty("binary")->AddObserver(itk::ModifiedEvent(), command2)));
}
itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &QmitkSegmentationView::RenderingManagerReinitialized);
m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver(mitk::RenderingManagerViewsInitializedEvent(), command);
InitToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), m_Controls->segImageSelector->GetSelectedNode());
m_RenderWindowPart = GetRenderWindowPart();
if (m_RenderWindowPart)
{
RenderWindowPartActivated(m_RenderWindowPart);
}
}
void QmitkSegmentationView::SetFocus()
{
m_Controls->btnNewSegmentation->setFocus();
}
void QmitkSegmentationView::OnManualTool2DSelected(int id)
{
if (id >= 0)
{
std::string text = "Active Tool: \"";
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
text += toolManager->GetToolById(id)->GetName();
text += "\"";
mitk::StatusBar::GetInstance()->DisplayText(text.c_str());
us::ModuleResource resource = toolManager->GetToolById(id)->GetCursorIconResource();
this->SetMouseCursor(resource, 0, 0);
}
else
{
this->ResetMouseCursor();
mitk::StatusBar::GetInstance()->DisplayText("");
}
}
void QmitkSegmentationView::ResetMouseCursor()
{
if ( m_MouseCursorSet )
{
mitk::ApplicationCursor::GetInstance()->PopCursor();
m_MouseCursorSet = false;
}
}
void QmitkSegmentationView::SetMouseCursor( const us::ModuleResource& resource, int hotspotX, int hotspotY )
{
if (!resource) return;
// Remove previously set mouse cursor
if ( m_MouseCursorSet )
{
mitk::ApplicationCursor::GetInstance()->PopCursor();
}
us::ModuleResourceStream cursor(resource, std::ios::binary);
mitk::ApplicationCursor::GetInstance()->PushCursor( cursor, hotspotX, hotspotY );
m_MouseCursorSet = true;
}
void QmitkSegmentationView::SetToolSelectionBoxesEnabled(bool status)
{
if (status)
{
m_Controls->m_ManualToolSelectionBox2D->RecreateButtons();
m_Controls->m_ManualToolSelectionBox3D->RecreateButtons();
}
m_Controls->m_ManualToolSelectionBox2D->setEnabled(status);
m_Controls->m_ManualToolSelectionBox3D->setEnabled(status);
m_Controls->m_SlicesInterpolator->setEnabled(status);
}