Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkStdMultiWidgetEditor.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 
15 #include <berryUIException.h>
16 #include <berryIWorkbenchPage.h>
18 #include <berryIPreferences.h>
19 
20 #include <mitkColorProperty.h>
21 #include <mitkNodePredicateNot.h>
23 
26 
27 // mitk qt widgets module
29 #include <QmitkLevelWindowWidget.h>
31 #include <QmitkStdMultiWidget.h>
32 
33 // mitk gui qt common plugin
35 
36 const QString QmitkStdMultiWidgetEditor::EDITOR_ID = "org.mitk.editors.stdmultiwidget";
37 
38 struct QmitkStdMultiWidgetEditor::Impl final
39 {
40  Impl();
41  ~Impl() = default;
42 
43  QmitkInteractionSchemeToolBar* m_InteractionSchemeToolBar;
44  QmitkLevelWindowWidget* m_LevelWindowWidget;
45 
46  std::unique_ptr<QmitkMultiWidgetDecorationManager> m_MultiWidgetDecorationManager;
47 };
48 
49 QmitkStdMultiWidgetEditor::Impl::Impl()
50  : m_InteractionSchemeToolBar(nullptr)
51  , m_LevelWindowWidget(nullptr)
52 {
53  // nothing here
54 }
55 
57 // QmitkStdMultiWidgetEditor
61  , m_Impl(std::make_unique<Impl>())
62 {
63  // nothing here
64 }
65 
67 {
68  GetSite()->GetPage()->RemovePartListener(this);
69 }
70 
71 berry::IPartListener::Events::Types QmitkStdMultiWidgetEditor::GetPartEventTypes() const
72 {
74 }
75 
77 {
78  if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID)
79  {
80  const auto& multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
81  if (nullptr != multiWidget)
82  {
83  multiWidget->RemovePlanesFromDataStorage();
84  multiWidget->ActivateMenuWidget(false);
85  }
86  }
87 }
88 
90 {
91  if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID)
92  {
93  const auto& multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
94  if (nullptr != multiWidget)
95  {
96  multiWidget->AddPlanesToDataStorage();
97  multiWidget->ActivateMenuWidget(true);
98  }
99  }
100 }
101 
103 {
104  if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID)
105  {
106  const auto& multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
107  if (nullptr != multiWidget)
108  {
109  multiWidget->ActivateMenuWidget(false);
110  }
111  }
112 }
113 
115 {
116  if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID)
117  {
118  const auto& multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
119  if (nullptr != multiWidget)
120  {
121  multiWidget->ActivateMenuWidget(true);
122  }
123  }
124 }
125 
127 {
128  return m_Impl->m_LevelWindowWidget;
129 }
130 
132 {
133  const auto& multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
134  if (nullptr == multiWidget)
135  {
136  return;
137  }
138 
139  multiWidget->SetWidgetPlanesVisibility(enable);
140 }
141 
143 {
144  const auto& multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
145  if (nullptr == multiWidget)
146  {
147  return false;
148  }
149 
150  mitk::DataNode::Pointer node = multiWidget->GetWidgetPlane1();
151  if (node.IsNotNull())
152  {
153  bool visible = false;
154  node->GetVisibility(visible, nullptr);
155  return visible;
156  }
157  else
158  {
159  return false;
160  }
161 }
162 
164 {
165  const auto& multiWidget = GetMultiWidget();
166  if (nullptr == multiWidget)
167  {
168  return;
169  }
170 
172  {
173  m_Impl->m_InteractionSchemeToolBar->setVisible(true);
174  }
175  else
176  {
177  m_Impl->m_InteractionSchemeToolBar->setVisible(false);
178  }
179 
181 }
182 
184 {
185  if (show)
186  {
187  m_Impl->m_LevelWindowWidget->disconnect(this);
188  m_Impl->m_LevelWindowWidget->SetDataStorage(GetDataStorage());
189  m_Impl->m_LevelWindowWidget->show();
190  }
191  else
192  {
193  m_Impl->m_LevelWindowWidget->disconnect(this);
194  m_Impl->m_LevelWindowWidget->hide();
195  }
196 }
197 
198 void QmitkStdMultiWidgetEditor::SetFocus()
199 {
200  const auto& multiWidget = GetMultiWidget();
201  if (nullptr != multiWidget)
202  {
203  multiWidget->setFocus();
204  }
205 }
206 
207 void QmitkStdMultiWidgetEditor::CreateQtPartControl(QWidget* parent)
208 {
209  QHBoxLayout* layout = new QHBoxLayout(parent);
210  layout->setContentsMargins(0, 0, 0, 0);
211 
213 
214  auto multiWidget = GetMultiWidget();
215  if (nullptr == multiWidget)
216  {
217  multiWidget = new QmitkStdMultiWidget(parent);
218 
219  // create left toolbar: interaction scheme toolbar to switch how the render window navigation behaves (in PACS mode)
220  if (nullptr == m_Impl->m_InteractionSchemeToolBar)
221  {
222  m_Impl->m_InteractionSchemeToolBar = new QmitkInteractionSchemeToolBar(parent);
223  layout->addWidget(m_Impl->m_InteractionSchemeToolBar);
224  }
225  m_Impl->m_InteractionSchemeToolBar->SetInteractionEventHandler(multiWidget->GetInteractionEventHandler());
226 
227  multiWidget->SetDataStorage(GetDataStorage());
228  multiWidget->InitializeMultiWidget();
229  SetMultiWidget(multiWidget);
230  }
231 
232  layout->addWidget(multiWidget);
233 
234  // create level window slider on the right side
235  if (nullptr == m_Impl->m_LevelWindowWidget)
236  {
237  m_Impl->m_LevelWindowWidget = new QmitkLevelWindowWidget(parent);
238  m_Impl->m_LevelWindowWidget->setObjectName(QString::fromUtf8("levelWindowWidget"));
239 
240  QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
241  sizePolicy.setHorizontalStretch(0);
242  sizePolicy.setVerticalStretch(0);
243  sizePolicy.setHeightForWidth(m_Impl->m_LevelWindowWidget->sizePolicy().hasHeightForWidth());
244  m_Impl->m_LevelWindowWidget->setSizePolicy(sizePolicy);
245  m_Impl->m_LevelWindowWidget->setMaximumWidth(50);
246  }
247 
248  layout->addWidget(m_Impl->m_LevelWindowWidget);
249 
250  m_Impl->m_MultiWidgetDecorationManager = std::make_unique<QmitkMultiWidgetDecorationManager>(multiWidget);
251 
252  GetSite()->GetPage()->AddPartListener(this);
253 
254  InitializePreferences(preferences);
255  OnPreferencesChanged(preferences);
256 }
257 
258 void QmitkStdMultiWidgetEditor::OnPreferencesChanged(const berry::IBerryPreferences* preferences)
259 {
260  const auto& multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
261  if (nullptr == multiWidget)
262  {
263  return;
264  }
265 
266  // change and apply decoration preferences
267  GetPreferenceDecorations(preferences);
268  m_Impl->m_MultiWidgetDecorationManager->DecorationPreferencesChanged(preferences);
269 
270  QmitkAbstractMultiWidget::RenderWindowWidgetMap renderWindowWidgets = multiWidget->GetRenderWindowWidgets();
271  int i = 0;
272  for (const auto& renderWindowWidget : renderWindowWidgets)
273  {
274  auto decorationColor = renderWindowWidget.second->GetDecorationColor();
275  multiWidget->SetDecorationColor(i, decorationColor);
276 
277  ++i;
278  }
279 
280  int crosshairgapsize = preferences->GetInt("crosshair gap size", 32);
281  multiWidget->GetWidgetPlane1()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize);
282  multiWidget->GetWidgetPlane2()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize);
283  multiWidget->GetWidgetPlane3()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize);
284 
285  // zooming and panning preferences
286  bool constrainedZooming = preferences->GetBool("Use constrained zooming and panning", true);
288 
289  // mouse modes switcher toolbar
290  bool PACSInteractionScheme = preferences->GetBool("PACS like mouse interaction", false);
291  OnInteractionSchemeChanged(PACSInteractionScheme ?
294 
295  // level window setting
296  bool showLevelWindowWidget = preferences->GetBool("Show level/window widget", true);
297  ShowLevelWindowWidget(showLevelWindowWidget);
298 
301 }
302 
303 void QmitkStdMultiWidgetEditor::InitializePreferences(berry::IBerryPreferences * preferences)
304 {
305  auto multiWidget = this->GetMultiWidget();
306 
307  if (nullptr == multiWidget)
308  return;
309 
310  this->GetPreferenceDecorations(preferences); // Override if preferences are defined
311 
312  for (const auto& renderWindowWidget : multiWidget->GetRenderWindowWidgets())
313  {
314  auto widgetName = renderWindowWidget.second->GetWidgetName();
315 
316  auto gradientBackgroundColors = renderWindowWidget.second->GetGradientBackgroundColors();
317  preferences->Put(widgetName + " first background color", this->MitkColorToHex(gradientBackgroundColors.first));
318  preferences->Put(widgetName + " second background color", this->MitkColorToHex(gradientBackgroundColors.second));
319 
320  auto decorationColor = renderWindowWidget.second->GetDecorationColor();
321  preferences->Put(widgetName + " decoration color", this->MitkColorToHex(decorationColor));
322 
323  auto cornerAnnotation = renderWindowWidget.second->GetCornerAnnotationText();
324  preferences->Put(widgetName + " corner annotation", QString::fromStdString(cornerAnnotation));
325  }
326 }
327 
328 void QmitkStdMultiWidgetEditor::GetPreferenceDecorations(const berry::IBerryPreferences * preferences)
329 {
330  auto multiWidget = dynamic_cast<QmitkStdMultiWidget*>(GetMultiWidget());
331 
332  if (nullptr == multiWidget)
333  return;
334 
335  auto hexBlack = "#000000";
336  auto gradientBlack = "#191919";
337  auto gradientGray = "#7F7F7F";
338 
339  auto renderWindowWidgets = multiWidget->GetRenderWindowWidgets();
340  int i = 0;
341  for (const auto& renderWindowWidget : renderWindowWidgets)
342  {
343  auto widgetName = renderWindowWidget.second->GetWidgetName();
344 
345  if (mitk::BaseRenderer::Standard3D == mitk::BaseRenderer::GetInstance(renderWindowWidget.second->GetRenderWindow()->GetVtkRenderWindow())->GetMapperID())
346  {
347  auto upper = preferences->Get(widgetName + " first background color", gradientBlack);
348  auto lower = preferences->Get(widgetName + " second background color", gradientGray);
349  renderWindowWidget.second->SetGradientBackgroundColors(HexColorToMitkColor(upper), HexColorToMitkColor(lower));
350  }
351  else
352  {
353  auto upper = preferences->Get(widgetName + " first background color", hexBlack);
354  auto lower = preferences->Get(widgetName + " second background color", hexBlack);
355  renderWindowWidget.second->SetGradientBackgroundColors(HexColorToMitkColor(upper), HexColorToMitkColor(lower));
356  }
357 
358  auto defaultDecorationColor = multiWidget->GetDecorationColor(i);
359  auto decorationColor = preferences->Get(widgetName + " decoration color", MitkColorToHex(defaultDecorationColor));
360  renderWindowWidget.second->SetDecorationColor(HexColorToMitkColor(decorationColor));
361 
362  auto defaultCornerAnnotation = renderWindowWidget.second->GetCornerAnnotationText();
363  auto cornerAnnotation = preferences->Get(widgetName + " corner annotation", QString::fromStdString(defaultCornerAnnotation));
364  renderWindowWidget.second->SetCornerAnnotationText(cornerAnnotation.toStdString());
365 
366  ++i;
367  }
368 }
369 
370 mitk::Color QmitkStdMultiWidgetEditor::HexColorToMitkColor(const QString& hexColor)
371 {
372  QColor qColor(hexColor);
373  mitk::Color returnColor;
374  float colorMax = 255.0f;
375  if (hexColor.isEmpty()) // default value
376  {
377  returnColor[0] = 1.0;
378  returnColor[1] = 1.0;
379  returnColor[2] = 1.0;
380  MITK_ERROR << "Using default color for unknown hex color " << qPrintable(hexColor);
381  }
382  else
383  {
384  returnColor[0] = qColor.red() / colorMax;
385  returnColor[1] = qColor.green() / colorMax;
386  returnColor[2] = qColor.blue() / colorMax;
387  }
388  return returnColor;
389 }
390 
391 QString QmitkStdMultiWidgetEditor::MitkColorToHex(const mitk::Color& color)
392 {
393  QColor returnColor;
394  float colorMax = 255.0f;
395  returnColor.setRed(static_cast<int>(color[0] * colorMax + 0.5));
396  returnColor.setGreen(static_cast<int>(color[1] * colorMax + 0.5));
397  returnColor.setBlue(static_cast<int>(color[2] * colorMax + 0.5));
398  return returnColor.name();
399 }
void OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme)
virtual void ActivateMenuWidget(bool state)
virtual void SetConstrainedPanningZooming(bool _arg)
RenderWindowWidgetMap GetRenderWindowWidgets() const
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
virtual QmitkAbstractMultiWidget * GetMultiWidget() const
Return the current multi widget of this editor.
virtual QmitkLevelWindowWidget * GetLevelWindowWidget() const override
#define MITK_ERROR
Definition: mitkLogMacros.h:20
virtual ~QmitkStdMultiWidgetEditor() override
STL namespace.
virtual void SetMultiWidget(QmitkAbstractMultiWidget *multiWidget)
Set the current multi widget of this editor.
virtual void PartClosed(const berry::IWorkbenchPartReference::Pointer &partRef) override
Overridden from berry::IPartListener.
virtual bool IsSlicingPlanesEnabled() const override
Overridden from mitk::ILinkedRenderWindowPart.
virtual void EnableSlicingPlanes(bool enable) override
Overridden from mitk::ILinkedRenderWindowPart.
virtual void PartOpened(const berry::IWorkbenchPartReference::Pointer &partRef) override
Overridden from berry::IPartListener.
virtual bool GetBool(const QString &key, bool def) const =0
virtual void PartVisible(const berry::IWorkbenchPartReference::Pointer &partRef) override
Overridden from berry::IPartListener.
virtual berry::IPartListener::Events::Types GetPartEventTypes() const override
Overridden from berry::IPartListener.
virtual mitk::DataStorage::Pointer GetDataStorage() const
The &#39;QmitkStdMultiWidget&#39; is a &#39;QmitkAbstractMultiWidget&#39; that is used to display multiple render win...
static RenderingManager * GetInstance()
void SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer=nullptr)
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
virtual void OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme)
virtual QString Get(const QString &key, const QString &def) const =0
virtual void Put(const QString &key, const QString &value)=0
std::map< QString, std::shared_ptr< QmitkRenderWindowWidget > > RenderWindowWidgetMap
virtual void PartHidden(const berry::IWorkbenchPartReference::Pointer &partRef) override
Overridden from berry::IPartListener.
virtual int GetInt(const QString &key, int def) const =0
virtual void InitializeViewsByBoundingObjects(const DataStorage *)
Initializes the renderwindows by the aggregated geometry of all objects that are held in the data sto...
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
IWorkbenchPartSite::Pointer GetSite() const override
ObjectType * GetPointer() const
virtual berry::IPreferences::Pointer GetPreferences() const