7 #include "ioDicom/SFilterSelectionEditor.hpp" 9 #include <fwData/Vector.hpp> 11 #include <fwDicomIOFilter/composite/IComposite.hpp> 12 #include <fwDicomIOFilter/exceptions/FilterFailure.hpp> 13 #include <fwDicomIOFilter/helper/Filter.hpp> 14 #include <fwDicomIOFilter/registry/detail.hpp> 16 #include <fwGui/dialog/MessageDialog.hpp> 18 #include <fwGuiQt/container/QtContainer.hpp> 20 #include <fwMedDataTools/helper/SeriesDB.hpp> 22 #include <fwRuntime/operations.hpp> 24 #include <fwServices/macros.hpp> 26 #include <QGridLayout> 27 #include <QHBoxLayout> 30 #include <QSignalMapper> 31 #include <QVBoxLayout> 53 _sstream <<
"SFilterSelectionEditor::info";
73 ::fwData::Vector::csptr dataVector = this->getInput< ::fwData::Vector >(
"selection");
74 SLM_ASSERT(
"Vector object should not be null.", dataVector);
77 ::fwGuiQt::container::QtContainer::sptr qtContainer = fwGuiQt::container::QtContainer::dynamicCast(getContainer());
79 QVBoxLayout* mainLayout =
new QVBoxLayout();
80 mainLayout->setAlignment(Qt::AlignTop);
81 qtContainer->setLayout(mainLayout);
84 QSizePolicy policy(QSizePolicy::Maximum, QSizePolicy::Preferred);
87 QHBoxLayout* topLayout =
new QHBoxLayout();
88 QWidget* topWidget =
new QWidget();
89 topWidget->setLayout(topLayout);
90 topLayout->setContentsMargins(QMargins(0, 0, 0, 0));
91 mainLayout->addWidget(topWidget);
98 auto path = ::fwRuntime::getBundleResourcePath(
"media");
101 m_addFilterButton =
new QPushButton(QIcon(QString::fromStdString((path /
"icons/Plus.svg").
string())),
"Add");
116 QHBoxLayout* applyLayout =
new QHBoxLayout();
117 QWidget* applyWidget =
new QWidget();
118 applyWidget->setLayout(applyLayout);
119 applyWidget->setSizePolicy(policy);
120 applyLayout->setContentsMargins(QMargins(0, 0, 0, 0));
123 mainLayout->addWidget(applyWidget, 0, Qt::AlignRight);
126 QHBoxLayout* bottomLayout =
new QHBoxLayout();
127 QWidget* bottomWidget =
new QWidget();
128 bottomWidget->setLayout(bottomLayout);
129 bottomLayout->setContentsMargins(QMargins(0, 0, 0, 0));
130 mainLayout->addWidget(bottomWidget);
132 QHBoxLayout* buttonLayout =
new QHBoxLayout();
133 QWidget* buttonWidget =
new QWidget();
134 buttonWidget->setLayout(buttonLayout);
135 buttonWidget->setSizePolicy(policy);
136 buttonLayout->setContentsMargins(QMargins(0, 0, 0, 0));
139 m_applyFiltersButton =
new QPushButton(QIcon(QString::fromStdString((path /
"icons/Apply.svg").
string())),
"Apply");
144 m_configureFilterButton =
new QPushButton(QIcon(QString::fromStdString((path /
"icons/Settings.svg").
string())),
151 m_splitFilterButton =
new QPushButton(QIcon(QString::fromStdString((path /
"icons/Split.svg").
string())),
"Split");
158 new QPushButton(QIcon(QString::fromStdString((path /
"icons/Minus.svg").
string())),
"Remove");
163 bottomLayout->addWidget(buttonWidget, 0, Qt::AlignRight);
171 QObject::connect(
m_addFilterButton, SIGNAL(clicked(
void)),
this, SLOT(addFilterAtTheEnd(
void)));
174 QObject::connect(
m_splitFilterButton, SIGNAL(clicked(
void)),
this, SLOT(splitFilter(
void)));
176 QObject::connect(
m_deleteShortcut, SIGNAL(activated()),
this, SLOT(removeFilter(
void)));
178 SLOT(showContextMenuForSelectedFilter(
const QPoint&)));
184 void SFilterSelectionEditor::onForceChecked(
int state)
186 if(state == Qt::Checked)
190 "You asked to ignore reading errors, there are high risks of issues for resulting image.",
191 ::fwGui::dialog::IMessageDialog::WARNING);
199 unsigned int index = 0;
201 std::vector< ::fwDicomIOFilter::IFilter::sptr > sortedFilters;
202 for(
const std::string& key: ::fwDicomIOFilter::registry::get()->getFactoryKeys())
204 ::fwDicomIOFilter::IFilter::sptr filter = ::fwDicomIOFilter::factory::New(key);
205 sortedFilters.push_back(filter);
210 for(const ::fwDicomIOFilter::IFilter::sptr& filter: sortedFilters)
213 if(!filter->isConfigurationRequired() || filter->isConfigurableWithGUI())
223 SFilterSelectionEditor::getFilterDescription(
224 filter).c_str(), Qt::ToolTipRole);
239 SLOT(updateButtonStatus(
int)));
240 QObject::disconnect(
m_addFilterButton, SIGNAL(clicked(
void)),
this, SLOT(addFilterAtTheEnd(
void)));
241 QObject::disconnect(
m_removeFilterButton, SIGNAL(clicked(
void)),
this, SLOT(removeFilter(
void)));
243 QObject::disconnect(
m_splitFilterButton, SIGNAL(clicked(
void)),
this, SLOT(splitFilter(
void)));
244 QObject::disconnect(
m_applyFiltersButton, SIGNAL(clicked(
void)),
this, SLOT(applyFilters(
void)));
245 QObject::disconnect(
m_deleteShortcut, SIGNAL(activated()),
this, SLOT(removeFilter(
void)));
247 SLOT(showContextMenuForSelectedFilter(
const QPoint&)));
260 void SFilterSelectionEditor::addFilter(
int filterTypeIndex)
263 this->addFilter(filterTypeIndex, index);
268 void SFilterSelectionEditor::addFilterAtTheEnd()
275 void SFilterSelectionEditor::addFilter(
int filterTypeIndex,
int position)
284 ::fwDicomIOFilter::IFilter::sptr filter = ::fwDicomIOFilter::factory::New(key);
285 std::string
id = filter->getID();
301 void SFilterSelectionEditor::removeFilter()
304 if(currentIndex >= 0)
317 void SFilterSelectionEditor::configureFilter()
327 void SFilterSelectionEditor::splitFilter()
330 std::string compositeId =
332 ::fwDicomIOFilter::composite::IComposite::sptr composite =
333 ::fwDicomIOFilter::composite::IComposite::dynamicCast(
m_filtersMap[compositeId]);
336 this->removeFilter();
339 int position = currentIndex;
340 for(const ::fwDicomIOFilter::IFilter::sptr& filter: composite->getChildren())
342 std::string
id = filter->getID();
347 SFilterSelectionEditor::getFilterDescription(filter).c_str());
357 void SFilterSelectionEditor::updateButtonStatus(
int filterIndex)
359 bool hasFilter = (filterIndex != -1);
380 void SFilterSelectionEditor::applyFilters()
382 typedef std::vector< ::fwMedData::DicomSeries::sptr > DicomSeriesContainertype;
383 typedef std::vector< ::fwDicomIOFilter::IFilter::sptr > FilterContainertype;
386 ::fwData::Vector::csptr vector = this->getInput< ::fwData::Vector >(
"selection");
387 SLM_ASSERT(
"Vector object should not be null.", vector);
391 messageBox.
setIcon(::fwGui::dialog::IMessageDialog::INFO);
392 messageBox.
addButton(::fwGui::dialog::IMessageDialog::OK);
393 messageBox.
setTitle(
"Filters information");
402 messageBox.
setMessage(
"You must select series on which you want to apply your filters.");
406 messageBox.
setMessage(
"You must select the filters that you want to apply on your series.");
411 DicomSeriesContainertype dicomSeriesContainer;
412 FilterContainertype filterContainer;
415 for(const ::fwData::Object::sptr& obj: vector->getContainer())
417 ::fwMedData::DicomSeries::sptr srcDicomSeries = ::fwMedData::DicomSeries::dynamicCast(obj);
418 SLM_ASSERT(
"The series should be a DicomSeries.", srcDicomSeries);
420 ::fwMedData::DicomSeries::sptr dicomSeries = ::fwMedData::DicomSeries::New();
421 dicomSeries->deepCopy(srcDicomSeries);
422 dicomSeriesContainer.push_back(dicomSeries);
432 std::stringstream ssFilters;
433 std::stringstream ssInfos;
436 ssFilters <<
"<b>Filters :</b><br />";
438 for(const ::fwDicomIOFilter::IFilter::sptr& filter: filterContainer)
440 ssFilters <<
"- " << filter->getName() <<
" -> ";
444 ssFilters <<
"<font color=\"Green\">OK</font><br />";
448 ssFilters <<
"<font color=\"Red\">ERROR</font><br />";
449 ssInfos <<
"- " << e.what() <<
"<br />";
458 if(forcedApply || ssInfos.str().empty())
461 for(const ::fwMedData::DicomSeries::sptr& series: dicomSeriesContainer)
463 sDBhelper.
add(series);
468 if(ssInfos.str().empty())
470 ssInfos <<
"All filters have been correctly applied.";
473 std::string msg = ssFilters.str() +
"<br /><br /><b>Informations :</b><br />" + ssInfos.str();
487 void SFilterSelectionEditor::showContextMenuForSelectedFilter(
const QPoint& pos)
493 QMenu* addMenu = contextMenu.addMenu(
"Add");
496 QPointer< QSignalMapper > mapper =
new QSignalMapper();
504 action->setIconVisibleInMenu(
true);
505 addMenu->addAction(action);
507 mapper->setMapping(action, i);
508 QObject::connect(action, SIGNAL(triggered()), mapper, SLOT(map()));
512 QObject::connect(mapper, SIGNAL(mapped(
int)),
this, SLOT(addFilter(
int)));
519 std::string
id = filterItem->data(Qt::UserRole).toString().toStdString();
520 ::fwDicomIOFilter::IFilter::sptr filter =
m_filtersMap[id];
524 QObject::connect(removeAction, SIGNAL(triggered()),
this, SLOT(removeFilter()));
525 contextMenu.addAction(removeAction);
529 configureAction->setEnabled(filter->isConfigurableWithGUI());
530 QObject::connect(configureAction, SIGNAL(triggered()),
this, SLOT(configureFilter()));
531 contextMenu.addAction(configureAction);
536 QObject::connect(splitAction, SIGNAL(triggered()),
this, SLOT(splitFilter()));
537 contextMenu.addAction(splitAction);
549 const ::fwDicomIOFilter::IFilter::sptr& b)
551 if(a->getFilterType() == b->getFilterType())
553 return a->getName() < b->getName();
555 return a->getFilterType() > b->getFilterType();
560 QIcon SFilterSelectionEditor::getFilterIcon(::fwDicomIOFilter::IFilter::sptr filter)
562 const ::boost::filesystem::path path = ::fwRuntime::getBundleResourcePath(std::string(
"media"));
564 QIcon(QString::fromStdString((path /
"icons/Modifier.svg").
string())),
565 QIcon(QString::fromStdString((path /
"icons/Sorter.svg").
string())),
566 QIcon(QString::fromStdString((path /
"icons/Splitter.svg").
string())),
567 QIcon(QString::fromStdString((path /
"icons/Composite.svg").
string())),
568 QIcon(QString::fromStdString((path /
"icons/Custom.svg").
string()))
570 return icons[filter->getFilterType()];
575 std::string SFilterSelectionEditor::getFilterDescription(::fwDicomIOFilter::IFilter::sptr filter)
577 std::string types[] = {
"Modifier",
"Sorter",
"Splitter",
"Composite",
"Custom" };
578 std::string description =
579 "<b>Name :</b> "+filter->getName()+
"<br />" 580 "<b>Type :</b> "+types[filter->getFilterType()]+
"<br />" 581 "<b>Configurable :</b> "+((filter->isConfigurableWithGUI()) ?
"Yes" :
"No")+
"<br />" 582 "<b>Informations :</b><br />"+filter->getDescription();
#define SLM_TRACE_FUNC()
Trace contextual function signature.
virtual FWGUI_API void setMessage(const std::string &msg) override
Set the message.
Defines the service interface managing the editor service for object.
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)
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
QPointer< QPushButton > m_splitFilterButton
Button used to split a composite filter.
QPointer< QListWidget > m_selectedFilterListWidget
Selected filters list widget.
QPointer< QComboBox > m_availableFilterListWidget
Combo box displaying the available filters.
FilterMapType m_filtersMap
Map used to store filters and their keys.
IODICOM_API void fillAvailableFilters()
Fill the combobox with the list of available filters.
QPointer< QPushButton > m_applyFiltersButton
Button used to apply filters of the list.
::fwMedData::SeriesDB::sptr m_destinationSeriesDB
Destination SeriesDB.
static FWDICOMIOFILTER_API bool applyFilter(DicomSeriesContainerType &dicomSeriesContainer,::fwDicomIOFilter::IFilter::sptr filter, bool forcedApply=false, const ::fwLog::Logger::sptr &logger=::fwLog::Logger::New())
Apply a filter to the DicomSeries.
virtual IODICOM_API void stopping() override
Override.
This editor service is used to select and apply filters to Dicom series.
virtual IODICOM_API void starting() override
Override.
This class defines a vector of objects.
virtual FWGUI_API void addButton(IMessageDialog::Buttons button) override
Add a button (OK, YES_NO, YES, NO, CANCEL)
virtual FWGUI_API IMessageDialog::Buttons show() override
Show the message box and return the clicked button.
QPointer< QPushButton > m_configureFilterButton
Button used to configure a filter in the list.
ioDicom contains services used to deal with the DICOM standard.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
QPointer< QPushButton > m_removeFilterButton
Button used to remove a filter in the list.
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
virtual FWGUI_API void setIcon(IMessageDialog::Icons icon) override
Set the icon (CRITICAL, WARNING, INFO or QUESTION)
static bool sortFilters(const ::fwDicomIOFilter::IFilter::sptr &a, const ::fwDicomIOFilter::IFilter::sptr &b)
Sort filters.
QPointer< QShortcut > m_deleteShortcut
Delete key shortcut.
IODICOM_API void info(std::ostream &_sstream) override
Override.
FilterFailure Exceptions.
IODICOM_API SFilterSelectionEditor() noexcept
Constructor.
IODICOM_API void updating() override
Override.
virtual IODICOM_API void configuring() override
Do nothing.
QPointer< QPushButton > m_addFilterButton
Button used to add a filter in the list.
std::string m_destinationSeriesDBID
Destination SeriesDB ID.
virtual IODICOM_API ~SFilterSelectionEditor() noexcept
Destructor.
QPointer< QCheckBox > m_forcedApplyCheckBox
Forced apply check box.
virtual FWGUI_API void setTitle(const std::string &title) override
Set the title of the message box.
FWGUI_API void initialize()
Initialize managers.