Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkFileSaveAction.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 
13 #include "QmitkFileSaveAction.h"
14 
15 #include "internal/org_mitk_gui_qt_application_Activator.h"
16 
17 #include <mitkWorkbenchUtil.h>
18 #include <mitkDataNodeSelection.h>
20 
21 #include <berryISelectionService.h>
23 #include <berryIPreferences.h>
24 
25 #include <QmitkIOUtil.h>
26 
27 #include <QFileDialog>
28 #include <QMessageBox>
29 
30 namespace
31 {
32  mitk::DataStorage::Pointer GetDataStorage()
33  {
34  auto context = mitk::org_mitk_gui_qt_application_Activator::GetContext();
35 
36  if (nullptr == context)
37  return nullptr;
38 
39  auto dataStorageServiceReference = context->getServiceReference<mitk::IDataStorageService>();
40 
41  if (!dataStorageServiceReference)
42  return nullptr;
43 
44  auto dataStorageService = context->getService<mitk::IDataStorageService>(dataStorageServiceReference);
45 
46  if (nullptr == dataStorageService)
47  return nullptr;
48 
49  auto dataStorageReference = dataStorageService->GetDataStorage();
50 
51  if (dataStorageReference.IsNull())
52  return nullptr;
53 
54  return dataStorageReference->GetDataStorage();
55  }
56 
57  QString GetParentPath(mitk::DataNode::Pointer dataNode)
58  {
59  if (dataNode.IsNull())
60  return "";
61 
62  auto dataStorage = GetDataStorage();
63 
64  if (dataStorage.IsNull())
65  return "";
66 
67  auto sources = dataStorage->GetSources(dataNode);
68 
69  if (sources.IsNull() || sources->empty())
70  return "";
71 
72  const auto &parentNode = sources->front();
73 
74  if (parentNode.IsNull())
75  return "";
76 
77  auto data = parentNode->GetData();
78 
79  if (nullptr != data)
80  {
81  auto pathProperty = data->GetConstProperty("path");
82 
83  if (pathProperty.IsNotNull())
84  return QFileInfo(QString::fromStdString(pathProperty->GetValueAsString())).canonicalPath();
85  }
86 
87  return GetParentPath(parentNode);
88  }
89 }
90 
91 class QmitkFileSaveActionPrivate
92 {
93 private:
94 
95  void HandleSelectionChanged(const berry::IWorkbenchPart::Pointer& /*part*/,
96  const berry::ISelection::ConstPointer& selection)
97  {
98  this->SetEnabled(selection);
99  }
100 
101  QScopedPointer<berry::ISelectionListener> m_SelectionListener;
102 
103 public:
104 
105  QmitkFileSaveActionPrivate()
106  : m_SelectionListener(new berry::NullSelectionChangedAdapter<QmitkFileSaveActionPrivate>(
107  this, &QmitkFileSaveActionPrivate::HandleSelectionChanged))
108  {
109  }
110 
111  ~QmitkFileSaveActionPrivate()
112  {
113  if (!m_Window.Expired())
114  {
115  m_Window.Lock()->GetSelectionService()->RemoveSelectionListener(m_SelectionListener.data());
116  }
117  }
118 
119  void Init(berry::IWorkbenchWindow* window, QAction* action)
120  {
121  m_Window = berry::IWorkbenchWindow::Pointer(window);
122  m_Action = action;
123 
124  m_Action->setText("&Save...");
125  m_Action->setToolTip("Save data objects (images, surfaces,...)");
126 
127  berry::ISelectionService* selectionService = m_Window.Lock()->GetSelectionService();
128  SetEnabled(selectionService->GetSelection());
129 
130  selectionService->AddSelectionListener(m_SelectionListener.data());
131 
132  QObject::connect(m_Action, SIGNAL(triggered(bool)), m_Action, SLOT(Run()));
133  }
134 
135  berry::IPreferences::Pointer GetPreferences() const
136  {
137  berry::IPreferencesService* prefService = mitk::PluginActivator::GetInstance()->GetPreferencesService();
138  if (prefService != nullptr)
139  {
140  return prefService->GetSystemPreferences()->Node("/General");
141  }
142  return berry::IPreferences::Pointer(nullptr);
143  }
144 
145  QString GetLastFileSavePath() const
146  {
147  berry::IPreferences::Pointer prefs = GetPreferences();
148  if (prefs.IsNotNull())
149  {
150  return prefs->Get("LastFileSavePath", "");
151  }
152  return QString();
153  }
154 
155  void SetLastFileSavePath(const QString& path) const
156  {
157  berry::IPreferences::Pointer prefs = GetPreferences();
158  if (prefs.IsNotNull())
159  {
160  prefs->Put("LastFileSavePath", path);
161  prefs->Flush();
162  }
163  }
164 
165  void SetEnabled(berry::ISelection::ConstPointer selection)
166  {
167  mitk::DataNodeSelection::ConstPointer nodeSelection = selection.Cast<const mitk::DataNodeSelection>();
168  if (nodeSelection.IsNotNull() && !selection->IsEmpty())
169  {
170  bool enable = false;
171  std::list<mitk::DataNode::Pointer> dataNodes = nodeSelection->GetSelectedDataNodes();
172  for (std::list<mitk::DataNode::Pointer>::const_iterator nodeIter = dataNodes.begin(), nodeIterEnd = dataNodes.end(); nodeIter != nodeIterEnd; ++nodeIter)
173  {
174  if ((*nodeIter)->GetData() != nullptr)
175  {
176  enable = true;
177  break;
178  }
179  }
180  m_Action->setEnabled(enable);
181  }
182  else
183  {
184  m_Action->setEnabled(false);
185  }
186  }
187 
189  QAction* m_Action;
190 };
191 
193  : QAction(tr("Save..."))
194  , d(new QmitkFileSaveActionPrivate)
195 {
196  d->Init(window.GetPointer(), this);
197 }
198 
200  : QAction(tr("Save..."))
201  , d(new QmitkFileSaveActionPrivate)
202 {
203  d->Init(window.GetPointer(), this);
204  setIcon(icon);
205 }
206 
208  : QAction(tr("Save..."))
209  , d(new QmitkFileSaveActionPrivate)
210 {
211  d->Init(window, this);
212  setIcon(icon);
213 }
214 
216 {
217 }
218 
220 {
221  // get the list of selected base data objects
222  mitk::DataNodeSelection::ConstPointer selection = d->m_Window.Lock()->GetSelectionService()->GetSelection().Cast<const mitk::DataNodeSelection>();
223  if (selection.IsNull() || selection->IsEmpty())
224  {
225  MITK_ERROR << "Assertion failed: data node selection is nullptr or empty";
226  return;
227  }
228 
229  std::list<mitk::DataNode::Pointer> dataNodes = selection->GetSelectedDataNodes();
230 
231  std::vector<const mitk::BaseData*> data;
232  QStringList names;
233  for (std::list<mitk::DataNode::Pointer>::const_iterator nodeIter = dataNodes.begin(), nodeIterEnd = dataNodes.end(); nodeIter != nodeIterEnd; ++nodeIter)
234  {
235  data.push_back((*nodeIter)->GetData());
236  std::string name;
237  (*nodeIter)->GetStringProperty("name", name);
238  names.push_back(QString::fromStdString(name));
239  }
240 
241  QString path;
242 
243  if (1 == data.size())
244  {
245  if (nullptr != data[0])
246  {
247  auto pathProperty = data[0]->GetConstProperty("path");
248 
249  if (pathProperty.IsNotNull())
250  path = QFileInfo(QString::fromStdString(pathProperty->GetValueAsString())).canonicalPath();
251  }
252 
253  if (path.isEmpty())
254  path = GetParentPath(dataNodes.front());
255  }
256 
257  if (path.isEmpty())
258  path = d->GetLastFileSavePath();
259 
260  try
261  {
262  auto setPathProperty = true;
263  auto fileNames = QmitkIOUtil::Save(data, names, path, d->m_Action->parentWidget(), setPathProperty);
264 
265  if (!fileNames.empty())
266  d->SetLastFileSavePath(QFileInfo(fileNames.back()).absolutePath());
267  }
268  catch (const mitk::Exception& e)
269  {
270  MITK_INFO << e;
271  return;
272  }
273 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
#define MITK_ERROR
Definition: mitkLogMacros.h:20
SmartPointer< Other > Cast() const
virtual IDataStorageReference::Pointer GetDataStorage() const =0
virtual SmartPointer< IPreferences > GetSystemPreferences()=0
virtual ISelection::ConstPointer GetSelection() const =0
berry::SmartPointer< Self > Pointer
Definition: berryObject.h:82
QmitkFileSaveAction(berry::IWorkbenchWindow::Pointer window)
An object of this class represents an exception of MITK. Please don&#39;t instantiate exceptions manually...
Definition: mitkException.h:45
virtual void AddSelectionListener(ISelectionListener *listener)=0
static QString Save(const mitk::BaseData *data, const QString &defaultBaseName, const QString &defaultPath=QString(), QWidget *parent=nullptr, bool setPathProperty=false)
void Run(berry::IWorkbenchPartSite::Pointer workbenchPartSite, mitk::DataStorage::Pointer dataStorage)
berry::SmartPointer< Self > Pointer
ObjectType * GetPointer() const