fw4spl
ioDcmtk/src/ioDcmtk/SSeriesDBReader.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "ioDcmtk/SSeriesDBReader.hpp"
8 
9 #include <fwCom/Signal.hpp>
10 #include <fwCom/Signal.hxx>
11 #include <fwCom/Signals.hpp>
12 
13 #include <fwCore/base.hpp>
14 
15 #include <fwData/String.hpp>
16 
17 #include <fwDcmtkIO/SeriesDBReader.hpp>
18 
19 #include <fwGui/Cursor.hpp>
20 #include <fwGui/dialog/LocationDialog.hpp>
21 #include <fwGui/dialog/MessageDialog.hpp>
22 #include <fwGui/dialog/ProgressDialog.hpp>
23 
24 #include <fwIO/IReader.hpp>
25 
26 #include <fwMedData/SeriesDB.hpp>
27 
28 #include <fwServices/macros.hpp>
29 #include <fwServices/op/Add.hpp>
30 #include <fwServices/registry/ServiceConfig.hpp>
31 
32 #include <fwTools/ProgressToLogger.hpp>
33 
34 namespace ioDcmtk
35 {
36 
37 fwServicesRegisterMacro( ::fwIO::IReader, ::ioDcmtk::SSeriesDBReader, ::fwMedData::SeriesDB );
38 
39 //------------------------------------------------------------------------------
40 
42 {
43 }
44 
45 //------------------------------------------------------------------------------
46 
48 {
49 }
50 
51 //------------------------------------------------------------------------------
52 
54 {
55  static ::boost::filesystem::path _sDefaultPath;
56 
58  dialogFile.setTitle(m_windowTitle.empty() ? this->getSelectorDialogTitle() : m_windowTitle);
59  dialogFile.setDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath) );
60  dialogFile.setOption(::fwGui::dialog::ILocationDialog::READ);
61  dialogFile.setType(::fwGui::dialog::LocationDialog::FOLDER);
62 
63  ::fwData::location::Folder::sptr result;
64  result = ::fwData::location::Folder::dynamicCast( dialogFile.show() );
65  if (result)
66  {
67  _sDefaultPath = result->getFolder();
68  this->setFolder( result->getFolder() );
69  dialogFile.saveDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath) );
70  }
71 
72  // Select filter
73  if(!m_filterSelectorSrvConfig.empty())
74  {
75  // Get the config
76  ::fwRuntime::ConfigurationElement::csptr filterSelectorConfig;
77  filterSelectorConfig = ::fwServices::registry::ServiceConfig::getDefault()->getServiceConfig(
78  m_filterSelectorSrvConfig, "::ioDicom::SFilterSelectorDialog");
79 
80  SLM_ASSERT("There is no service configuration "
81  + m_filterSelectorSrvConfig
82  + " for ::ioDicom::SFilterSelectorDialog", filterSelectorConfig);
83 
84  // Init and execute the service
85  ::fwServices::IService::sptr filterSelectorSrv;
86  ::fwData::String::sptr key = ::fwData::String::New();
87  filterSelectorSrv = ::fwServices::add(key,
88  "::fwGui::editor::IDialogEditor",
89  "::ioDicom::SFilterSelectorDialog");
90  filterSelectorSrv->setConfiguration( ::fwRuntime::ConfigurationElement::constCast(filterSelectorConfig) );
91  filterSelectorSrv->configure();
92  filterSelectorSrv->start();
93  filterSelectorSrv->update();
94  filterSelectorSrv->stop();
95  ::fwServices::OSR::unregisterService( filterSelectorSrv );
96 
97  m_filterType = key->getValue();
98 
99  }
100 }
101 
102 //------------------------------------------------------------------------------
103 
105 {
107 
108  // Use filter selector
109  ::fwRuntime::ConfigurationElement::sptr selectorConfig =
110  m_configuration->findConfigurationElement("FilterSelectorSrvConfig");
111  if(selectorConfig)
112  {
113  SLM_ASSERT("Missing 'name' attribute", selectorConfig->hasAttribute("name"));
114  m_filterSelectorSrvConfig = selectorConfig->getAttributeValue("name");
115  }
116 
117  // Get SOP Class selection
118  const ::fwRuntime::ConfigurationElement::sptr sopClassSelection =
119  m_configuration->findConfigurationElement("SOPClassSelection");
120  if(sopClassSelection)
121  {
123  sopClassSelection->findAllConfigurationElement("SOPClass");
124 
125  for(::fwRuntime::ConfigurationElementContainer::Iterator it = sopClassElements.begin();
126  it != sopClassElements.end(); ++it)
127  {
128  const ::fwRuntime::ConfigurationElement::AttributePair attributePair = (*it)->getSafeAttributeValue("uid");
129  if(attributePair.first)
130  {
131  SLM_TRACE("New SOP class supported : " + attributePair.second);
132  m_supportedSOPClassSelection.push_back(attributePair.second);
133  }
134  }
135  }
136 
137  // Set filter
138  ::fwRuntime::ConfigurationElement::sptr config = m_configuration->findConfigurationElement("config");
139  if(config)
140  {
141  m_filterType = config->getAttributeValue("filterType");
142  }
143 }
144 
145 //------------------------------------------------------------------------------
146 
148 {
149  SLM_TRACE_FUNC();
150 }
151 
152 //------------------------------------------------------------------------------
153 
155 {
156  SLM_TRACE_FUNC();
157 }
158 
159 //------------------------------------------------------------------------------
160 
161 void SSeriesDBReader::info(std::ostream& _sstream )
162 {
163  _sstream << "SSeriesDBReader::info";
164 }
165 
166 //------------------------------------------------------------------------------
167 
169 {
170  return "Choose a directory with DICOM images";
171 }
172 
173 //------------------------------------------------------------------------------
174 
175 ::fwMedData::SeriesDB::sptr SSeriesDBReader::createSeriesDB(const ::boost::filesystem::path& dicomDir)
176 {
177  SLM_TRACE_FUNC();
178  ::fwDcmtkIO::SeriesDBReader::sptr myLoader = ::fwDcmtkIO::SeriesDBReader::New();
179  ::fwMedData::SeriesDB::sptr dummy = ::fwMedData::SeriesDB::New();
180  myLoader->setObject(dummy);
181  myLoader->setFolder(dicomDir);
182  myLoader->setDicomFilterType(m_filterType);
183  myLoader->setSupportedSOPClassContainer(m_supportedSOPClassSelection);
184 
185  if(myLoader->isDicomDirAvailable())
186  {
188  messageBox.setTitle("Dicomdir file");
189  messageBox.setMessage( "There is a dicomdir file in the root folder. "
190  "Would you like to use it for the reading process ?" );
191  messageBox.setIcon(::fwGui::dialog::IMessageDialog::QUESTION);
192  messageBox.addButton(::fwGui::dialog::IMessageDialog::YES_NO);
193  ::fwGui::dialog::IMessageDialog::Buttons button = messageBox.show();
194 
195  myLoader->setDicomdirActivated(button == ::fwGui::dialog::IMessageDialog::YES);
196  }
197 
198  try
199  {
200  ::fwGui::dialog::ProgressDialog progressMeterGUI("Loading Dicom Image");
201  myLoader->addHandler( progressMeterGUI );
202  myLoader->read();
203  }
204  catch (const std::exception& e)
205  {
206  std::stringstream ss;
207  ss << "Warning during loading : " << e.what();
209  "Warning", ss.str(), ::fwGui::dialog::IMessageDialog::WARNING);
210  }
211  catch( ... )
212  {
214  "Warning", "Warning during loading", ::fwGui::dialog::IMessageDialog::WARNING);
215  }
216 
217  return myLoader->getConcreteObject();
218 }
219 
220 //------------------------------------------------------------------------------
221 
223 {
224  SLM_TRACE_FUNC();
225  if( this->hasLocationDefined() )
226  {
227  ::fwMedData::SeriesDB::sptr seriesDB = createSeriesDB( this->getFolder() );
228 
229  if( seriesDB->size() > 0 )
230  {
231  // Retrieve dataStruct associated with this service
232  ::fwMedData::SeriesDB::sptr associatedSeriesDB =
233  this->getInOut< ::fwMedData::SeriesDB >(::fwIO::s_DATA_KEY);
234  SLM_ASSERT("associated SeriesDB not instanced", associatedSeriesDB);
235  associatedSeriesDB->shallowCopy( seriesDB );
236 
237  ::fwGui::Cursor cursor;
238  cursor.setCursor(::fwGui::ICursor::BUSY);
239  this->notificationOfDBUpdate();
240  cursor.setDefaultCursor();
241  }
242  else
243  {
245  "Image Reader", "This file can not be read. Retry with another file reader.",
246  ::fwGui::dialog::IMessageDialog::WARNING);
247  }
248  }
249 }
250 
251 //------------------------------------------------------------------------------
252 
253 void SSeriesDBReader::notificationOfDBUpdate()
254 {
255  ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >(::fwIO::s_DATA_KEY);
256  SLM_ASSERT("Unable to get seriesDB", seriesDB);
257 
258  ::fwMedData::SeriesDB::ContainerType addedSeries;
259  for(const ::fwMedData::Series::sptr& s : seriesDB->getContainer() )
260  {
261  addedSeries.push_back(s);
262  }
263 
264  auto sig = seriesDB->signal< ::fwMedData::SeriesDB::AddedSeriesSignalType >(
266  sig->asyncEmit(addedSeries);
267 }
268 
269 //-----------------------------------------------------------------------------
270 
272 {
273  return ::fwIO::FOLDER;
274 }
275 
276 //------------------------------------------------------------------------------
277 
278 } // namespace ioDcmtk
virtual FWGUI_API void setCursor(::fwGui::ICursor::CursorType cursor) override
Set the cursor.
std::string m_windowTitle
Title of the window that will open when the configureWithIHM slot is called.
Definition: IReader.hpp:207
FWRUNTIME_API Iterator begin()
Retrieves the iterator on the first managed configuration element.
#define SLM_TRACE_FUNC()
Trace contextual function signature.
Definition: spyLog.hpp:329
FWIO_API bool hasLocationDefined() const
Returns if a location has been defined ( by the configuration process or directly by user ) ...
Definition: IReader.cpp:233
virtual FWGUI_API void setMessage(const std::string &msg) override
Set the message.
virtual FWIO_API void configuring() override
This method proposes to parse xml configuration to retrieve file/files/folder paths.
Definition: IReader.cpp:144
Defines the generic message box for IHM. Use the Delegate design pattern.
static FWGUI_API IMessageDialog::Buttons showMessageDialog(const std::string &title, const std::string &message,::fwGui::dialog::IMessageDialog::Icons icon=INFO)
virtual FWGUI_API void setDefaultLocation(::fwData::location::ILocation::sptr loc) override
Set the initial location for the dialog.
FWGUI_API::fwGui::dialog::ILocationDialog & setOption(::fwGui::dialog::ILocationDialog::Options option) override
allow to set option to the file dialog mode=READ/WRITE, check=FILE_MUST_EXIST
FWGUI_API::fwData::location::ILocation::sptr show() override
Display the dialog.
FWRUNTIME_API ConfigurationElementContainer findAllConfigurationElement(const std::string &name) const
Retrieves the configurations corresponding to the specified name.
FWIO_APIconst::boost::filesystem::path & getFolder() const
Returns folder path set by the user or set during service configuration.
Definition: IReader.cpp:97
Defines the generic progress dialog for IHM. Use the Delegate design pattern. The specific implementa...
virtual IODCMTK_API void stopping() override
Override.
virtual IODCMTK_API ~SSeriesDBReader() noexcept
destructor
virtual FWGUI_API void addButton(IMessageDialog::Buttons button) override
Add a button (OK, YES_NO, YES, NO, CANCEL)
IODCMTK_API::fwIO::IOPathType getIOPathType() const override
Return path type managed by the service, here FOLDER.
virtual IODCMTK_API void configuring() override
static FWMEDDATA_APIconst::fwCom::Signals::SignalKeyType s_ADDED_SERIES_SIG
Type of signal when series are added.
IODCMTK_API SSeriesDBReader() noexcept
constructor
virtual FWGUI_API IMessageDialog::Buttons show() override
Show the message box and return the clicked button.
Reader service API. It manages extension points definition and extension configuration.
Definition: IReader.hpp:34
virtual IODCMTK_API std::string getSelectorDialogTitle() override
Override.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
IODCMTK_API void info(std::ostream &_sstream) override
Override.
virtual IODCMTK_API void configureWithIHM() override
Override.
::fwRuntime::ConfigurationElement::sptr m_configuration
Configuration element used to configure service internal state using a generic XML like structure TOD...
Definition: IService.hpp:670
virtual FWGUI_API void setIcon(IMessageDialog::Icons icon) override
Set the icon (CRITICAL, WARNING, INFO or QUESTION)
IOPathType
IOPathType defines different type of paths used by service readers/writers.
Definition: ioTypes.hpp:19
#define SLM_TRACE(message)
Definition: spyLog.hpp:228
IODCMTK_API void updating() override
Override.
FWGUI_API void setTitle(const std::string &title) override
Set the title for the dialog.
virtual IODCMTK_API void starting() override
Override.
Defines the generic file/folder selector dialog for IHM.
Defines the generic configuration element container class.
Defines the generic cursor for IHM. Use the Delegate design pattern.
Read ImageSeries from DICOM with dcmtk.
static FWSERVICES_API ServiceConfig::sptr getDefault()
Return the default global instance of ServiceConfig.
ioDcmtk contains services use to deal with DICOM using the GDCM library.
FWRUNTIME_API Iterator end()
Retrieves the iterator on the end of the configuration element container.
FWIO_API void setFolder(const ::boost::filesystem::path &folder)
Sets folder path.
Definition: IReader.cpp:106
Container::iterator Iterator
Defines the configuration element container type.
FWGUI_API void setType(::fwGui::dialog::ILocationDialog::Types type) override
Set the type of location for the dialog (SINGLE_FILE, FORLDER, MULTI_FILES)
FWGUI_API void saveDefaultLocation(::fwData::location::ILocation::sptr loc) override
Save the specified default location for the dialog in preferences (if available)
virtual FWGUI_API void setTitle(const std::string &title) override
Set the title of the message box.
virtual FWGUI_API void setDefaultCursor() override
Set the default cursor.