7 #include "ioAtoms/SWriter.hpp" 9 #include "ioAtoms/SReader.hpp" 11 #include <fwAtomConversion/convert.hpp> 13 #include <fwAtomsBoostIO/types.hpp> 14 #include <fwAtomsBoostIO/Writer.hpp> 16 #include <fwAtomsPatch/PatchingManager.hpp> 17 #include <fwAtomsPatch/VersionsGraph.hpp> 18 #include <fwAtomsPatch/VersionsManager.hpp> 20 #include <fwCom/Signal.hxx> 22 #include <fwData/Composite.hpp> 23 #include <fwData/location/Folder.hpp> 24 #include <fwData/location/SingleFile.hpp> 26 #include <fwDataCamp/visitor/RecursiveLock.hpp> 28 #include <fwGui/Cursor.hpp> 29 #include <fwGui/dialog/MessageDialog.hpp> 30 #include <fwGui/dialog/ProgressDialog.hpp> 31 #include <fwGui/dialog/SelectorDialog.hpp> 33 #include <fwJobs/Aggregator.hpp> 34 #include <fwJobs/Job.hpp> 36 #include <fwMDSemanticPatch/PatchLoader.hpp> 38 #include <fwServices/macros.hpp> 40 #include <fwZip/WriteDirArchive.hpp> 41 #include <fwZip/WriteZipArchive.hpp> 43 #include <boost/algorithm/string/join.hpp> 44 #include <boost/assign.hpp> 45 #include <boost/filesystem/path.hpp> 56 static const ::fwCom::Signals::SignalKeyType JOB_CREATED_SIGNAL =
"jobCreated";
61 m_useAtomsPatcher(false),
62 m_exportedVersion(
"Undefined"),
63 m_context(
"Undefined"),
64 m_version(
"Undefined")
66 m_sigJobCreated = newSignal< JobCreatedSignalType >( JOB_CREATED_SIGNAL );
97 const auto archiveCfgs = config.equal_range(
"archive");
99 for (
auto it = archiveCfgs.first; it != archiveCfgs.second; ++it)
101 const std::string backend = it->second.get<std::string>(
"<xmlattr>.backend");
102 SLM_ASSERT(
"No backend attribute given in archive tag", backend !=
"");
103 SLM_ASSERT(
"Unsupported backend '" + backend +
"'",
106 const auto extCfgs = it->second.equal_range(
"extension");
108 for (
auto itExt = extCfgs.first; itExt != extCfgs.second; ++itExt)
110 const std::string extension = itExt->second.get<std::string>(
"");
111 SLM_ASSERT(
"No extension given for backend '" + backend +
"'", !extension.empty());
112 SLM_ASSERT(
"Extension must begin with '.'", extension[0] ==
'.');
119 const auto extensionsCfg = config.get_child_optional(
"extensions");
125 const auto extCfgs = extensionsCfg->equal_range(
"extension");
126 for (
auto it = extCfgs.first; it != extCfgs.second; ++it)
128 const std::string ext = it->second.get<std::string>(
"");
132 FileExtension2NameType::const_iterator itCustom =
m_customExts.find(ext);
135 SLM_ASSERT(
"Extension '" + ext +
"' is not allowed in configuration", extIsKnown);
148 for(FileExtension2NameType::value_type ext :
m_customExts)
160 const auto patcherCfg = config.get_child_optional(
"patcher");
164 m_context = patcherCfg->get<std::string>(
"<xmlattr>.context",
"MedicalData");
165 m_version = patcherCfg->get<std::string>(
"<xmlattr>.version",
182 std::vector< std::string > versions = vg->getConnectedVersions(
m_version);
183 if ( versions.size() == 0 )
192 std::transform(versions.begin(), versions.end(), versions.begin(), [](
const std::string& _version)
194 static const std::regex ala(
"ALA");
195 return std::regex_replace(_version, ala,
"");
201 std::sort(versions.begin(), versions.end(), [](
const std::string& _a,
const std::string& _b)
207 const std::string repoA = _a.substr(3, _a.size());
208 const std::string repoB = _b.substr(3, _b.size());
211 const std::string numA = _a.substr(1, 2);
212 const std::string numB = _b.substr(1, 2);
215 return repoA < repoB;
217 catch ( std::out_of_range e)
219 OSLM_ERROR(
"Bad version format: either " + _a +
" or " + _b);
224 std::vector< std::string > prettyVersionsAll;
225 std::map< std::string, std::string > prettyVersionsToVersions;
227 for(
const auto& v : versions)
231 const std::string num = v.substr(0, 3);
232 const std::string repo = v.substr(3, v.size());
234 const std::string prettyVersion = num + ((repo.empty()) ?
"" :
" (" + repo +
")");
235 prettyVersionsAll.push_back(prettyVersion);
236 prettyVersionsToVersions[ prettyVersion ] = v;
239 catch ( std::out_of_range e)
243 prettyVersionsAll.push_back(v);
244 prettyVersionsToVersions[ v ] = v;
249 std::vector< std::string > prettyVersions;
250 prettyVersions.push_back(prettyVersionsAll[0]);
251 for(
auto itVersion = prettyVersionsAll.begin() + 1; itVersion != prettyVersionsAll.end(); ++itVersion)
253 const auto& versionA = *(itVersion - 1);
254 const auto& versionB = *(itVersion);
255 const std::string repoA = versionA.substr(3, versionA.size());
256 const std::string repoB = versionB.substr(3, versionB.size());
260 prettyVersions.push_back(versionB);
266 dialogVersion.
setTitle(
"Archive version");
267 dialogVersion.
setMessage(
"Select an archive version");
269 bool selectAmongstAllVersions =
false;
270 dialogVersion.
addCustomButton(
"Advanced", [&selectAmongstAllVersions]()
272 selectAmongstAllVersions =
true;
276 std::string result = dialogVersion.
show();
277 if(selectAmongstAllVersions)
281 dialogVersionAll.
setTitle(
"Archive version");
282 dialogVersionAll.
setMessage(
"Select an archive version");
284 result = dialogVersionAll.
show();
286 if( !result.empty() )
290 return !result.empty();
309 ::fwData::Object::csptr obj = this->getInput< ::fwData::Object >(::fwIO::s_DATA_KEY);
313 obj = this->getObject< ::fwData::Object >();
317 cursor.
setCursor(::fwGui::ICursor::BUSY);
320 const ::boost::filesystem::path& requestedFilePath = this->
getFile();
321 std::string requestedExtension = requestedFilePath.extension().string();
324 && !requestedExtension.empty()
327 std::string errorMessage(
"File extension '" + requestedExtension +
331 ::fwGui::dialog::IMessageDialog::CRITICAL);
335 ::boost::filesystem::path filePath = requestedFilePath;
336 if( ::boost::filesystem::exists( requestedFilePath ) )
338 FW_RAISE_IF(
"can't write to : " << requestedFilePath <<
", it is a directory.",
339 ::boost::filesystem::is_directory(requestedFilePath)
341 filePath = ::boost::filesystem::unique_path(filePath);
344 const ::boost::filesystem::path folderPath = filePath.parent_path();
345 ::boost::filesystem::path filename = filePath.filename();
346 std::string extension = filePath.extension().string();
349 if (extension.empty())
357 std::set< std::string >::const_iterator begin =
m_allowedExts.begin();
358 std::string firstAllowedExt = *begin;
360 extension = firstAllowedExt;
362 FW_RAISE_IF(
"Extension is empty", extension.empty() );
363 FW_RAISE_IF(
"The file extension '" << extension <<
"' is not managed",
375 ::fwAtoms::Object::sptr atom;
376 const unsigned int progressBarOffset = 10;
382 runningJob.
doneWork(progressBarOffset);
384 atom = ::fwAtomConversion::convert(::fwData::Object::constCast(obj));
394 atom->setMetaInfo(
"version_name",
m_version);
401 runningJob.
doneWork(progressBarOffset);
418 runningJob.
doneWork(progressBarOffset);
420 ::fwZip::IWriteArchive::sptr writeArchive;
421 ::fwAtomsBoostIO::FormatType format;
422 ::boost::filesystem::path archiveRootName;
423 if ( extension ==
".json" )
425 writeArchive = ::fwZip::WriteDirArchive::New(folderPath.string());
426 archiveRootName = filename;
427 format = ::fwAtomsBoostIO::JSON;
429 else if ( extension ==
".jsonz" )
431 if ( ::boost::filesystem::exists( filePath ) )
433 ::boost::filesystem::remove( filePath );
435 writeArchive = ::fwZip::WriteZipArchive::New(filePath.string());
436 archiveRootName =
"root.json";
437 format = ::fwAtomsBoostIO::JSON;
439 else if ( extension ==
".xml" )
441 writeArchive = ::fwZip::WriteDirArchive::New(folderPath.string());
442 archiveRootName = filename;
443 format = ::fwAtomsBoostIO::XML;
445 else if ( extension ==
".xmlz" )
447 if ( ::boost::filesystem::exists( filePath ) )
449 ::boost::filesystem::remove( filePath );
451 writeArchive = ::fwZip::WriteZipArchive::New(filePath.string());
452 archiveRootName =
"root.xml";
453 format = ::fwAtomsBoostIO::XML;
457 FW_RAISE(
"This file extension '" << extension <<
"' is not managed" );
461 writeArchive.reset();
467 jobs->add(convertJob);
468 jobs->add(patchingJob);
470 jobs->setCancelable(
false);
478 catch( std::exception& e )
483 ::fwGui::dialog::IMessageDialog::CRITICAL);
488 "Writing process aborted",
489 ::fwGui::dialog::IMessageDialog::CRITICAL);
492 cursor.setDefaultCursor();
506 static ::boost::filesystem::path _sDefaultPath;
513 dialogFile.
setOption(::fwGui::dialog::ILocationDialog::WRITE);
514 dialogFile.
setType(::fwGui::dialog::LocationDialog::SINGLE_FILE);
523 ::fwData::location::SingleFile::sptr result
524 = ::fwData::location::SingleFile::dynamicCast( dialogFile.
show() );
528 _sDefaultPath = result->getPath();
529 this->
setFile( _sDefaultPath );
530 dialogFile.
saveDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath.parent_path()) );
IOATOMS_API void configuring() override
Parse the configuration.
#define FW_DEPRECATED_KEY(newKey, access, version)
Use this macro when deprecating a service key to warn the developer.
virtual FWGUI_API void setCursor(::fwGui::ICursor::CursorType cursor) override
Set the cursor.
FWATOMSPATCH_API::fwAtoms::Object::sptr transformTo(const std::string &newVersion)
Transforms the object to the given version.
JobCreatedSignalType::sptr m_sigJobCreated
Signal emitted when job created.
IOATOMS_API void starting() override
Does nothing.
virtual FWGUI_API void setSelections(std::vector< std::string > _selections) override
Set the string list that can be chosen by the selector.
virtual FWGUI_API void setMessage(const std::string &msg) override
Set the message.
IOATOMS_API::fwIO::IOPathType getIOPathType() const override
Returns managed path type, here service manages only single file.
FWJOBS_API void doneWork(std::uint64_t units)
Setter on done work units.
static FWGUI_API IMessageDialog::Buttons showMessageDialog(const std::string &title, const std::string &message,::fwGui::dialog::IMessageDialog::Icons icon=INFO)
FWGUI_API void setTitle(std::string title) override
Sets the selector title.
FileExtension2NameType m_customExts
Maps custom extensions to known format.
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.
IOATOMS_API void stopping() override
Does nothing.
std::string m_context
Defines context of data.
FWGUI_API void addFilter(const std::string &filterName, const std::string &wildcardList) override
specify some filtering when browsing files:
SelectorDialog allows the choice of an element among several (_selections) Use the Delegate design pa...
std::shared_ptr< ::fwJobs::Aggregator > sptr
Aggregator container type.
FWJOBS_API const bool & cancelRequested() const
Returns the job canceling status.
This class encapsulate a task that will report it's progression The embeded task will be run at most ...
FileExtension2NameType m_allowedExtLabels
Labels shown in file dialog for each allowed extension.
static FWMDSEMANTICPATCH_API std::string getCurrentVersion()
Returns current MedicalData version.
FWIO_API void setFile(const ::boost::filesystem::path &file)
Sets file path.
FWGUI_API std::string show() override
Show the selector and return the selection.
#define OSLM_ERROR(message)
bool m_useAtomsPatcher
To activate atom patcher.
virtual FWGUI_API void addCustomButton(const std::string &label, std::function< void()> clickedFn) override
Add a custom button to this dialog.
virtual FWIO_API void configuring() override
This method proposes to parse xml configuration to retrieve file/files/folder paths.
FWIO_APIconst::boost::filesystem::path & getFile() const
Returns the file path set by the user or set during service configuration.
IOATOMS_API SWriter()
Does nothing.
std::string m_version
Current version of format.
FWIO_API void clearLocations()
Clear any location set by the setFile/setFiles/setFolder setter.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
static const FileExtension2NameType s_EXTENSIONS
Managed file extensions.
This class is an helper to lock an object and all its children recursively.
Base class for each data object.
IOATOMS_API void updating() override
Convert fwData to fwAtoms, and apply the writer chosen from file extension.
IOPathType
IOPathType defines different type of paths used by service readers/writers.
std::set< std::string > m_allowedExts
Allowed file extensions.
static std::shared_ptr< VersionsManager > getDefault()
Returns the default instance of VersionsManager.
static FWJOBS_API sptr New(const std::string &name, Task task, const std::shared_ptr< ::fwThread::Worker > &worker=nullptr)
Construct a new job and return a smart pointer of it.
Writer service API. It manages extension points definition and extension configuration.
FWGUI_API void setTitle(const std::string &title) override
Set the title for the dialog.
Defines the generic file/folder selector dialog for IHM.
FWGUI_API std::string getCurrentSelection() const override
Gets the current extension file selection.
Defines the generic cursor for IHM. Use the Delegate design pattern.
std::shared_ptr< ::fwThread::Worker > m_associatedWorker
Associated worker.
std::string m_selectedExtension
Extension selected in file dialog.
FWJOBS_API void done()
Set done work units to total work units.
Contains services to read and write data via atom conversion.
IOATOMS_API void configureWithIHM() override
Propose to create a medical data file.
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)
static FWJOBS_API sptr New(const std::string &name="")
Create a new Aggregator smart pointer.
std::shared_ptr< ::fwJobs::Job > sptr
Task type.
FWIO_API bool hasLocationDefined() const
Returns if a location has been defined ( by the configuration process or directly by user ) ...
Atoms writer. Service to write an fwData medical data converted in fwAtoms.
std::string m_exportedVersion
Selected exported version of atom.
std::string m_windowTitle
Title of the window that will open when the configureWithIHM slot is called.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.