fw4spl
SSeriesDBWriter.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 "ioGdcm/SSeriesDBWriter.hpp"
8 
9 #include <fwCore/base.hpp>
10 
11 #include <fwData/location/Folder.hpp>
12 #include <fwData/Vector.hpp>
13 
14 #include <fwGdcmIO/helper/Fiducial.hpp>
15 #include <fwGdcmIO/writer/SeriesDB.hpp>
16 
17 #include <fwGui/Cursor.hpp>
18 #include <fwGui/dialog/LocationDialog.hpp>
19 #include <fwGui/dialog/MessageDialog.hpp>
20 #include <fwGui/dialog/ProgressDialog.hpp>
21 #include <fwGui/dialog/SelectorDialog.hpp>
22 
23 #include <fwIO/IWriter.hpp>
24 
25 #include <fwMedData/Series.hpp>
26 #include <fwMedData/SeriesDB.hpp>
27 
28 #include <fwMedDataTools/helper/SeriesDB.hpp>
29 
30 #include <fwServices/macros.hpp>
31 
32 #include <fwTools/ProgressToLogger.hpp>
33 
34 namespace ioGdcm
35 {
36 
37 fwServicesRegisterMacro( ::fwIO::IWriter, ::ioGdcm::SSeriesDBWriter, ::fwData::Vector );
38 
39 //------------------------------------------------------------------------------
40 
42  m_fiducialsExportMode(::fwGdcmIO::writer::Series::COMPREHENSIVE_3D_SR)
43 {
44 }
45 
46 //------------------------------------------------------------------------------
47 
49 {
50 }
51 
52 //------------------------------------------------------------------------------
53 
55 {
56  static ::boost::filesystem::path _sDefaultPath;
57 
59  dialogFile.setTitle(m_windowTitle.empty() ? "Choose a directory for DICOM images" : m_windowTitle);
60  dialogFile.setDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath) );
61  dialogFile.setOption(::fwGui::dialog::ILocationDialog::WRITE);
62  dialogFile.setType(::fwGui::dialog::LocationDialog::FOLDER);
63 
64  ::fwData::location::Folder::sptr result;
65  result = ::fwData::location::Folder::dynamicCast( dialogFile.show() );
66  if (result && this->selectFiducialsExportMode())
67  {
68  _sDefaultPath = result->getFolder();
69  this->setFolder( result->getFolder() );
70  dialogFile.saveDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath) );
71  }
72  else
73  {
74  this->clearLocations();
75  }
76 }
77 
78 //------------------------------------------------------------------------------
79 
81 {
82 }
83 
84 //------------------------------------------------------------------------------
85 
87 {
88 }
89 
90 //------------------------------------------------------------------------------
91 
93 {
95 }
96 
97 //------------------------------------------------------------------------------
98 
100 {
101  if( this->hasLocationDefined() )
102  {
103  const ::boost::filesystem::path& folder = this->getFolder();
104  if(!::boost::filesystem::is_empty(folder))
105  {
107  dialog.setMessage("Folder '"+folder.string()+"' isn't empty, files can be overwritten."
108  "\nDo you want to continue ?");
109  dialog.setTitle("Folder not empty.");
110  dialog.setIcon(::fwGui::dialog::MessageDialog::QUESTION);
111  dialog.addButton( ::fwGui::dialog::MessageDialog::YES_NO );
113 
114  if(button == ::fwGui::dialog::MessageDialog::NO)
115  {
116  return;
117  }
118  }
119 
120  // Retrieve dataStruct associated with this service
121  ::fwData::Vector::csptr vector = this->getInput< ::fwData::Vector >(::fwIO::s_DATA_KEY);
122 
123  // Create SeriesDB
124  ::fwMedData::SeriesDB::sptr seriesDB = ::fwMedData::SeriesDB::New();
125  ::fwMedDataTools::helper::SeriesDB seriesDBHelper(seriesDB);
126 
127  for(const ::fwData::Object::sptr& object : vector->getContainer())
128  {
129  ::fwMedData::Series::sptr series = ::fwMedData::Series::dynamicCast(object);
130  SLM_ASSERT("The container should only contain series.", series);
131  seriesDBHelper.add(series);
132  }
133 
134  ::fwGui::Cursor cursor;
135  cursor.setCursor(::fwGui::ICursor::BUSY);
136  this->saveSeriesDB(folder, seriesDB);
137  cursor.setDefaultCursor();
138  }
139 }
140 
141 //------------------------------------------------------------------------------
142 
143 void SSeriesDBWriter::saveSeriesDB( const ::boost::filesystem::path folder, ::fwMedData::SeriesDB::sptr seriesDB )
144 {
145  ::fwGdcmIO::writer::SeriesDB::sptr writer = ::fwGdcmIO::writer::SeriesDB::New();
146  writer->setObject(seriesDB);
147  writer->setFiducialsExportMode(m_fiducialsExportMode);
148  ::fwData::location::Folder::sptr loc = ::fwData::location::Folder::New();
149  loc->setFolder(folder);
150  writer->setLocation(loc);
151 
152  try
153  {
154  ::fwGui::dialog::ProgressDialog progressMeterGUI("Saving series ");
155  writer->addHandler( progressMeterGUI );
156  writer->write();
157  }
158  catch (const std::exception& e)
159  {
160  std::stringstream ss;
161  ss << "Warning during saving : " << e.what();
163  "Warning", ss.str(), ::fwGui::dialog::IMessageDialog::WARNING);
164  }
165  catch( ... )
166  {
168  "Warning", "Warning during saving", ::fwGui::dialog::IMessageDialog::WARNING);
169  }
170 }
171 
172 //-----------------------------------------------------------------------------
173 
175 {
176  return ::fwIO::FOLDER;
177 }
178 
179 //------------------------------------------------------------------------------
180 
181 bool SSeriesDBWriter::selectFiducialsExportMode()
182 {
183  // Retrieve dataStruct associated with this service
184  ::fwData::Vector::csptr vector = this->getInput< ::fwData::Vector >(::fwIO::s_DATA_KEY);
185 
186  // Create SeriesDB
187  ::fwMedData::SeriesDB::sptr seriesDB = ::fwMedData::SeriesDB::New();
188  ::fwMedDataTools::helper::SeriesDB seriesDBHelper(seriesDB);
189 
190  for(const ::fwData::Object::sptr& object : vector->getContainer())
191  {
192  ::fwMedData::Series::sptr series = ::fwMedData::Series::dynamicCast(object);
193  SLM_ASSERT("The container should only contain series.", series);
194  seriesDBHelper.add(series);
195  }
196 
197  const bool containsLandmarks = ::fwGdcmIO::helper::Fiducial::containsLandmarks(seriesDB);
198  const bool containsDistances = ::fwGdcmIO::helper::Fiducial::containsDistances(seriesDB);
199  const bool contains3DDistances = ::fwGdcmIO::helper::Fiducial::contains3DDistances(seriesDB);
200 
201  if(containsLandmarks || containsDistances)
202  {
203  static const std::string fiducialIOD = "Spatial Fiducials";
204  static const std::string comprehensiveSRIOD = "Comprehensive SR";
205  static const std::string comprehensive3DSRIOD = "Comprehensive 3D SR";
206 
207  std::vector< std::string > exportModes;
208  if(!containsDistances)
209  {
210  exportModes.push_back(fiducialIOD);
211  }
212  if(!contains3DDistances)
213  {
214  exportModes.push_back(comprehensiveSRIOD);
215  }
216  exportModes.push_back(comprehensive3DSRIOD);
217 
218  // Create selector
219  ::fwGui::dialog::SelectorDialog::sptr selector = ::fwGui::dialog::SelectorDialog::New();
220 
221  selector->setTitle("Fiducials export mode");
222  selector->setSelections(exportModes);
223  const std::string mode = selector->show();
224  const bool modeSelectionIsCanceled = mode.empty();
225 
226  if(mode == fiducialIOD)
227  {
228  m_fiducialsExportMode = ::fwGdcmIO::writer::Series::SPATIAL_FIDUCIALS;
229  }
230  else if(mode == comprehensiveSRIOD)
231  {
232  m_fiducialsExportMode = ::fwGdcmIO::writer::Series::COMPREHENSIVE_SR;
233  }
234  else
235  {
236  m_fiducialsExportMode = ::fwGdcmIO::writer::Series::COMPREHENSIVE_3D_SR;
237  }
238 
239  return !modeSelectionIsCanceled;
240  }
241 
242  return true;
243 }
244 
245 } // namespace ioGdcm
virtual IOGDCM_API void stopping() override
Does nothing.
virtual FWGUI_API void setCursor(::fwGui::ICursor::CursorType cursor) override
Set the cursor.
virtual FWGUI_API void setMessage(const std::string &msg) override
Set the message.
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.
FWMEDDATATOOLS_API void add(::fwMedData::Series::sptr newSeries)
Add a Series in the SeriesDB.
Defines an helper to modify an fwMedData::SeriesDB and create in parallel the message to announce thi...
The namespace fwGdcmIO contains reader, writer and helper for dicom data.
virtual IOGDCM_API void configureWithIHM() override
Propose a directory selection where to save the DICOM files.
Defines the generic progress dialog for IHM. Use the Delegate design pattern. The specific implementa...
This class defines a vector of objects.
IOGDCM_API void updating() override
Write the ImageSeries in DICOM format.
static FWGDCMIO_API bool containsLandmarks(const std::shared_ptr< ::fwMedData::SeriesDB > &seriesDB)
Return true if the series contains at least one image containing landmarks.
virtual IOGDCM_API ~SSeriesDBWriter() noexcept override
Destructor.
virtual FWGUI_API void addButton(IMessageDialog::Buttons button) override
Add a button (OK, YES_NO, YES, NO, CANCEL)
static FWGDCMIO_API bool contains3DDistances(const std::shared_ptr< ::fwMedData::SeriesDB > &seriesDB)
Return true if the series contains at least one image containing 3D distances.
virtual FWGUI_API IMessageDialog::Buttons show() override
Show the message box and return the clicked button.
virtual FWIO_API void configuring() override
This method proposes to parse xml configuration to retrieve file/files/folder paths.
Definition: IWriter.cpp:122
FWIO_API void clearLocations()
Clear any location set by the setFile/setFiles/setFolder setter.
Definition: IWriter.cpp:115
#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
FWIO_APIconst::boost::filesystem::path & getFolder() const
Returns folder path set by the user or set during service configuration.
Definition: IWriter.cpp:75
Services to write several series (ImageSeries or ModelSeries) in DICOM format.
static FWGDCMIO_API bool containsDistances(const std::shared_ptr< ::fwMedData::SeriesDB > &seriesDB)
Return true if the series contains at least one image containing distances.
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
ioGdcm contains services use to deal with DICOM using the GDCM library.
IOGDCM_API SSeriesDBWriter() noexcept
Constructor.
virtual IOGDCM_API void starting() override
Does nothing.
Writer service API. It manages extension points definition and extension configuration.
Definition: IWriter.hpp:33
FWGUI_API void setTitle(const std::string &title) override
Set the title for the dialog.
Defines the generic file/folder selector dialog for IHM.
Defines the generic cursor for IHM. Use the Delegate design pattern.
FWIO_API void setFolder(const ::boost::filesystem::path &folder)
Sets folder path.
Definition: IWriter.cpp:84
FWGUI_API void setType(::fwGui::dialog::ILocationDialog::Types type) override
Set the type of location for the dialog (SINGLE_FILE, FORLDER, MULTI_FILES)
virtual IOGDCM_API void configuring() override
Configuring method. This method is used to configure the service.
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.
FWIO_API bool hasLocationDefined() const
Returns if a location has been defined ( by the configuration process or directly by user ) ...
Definition: IWriter.cpp:184
IOGDCM_API::fwIO::IOPathType getIOPathType() const override
Return path type managed by the service, here FOLDER.
virtual FWGUI_API void setDefaultCursor() override
Set the default cursor.
std::string m_windowTitle
Title of the window that will open when the configureWithIHM slot is called.
Definition: IWriter.hpp:171