MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
QmitkUSNavigationStepCombinedModality.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
13#include "ui_QmitkUSNavigationStepCombinedModality.h"
14
17
18
20
21#include <QFileDialog>
22#include <QTextStream>
23#include <QSettings>
24
25#include "mitkBaseRenderer.h"
26
29 m_LastCalibrationFilename(""),
30 m_CalibrationLoadedNecessary(true),
31 m_ListenerDeviceChanged(this, &QmitkUSNavigationStepCombinedModality::OnDevicePropertyChanged),
33{
34 ui->setupUi(this);
35
36 // combined modality create widget should only be visible after button press
37 ui->combinedModalityCreateWidget->setVisible(false);
38 ui->combinedModalityEditWidget->setVisible(false);
39
40 connect(ui->combinedModalityListWidget, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnDeviceSelectionChanged()));
41 connect(ui->combinedModalityListWidget, SIGNAL(ServiceModified(us::ServiceReferenceU)), this, SLOT(OnDeviceSelectionChanged()));
42 connect(ui->combinedModalityCreateWidget, SIGNAL(SignalAborted()), this, SLOT(OnCombinedModalityCreationExit()));
43 connect(ui->combinedModalityCreateWidget, SIGNAL(SignalCreated()), this, SLOT(OnCombinedModalityCreationExit()));
44
45 connect(ui->combinedModalityEditWidget, SIGNAL(SignalAborted()), this, SLOT(OnCombinedModalityEditExit()));
46 connect(ui->combinedModalityEditWidget, SIGNAL(SignalSaved()), this, SLOT(OnCombinedModalityEditExit()));
47
48 std::string filterOnlyCombinedModalities = "(&(" + us::ServiceConstants::OBJECTCLASS() + "=" + "org.mitk.services.AbstractUltrasoundTrackerDevice)(" + mitk::AbstractUltrasoundTrackerDevice::US_PROPKEY_CLASS + "=" + mitk::AbstractUltrasoundTrackerDevice::DeviceClassIdentifier + "))";
49 //std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "=" + "org.mitk.services.UltrasoundDevice))";
50 ui->combinedModalityListWidget->Initialize<mitk::AbstractUltrasoundTrackerDevice>(filterOnlyCombinedModalities);
51 ui->combinedModalityListWidget->SetAutomaticallySelectFirstEntry(true);
52
53 //try to load UI settings
54 QSettings settings;
55 settings.beginGroup(QString::fromStdString("QmitkUSNavigationStepCombinedModality"));
56 m_LastCalibrationFilename = settings.value("LastCalibrationFilename", QVariant("")).toString().toStdString();
57 MITK_DEBUG << "PERSISTENCE load: " << m_LastCalibrationFilename;
58 settings.endGroup();
59}
60
62{
63 ui->combinedModalityListWidget->blockSignals(true);
64 //save UI settings
65 QSettings settings;
66 settings.beginGroup(QString::fromStdString("QmitkUSNavigationStepCombinedModality"));
67 settings.setValue("LastCalibrationFilename", QVariant(m_LastCalibrationFilename.c_str()));
68 settings.endGroup();
69 MITK_DEBUG << "PERSISTENCE save: " << m_LastCalibrationFilename;
70 //delete UI
71 delete ui;
72}
73
75{
76 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetSelectedCombinedModality();
77 bool combinedModalitySelected = combinedModality.IsNotNull();
78
79 ui->calibrationGroupBox->setEnabled(combinedModalitySelected);
80 ui->combinedModalityDeleteButton->setEnabled(combinedModalitySelected);
81 ui->combinedModalitEditButton->setEnabled(combinedModalitySelected);
82
83 if (!combinedModalitySelected || m_CombinedModality != combinedModality)
84 {
86
87 if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetUltrasoundDevice().IsNotNull())
88 {
89 m_CombinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_ListenerDeviceChanged);
90 }
91
92 if (combinedModalitySelected && combinedModality->GetUltrasoundDevice().IsNotNull())
93 {
94 combinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_ListenerDeviceChanged);
95 }
96 }
97 m_CombinedModality = combinedModality;
98
99 if (combinedModalitySelected)
100 {
101 bool calibrated = this->UpdateCalibrationState();
102
104 else
105 {
106 if (calibrated) { emit SignalReadyForNextStep(); }
107 else { emit SignalNoLongerReadyForNextStep(); }
108 }
109
110 // enable disconnect button only if combined modality is connected or active
111 ui->combinedModalityDistconnectButton->setEnabled(combinedModality->GetUltrasoundDevice()->GetDeviceState() >= mitk::USDevice::State_Connected);
112 ui->combinedModalityActivateButton->setEnabled(combinedModality->GetUltrasoundDevice()->GetDeviceState() < mitk::USDevice::State_Activated);
113
115 }
116 else
117 {
118 ui->combinedModalityDistconnectButton->setEnabled(false);
119 ui->combinedModalityActivateButton->setEnabled(false);
120 }
121}
122
124{
125 QString filename = QFileDialog::getOpenFileName(QApplication::activeWindow(),
126 "Load Calibration",
128 "Calibration files *.cal");
129 m_LastCalibrationFilename = filename.toStdString();
130
131 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetSelectedCombinedModality();
132 if (combinedModality.IsNull())
133 {
134 ui->calibrationLoadStateLabel->setText("Selected device is no USCombinedModality.");
136 return;
137 }
138
139 if (filename.isEmpty())
140 {
141 bool calibrated = this->UpdateCalibrationState();
142 if (!calibrated) { emit SignalNoLongerReadyForNextStep(); }
143
144 return;
145 }
146
147 QFile file(filename);
148 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
149 {
150 MITK_WARN << "Cannot open file '" << filename.toStdString() << "' for reading.";
151 ui->calibrationLoadStateLabel->setText("Cannot open file '" + filename + "' for reading.");
153 return;
154 }
155
156 QTextStream inStream(&file);
157 m_LoadedCalibration = inStream.readAll().toStdString();
158 if (m_LoadedCalibration.empty())
159 {
160 MITK_WARN << "Failed to load file. Unsupported format?";
161 ui->calibrationLoadStateLabel->setText("Failed to load file. Unsupported format?");
163 return;
164 }
165
166 try
167 {
168 combinedModality->DeserializeCalibration(m_LoadedCalibration);
169 }
170 catch (const mitk::Exception& /*exception*/)
171 {
172 MITK_WARN << "Failed to deserialize calibration. Unsuppoerted format?";
173 ui->calibrationLoadStateLabel->setText("Failed to deserialize calibration. Unsuppoerted format?");
175 return;
176 }
177
178 ui->calibrationLoadStateLabel->setText("Loaded calibration : " + filename);
179
180 m_CombinedModality = combinedModality;
181
183}
184
189
191{
193 mitk::DataNode::Pointer usNode = mitk::RenderingManager::GetInstance()->GetDataStorage()->GetNamedNode("US Viewing Stream - Image 0");
194 if (usNode.IsNotNull())
195 {
196 mitk::RenderingManager::GetInstance()->InitializeViews(usNode->GetData()->GetTimeGeometry());
197 }
198 else
199 {
200 MITK_WARN << "No reinit possible";
201 }
202}
203
205{
207 ui->combinedModalityEditWidget->SetCombinedModality(nullptr);
208}
209
211{
212 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetSelectedCombinedModality();
213 if (combinedModality.IsNotNull())
214 {
215 combinedModality->RemoveAllObservers();
216 combinedModality->UnregisterOnService();
217 }
218}
219
221{
222 ui->combinedModalityEditWidget->SetCombinedModality(m_CombinedModality);
224}
225
227{
228 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetSelectedCombinedModality();
229 if (combinedModality.IsNotNull())
230 {
231 if (!combinedModality->GetUltrasoundDevice()->GetIsConnected()) { combinedModality->GetUltrasoundDevice()->Connect(); }
232 if (!combinedModality->GetUltrasoundDevice()->GetIsActive()) { combinedModality->GetUltrasoundDevice()->Activate(); }
233 }
234}
235
237{
238 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetSelectedCombinedModality();
239 if (combinedModality.IsNotNull())
240 {
241 if (combinedModality->GetUltrasoundDevice()->GetIsActive()) { combinedModality->GetUltrasoundDevice()->Deactivate(); }
242 if (combinedModality->GetUltrasoundDevice()->GetIsConnected()) { combinedModality->GetUltrasoundDevice()->Disconnect(); }
243 }
244}
245
250
255
257{
258 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetSelectedCombinedModality();
259 if (combinedModality.IsNotNull())
260 {
261 QApplication::setOverrideCursor(Qt::WaitCursor);
262 // make sure that the combined modality is in connected state before using it
263 if (combinedModality->GetUltrasoundDevice()->GetDeviceState() < mitk::USDevice::State_Connected) { combinedModality->GetUltrasoundDevice()->Connect(); }
264 if (combinedModality->GetUltrasoundDevice()->GetDeviceState() < mitk::USDevice::State_Activated) { combinedModality->GetUltrasoundDevice()->Activate(); }
265 QApplication::restoreOverrideCursor();
266 }
267
268 emit SignalCombinedModalityChanged(combinedModality);
269
271
272 return true;
273}
274
276{
277 // make sure that device selection status is up-to-date
279
280 return true;
281}
282
286
288{
289 return "Selection of Combined Modality";
290}
291
296
298{
299 ui->combinedModalityLabel->setVisible(!enabled);
300 ui->combinedModalityListWidget->setVisible(!enabled);
301 ui->combinedModalityCreateButton->setVisible(!enabled);
302 ui->combinedModalityDeleteButton->setVisible(!enabled);
303 ui->combinedModalitEditButton->setVisible(!enabled);
304 ui->combinedModalityActivateButton->setVisible(!enabled);
305 ui->combinedModalityDistconnectButton->setVisible(!enabled);
306 ui->helpLabel->setVisible(!enabled);
307 ui->calibrationGroupBox->setVisible(!enabled);
308 ui->combinedModalityCreateWidget->setVisible(enabled);
309}
310
312{
313 ui->combinedModalityLabel->setVisible(!enabled);
314 ui->combinedModalityListWidget->setVisible(!enabled);
315 ui->combinedModalityCreateButton->setVisible(!enabled);
316 ui->combinedModalityDeleteButton->setVisible(!enabled);
317 ui->combinedModalitEditButton->setVisible(!enabled);
318 ui->combinedModalityActivateButton->setVisible(!enabled);
319 ui->combinedModalityDistconnectButton->setVisible(!enabled);
320 ui->helpLabel->setVisible(!enabled);
321 ui->calibrationGroupBox->setVisible(!enabled);
322 ui->combinedModalityEditWidget->setVisible(enabled);
323}
324
326{
327 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetCombinedModality();
328 mitk::USDevice::Pointer usDevice = combinedModality->GetUltrasoundDevice();
329
330 // save identifiers and calibration to a result object
331 mitk::DataNode::Pointer combinedModalityResult = mitk::DataNode::New();
332 combinedModalityResult->SetName("CombinedModalityResult");
333 combinedModalityResult->SetStringProperty("USNavigation::CombinedModality",
334 std::string(combinedModality->GetUltrasoundDevice()->GetManufacturer() + ": " + combinedModality->GetUltrasoundDevice()->GetName()
335 + " (" + combinedModality->GetUltrasoundDevice()->GetComment() + ")").c_str());
336 combinedModalityResult->SetStringProperty("USNavigation::UltrasoundDevice",
337 std::string(usDevice->GetManufacturer() + ": " + usDevice->GetName()
338 + " (" + usDevice->GetComment() + ")").c_str());
339 combinedModalityResult->SetStringProperty("USNavigation::TrackingDevice",
340 combinedModality->GetNavigationDataSource()->GetName().c_str());
341 combinedModalityResult->SetStringProperty("USNavigation::Calibration",
342 combinedModality->SerializeCalibration().c_str());
343
344 emit SignalIntermediateResult(combinedModalityResult);
345}
346
348{
349 if (m_CombinedModality.IsNull()) { return false; }
350
351 bool calibrated = m_CombinedModality->GetContainsAtLeastOneCalibration();
352
353 if (calibrated) { ui->calibrationLoadStateLabel->setText("Selected device contains at least one calibration."); }
354 else { ui->calibrationLoadStateLabel->setText("Selected device is not calibrated."); }
355
356 return calibrated;
357}
358
359mitk::AbstractUltrasoundTrackerDevice::Pointer QmitkUSNavigationStepCombinedModality::GetSelectedCombinedModality()
360{
361 // nothing more to do if no device is selected at the moment
362 if (!ui->combinedModalityListWidget->GetIsServiceSelected()) { return nullptr; }
363
364 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = ui->combinedModalityListWidget->GetSelectedService<mitk::AbstractUltrasoundTrackerDevice>();
365
366 if (combinedModality.IsNull())
367 {
368 MITK_WARN << "Selected device is no USCombinedModality.";
369 }
370
371 return combinedModality;
372}
373
378
379void QmitkUSNavigationStepCombinedModality::OnDevicePropertyChanged(const std::string& key, const std::string&)
380{
381 // property changes only matter if the navigation step is currently active
382 // (being sensitive to them in other states may even be dangerous)
384
385 // calibration state could have changed if the depth was changed
386 if (key == mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH)
387 {
388 bool calibrated = this->UpdateCalibrationState();
389 if (calibrated) { emit SignalReadyForNextStep(); }
390 else { emit SignalNoLongerReadyForNextStep(); }
391 }
392}
393
395{
396 //check if everything is initialized
397 if (m_CombinedModality.IsNull()) { return; }
398 mitk::NavigationDataSource::Pointer navigationDataSource = m_CombinedModality->GetNavigationDataSource();
399 if (navigationDataSource.IsNull()) { return; }
400 if (GetDataStorage(false).IsNull()) { return; }
401
402 // get the settings node
403 mitk::DataNode::Pointer settingsNode = this->GetNamedDerivedNode(DATANAME_SETTINGS, DATANAME_BASENODE);
404 std::string needleNames;
405
406 itk::ProcessObject::DataObjectPointerArray outputs = navigationDataSource->GetOutputs();
407 for (itk::ProcessObject::DataObjectPointerArray::iterator it = outputs.begin(); it != outputs.end(); ++it)
408 {
409 needleNames += std::string((static_cast<mitk::NavigationData*>(it->GetPointer()))->GetName()) + ";";
410 }
411
412 // change the settings node only if the settings changed
413 std::string oldProperty;
414 if (!settingsNode->GetStringProperty("settings.needle-names", oldProperty)
415 || oldProperty != needleNames
416 || !settingsNode->GetStringProperty("settings.reference-names", oldProperty)
417 || oldProperty != needleNames)
418 {
419 settingsNode->SetStringProperty("settings.needle-names", needleNames.c_str());
420 settingsNode->SetStringProperty("settings.reference-names", needleNames.c_str());
421
422 emit SignalSettingsNodeChanged(settingsNode);
423 }
424}
Abstract base class for navigation step widgets.
itk::SmartPointer< mitk::DataStorage > GetDataStorage(bool throwNull=true)
Returns the data storage set for the navigation step.
void SignalNoLongerReadyForNextStep()
Signals that it is no longer possible to proceed with following steps. This signal is emitted when th...
NavigationStepState GetNavigationStepState()
Get the current state of the navigation step.
void SignalSettingsNodeChanged(itk::SmartPointer< mitk::DataNode >)
Signals that the settings node was changed. This signal must not be emitted in an OnSettingsChanged()...
void SignalReadyForNextStep()
Signals that all necessary actions where done. The user can proceed with the next stept after this wa...
void SignalCombinedModalityChanged(itk::SmartPointer< mitk::AbstractUltrasoundTrackerDevice >)
Signals that the combined modality was changed by this step. This signal is mainly for steps which cr...
itk::SmartPointer< mitk::AbstractUltrasoundTrackerDevice > GetCombinedModality(bool throwNull=true)
Returns the combined modality set for the navigation step.
void SignalIntermediateResult(const itk::SmartPointer< mitk::DataNode >)
Signals that an intermediate result was produced. The properties of the given data node must contain ...
itk::SmartPointer< mitk::DataNode > GetNamedDerivedNode(const char *name, const char *sourceName)
Returns node with the given name and the given source node (parent) from the data storage.
Navigation step for creating and selecting a combined modality. Already created combined modalities c...
void OnCombinedModalityCreateNewButtonClicked()
Triggered, when the button for creating a new combined modality was clicked.
bool GetIsRestartable() override
Indicates if it makes sense to be able to restart the step. This method must be implemented by concre...
void OnCombinedModalityCreationExit()
Triggered, when the dialog for creating a new combined modality was closed.
bool OnRestartStep() override
Called when restarting a navigation step. This method may be implemented by a concrete subclass to ha...
bool OnStartStep() override
Called when the navigation step gets started. This method has to be implemented by a concrete subclas...
QString GetTitle() override
Getter for the title of the navigation step. This title should be human readable and can be used to d...
void OnDisconnectButtonClicked()
Triggered, when the button for disconnecting a combined modality was clicked. The state of the combin...
itk::SmartPointer< mitk::AbstractUltrasoundTrackerDevice > m_CombinedModality
The Combined Modality which was selected by the user.
void OnLoadCalibration()
Triggered, when the user has clicked "Load Calibration". Opens a file open dialog and sets the select...
void OnDeleteButtonClicked()
Triggered, when the button for deleting a combined modality was clicked. Unregisters the combined mod...
void OnDeviceSelectionChanged()
Triggered, when the selection in the service list widget has changed.
void OnUpdate() override
Called periodically while a navigation step is active. This method has to be implemented by a concret...
bool OnFinishStep() override
Called when all necessary actions for the step where done. This method has to be implemented by a con...
mitk::AbstractUltrasoundTrackerDevice::Pointer GetSelectedCombinedModality()
void OnDevicePropertyChanged(const std::string &, const std::string &)
bool OnActivateStep() override
Called when the navigation step gets activated. This method has to be implemented by a concrete subcl...
Abstract class for an easy handling of a combination of an USDevice and a NavigationDataSource....
static mitk::USDevice::PropertyKeys GetPropertyKeys()