7 #include "uiMedDataQt/editor/SActivityWizard.hpp" 9 #include <fwActivities/IValidator.hpp> 11 #include <fwCom/Signal.hpp> 12 #include <fwCom/Signal.hxx> 13 #include <fwCom/Signals.hpp> 14 #include <fwCom/Slot.hpp> 15 #include <fwCom/Slots.hpp> 16 #include <fwCom/Slots.hxx> 18 #include <fwData/Composite.hpp> 20 #include <fwGui/dialog/InputDialog.hpp> 22 #include <fwGuiQt/container/QtContainer.hpp> 24 #include <fwMedData/Equipment.hpp> 25 #include <fwMedData/Patient.hpp> 26 #include <fwMedData/Series.hpp> 27 #include <fwMedData/Study.hpp> 29 #include <fwMedDataTools/helper/SeriesDB.hpp> 31 #include <fwRuntime/ConfigurationElement.hpp> 32 #include <fwRuntime/operations.hpp> 34 #include <fwServices/macros.hpp> 36 #include <fwTools/dateAndTime.hpp> 37 #include <fwTools/UUID.hpp> 39 #include <QApplication> 40 #include <QHBoxLayout> 42 #include <QMessageBox> 44 #include <QVBoxLayout> 57 const ::fwCom::Slots::SlotKeyType SActivityWizard::s_CREATE_ACTIVITY_SLOT =
"createActivity";
58 const ::fwCom::Slots::SlotKeyType SActivityWizard::s_UPDATE_ACTIVITY_SLOT =
"updateActivity";
59 const ::fwCom::Slots::SlotKeyType SActivityWizard::s_UPDATE_ACTIVITY_SERIES_SLOT =
"updateActivitySeries";
60 const ::fwCom::Signals::SignalKeyType SActivityWizard::s_ACTIVITY_CREATED_SIG =
"activityCreated";
61 const ::fwCom::Signals::SignalKeyType SActivityWizard::s_ACTIVITY_UPDATED_SIG =
"activityUpdated";
62 const ::fwCom::Signals::SignalKeyType SActivityWizard::s_CANCELED_SIG =
"canceled";
64 static const ::fwServices::IService::KeyType s_SERIESDB_INOUT =
"seriesDB";
70 m_confirmUpdate(true),
73 newSlot(s_CREATE_ACTIVITY_SLOT, &SActivityWizard::createActivity,
this);
74 newSlot(s_UPDATE_ACTIVITY_SLOT, &SActivityWizard::updateActivity,
this);
75 newSlot(s_UPDATE_ACTIVITY_SERIES_SLOT, &SActivityWizard::updateActivitySeries,
this);
77 m_sigActivityCreated = newSignal<ActivityCreatedSignalType>(s_ACTIVITY_CREATED_SIG);
78 m_sigActivityUpdated = newSignal<ActivityUpdatedSignalType>(s_ACTIVITY_UPDATED_SIG);
79 m_sigCanceled = newSignal< CanceledSignalType >(s_CANCELED_SIG);
96 m_ioSelectorConfig = config.get(
"ioSelectorConfig",
"");
97 SLM_ASSERT(
"ioSelector Configuration must not be empty", !m_ioSelectorConfig.empty());
99 m_sdbIoSelectorConfig = config.get(
"sdbIoSelectorConfig",
"");
100 if (m_sdbIoSelectorConfig.empty())
102 m_sdbIoSelectorConfig = m_ioSelectorConfig;
105 m_confirmUpdate = config.get(
"confirm", m_confirmUpdate);
106 m_isCancelable = config.get(
"cancel", m_isCancelable);
108 const auto iconsCfg = config.get_child(
"icons");
109 const auto iconCfg = iconsCfg.equal_range(
"icon");
110 for (
auto itIcon = iconCfg.first; itIcon != iconCfg.second; ++itIcon)
112 const auto iconCfg = itIcon->second.get_child(
"<xmlattr>");
114 const std::string type = iconCfg.get<std::string>(
"type");
115 SLM_ASSERT(
"'type' attribute must not be empty", !type.empty());
116 const std::string icon = iconCfg.get<std::string>(
"icon");
117 SLM_ASSERT(
"'icon' attribute must not be empty", !icon.empty());
119 const auto file = ::fwRuntime::getResourceFilePath(icon);
120 m_objectIcons[type] = file.string();
122 OSLM_ASSERT(
"icons are empty", !m_objectIcons.empty());
131 fwGuiQt::container::QtContainer::sptr qtContainer = fwGuiQt::container::QtContainer::dynamicCast(getContainer());
133 QWidget*
const container = qtContainer->getQtContainer();
135 QVBoxLayout* layout =
new QVBoxLayout();
137 m_title =
new QLabel(
"");
138 m_title->setStyleSheet(
"QLabel { font: bold; color: blue; }");
139 m_title->setAlignment(Qt::AlignHCenter);
140 layout->addWidget(m_title);
142 m_description =
new QLabel(
"");
143 m_description->setStyleSheet(
"QLabel { font: italic; border: solid 1px;}");
144 m_description->setAlignment(Qt::AlignHCenter);
145 layout->addWidget(m_description);
148 m_activityDataView->setIOSelectorConfig(m_ioSelectorConfig);
149 m_activityDataView->setSDBIOSelectorConfig(m_sdbIoSelectorConfig);
151 m_activityDataView->setObjectIconAssociation(m_objectIcons);
153 layout->addWidget(m_activityDataView, 1);
155 QHBoxLayout* buttonLayout =
new QHBoxLayout();
156 layout->addLayout(buttonLayout);
160 m_cancelButton =
new QPushButton(
"Cancel");
161 m_cancelButton->setToolTip(
"Cacnel the activity creation");
162 buttonLayout->addWidget(m_cancelButton);
165 m_resetButton =
new QPushButton(
"Clear");
166 m_resetButton->setToolTip(
"Clear the current selected data");
167 buttonLayout->addWidget(m_resetButton);
169 m_okButton =
new QPushButton(
"Apply");
170 m_okButton->setToolTip(
"Create or update the activity with the selected data");
171 buttonLayout->addWidget(m_okButton);
173 container->setLayout(layout);
175 QObject::connect(m_activityDataView.data(), &widget::ActivityDataView::currentChanged,
176 this, &SActivityWizard::onTabChanged);
177 QObject::connect(m_okButton.data(), &QPushButton::clicked,
this, &SActivityWizard::onBuildActivity);
178 QObject::connect(m_resetButton.data(), &QPushButton::clicked,
this, &SActivityWizard::onReset);
181 QObject::connect(m_cancelButton.data(), &QPushButton::clicked,
this, &SActivityWizard::onCancel);
189 m_activityDataView->clear();
191 QObject::disconnect(m_activityDataView.data(), &widget::ActivityDataView::currentChanged,
192 this, &SActivityWizard::onTabChanged);
193 QObject::disconnect(m_okButton.data(), &QPushButton::clicked,
this, &SActivityWizard::onBuildActivity);
194 QObject::disconnect(m_resetButton.data(), &QPushButton::clicked,
this, &SActivityWizard::onReset);
197 QObject::disconnect(m_cancelButton.data(), &QPushButton::clicked,
this, &SActivityWizard::onCancel);
207 auto as = this->getInOut< ::fwMedData::ActivitySeries>(
"activitySeries");
210 this->updateActivity(as);
213 SLM_DEBUG_IF(
"activity series is not defined, it cannot be updated", !as);
218 void SActivityWizard::createActivity(std::string activityID)
220 m_mode = Mode::CREATE;
225 std::shared_ptr< ::fwRuntime::Bundle > bundle = ::fwRuntime::findBundle(info.
bundleId,
227 if (!bundle->isStarted())
232 m_actSeries = ::fwMedData::ActivitySeries::New();
234 m_actSeries->setModality(
"OT");
237 ::boost::posix_time::ptime now = ::boost::posix_time::second_clock::local_time();
241 m_actSeries->setActivityConfigId(info.id);
243 m_title->setText(QString(
"<h1>%1</h1>").arg(QString::fromStdString(info.title)));
244 m_description->setText(QString::fromStdString(info.description));
246 bool needConfig =
false;
249 for(
const auto& req : info.requirements)
251 if(req.maxOccurs > 0)
260 m_activityDataView->fillInformation(info);
261 if (m_activityDataView->count() > 1)
263 m_okButton->setText(
"Next");
271 for(
const auto& req : info.requirements)
273 SLM_ASSERT(
"minOccurs and maxOccurs should be 0", req.minOccurs == 0 && req.maxOccurs == 0);
274 ::fwData::Composite::sptr data = m_actSeries->getData();
275 (*data)[req.name] = ::fwData::factory::New(req.type);
278 ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >(s_SERIESDB_INOUT);
282 seriesDB = this->getObject< ::fwMedData::SeriesDB >();
286 helper.add(m_actSeries);
288 m_sigActivityCreated->asyncEmit(m_actSeries);
294 void SActivityWizard::updateActivity(::fwMedData::ActivitySeries::sptr activitySeries)
300 std::shared_ptr< ::fwRuntime::Bundle > bundle = ::fwRuntime::findBundle(info.
bundleId,
302 if (!bundle->isStarted())
307 m_title->setText(QString(
"<h1>%1</h1>").arg(QString::fromStdString(info.title)));
308 m_description->setText(QString::fromStdString(info.description));
310 m_mode = Mode::UPDATE;
311 m_actSeries = activitySeries;
313 bool needConfig =
false;
316 for(
const auto& req : info.requirements)
318 if(req.maxOccurs != 0)
327 m_activityDataView->fillInformation(m_actSeries);
328 if (m_activityDataView->count() > 1)
330 m_okButton->setText(
"Next");
336 ::fwData::Object::ModifiedSignalType::sptr sig;
339 m_sigActivityUpdated->asyncEmit(m_actSeries);
345 void SActivityWizard::updateActivitySeries(::fwMedData::Series::sptr series)
347 ::fwMedData::ActivitySeries::sptr activitySeries = ::fwMedData::ActivitySeries::dynamicCast(series);
350 this->updateActivity(activitySeries);
356 void SActivityWizard::onTabChanged(
int index)
358 if (index == m_activityDataView->count() - 1)
360 m_okButton->setText(
"Apply");
364 m_okButton->setText(
"Next");
370 void SActivityWizard::onReset()
376 m_activityDataView->fillInformation(info);
378 if (m_activityDataView->count() > 1)
380 m_okButton->setText(
"Next");
387 void SActivityWizard::onCancel()
389 m_activityDataView->clear();
390 m_sigCanceled->asyncEmit();
395 void SActivityWizard::onBuildActivity()
397 int index = m_activityDataView->currentIndex();
398 int lastTab = m_activityDataView->count() -1;
400 std::string errorMsg;
402 if (m_activityDataView->checkData(
size_t(index), errorMsg))
404 if (index != lastTab)
407 m_activityDataView->setTabEnabled(index+1,
true);
408 m_activityDataView->setCurrentIndex(index+1);
414 if (m_mode == Mode::UPDATE && m_confirmUpdate)
416 QMessageBox::StandardButton button = QMessageBox::question(
417 qApp->activeWindow(),
419 "You will override your activity. You could loose some data.\n" 420 "Would you duplicate your activity ?",
421 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
424 if (button == QMessageBox::Cancel)
428 else if (button == QMessageBox::Yes)
431 m_mode = Mode::CREATE;
436 bool ok = m_activityDataView->checkAndComputeData(m_actSeries, errorMsg);
439 ::fwData::Composite::sptr data = m_actSeries->getData();
442 ::fwMedData::Series::sptr series;
443 for(
const auto& elt : (*data) )
445 series = ::fwMedData::Series::dynamicCast(elt.second);
455 if (m_mode == Mode::CREATE)
460 m_actSeries->getActivityConfigId());
464 "Please, give a description of the activity.",
466 if (description.empty())
470 m_actSeries->setDescription(description);
471 ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >(s_SERIESDB_INOUT);
475 seriesDB = this->getObject< ::fwMedData::SeriesDB >();
478 helper.add(m_actSeries);
480 m_sigActivityCreated->asyncEmit(m_actSeries);
484 ::fwData::Object::ModifiedSignalType::sptr sig;
487 m_sigActivityUpdated->asyncEmit(m_actSeries);
492 QString message =
"This activity can not be created : \n";
493 message.append(QString::fromStdString(errorMsg));
494 QMessageBox::warning(qApp->activeWindow(),
"Activity Creation", message);
501 QMessageBox::warning(qApp->activeWindow(),
"Error", QString::fromStdString(errorMsg));
virtual void starting() override
This method creates the editor gui.
#define FW_DEPRECATED_KEY(newKey, access, version)
Use this macro when deprecating a service key to warn the developer.
The namespace uiMedDataQt contains editors for medical data.
virtual void stopping() override
This method destroys the editor gui.
virtual UIMEDDATAQT_API ~SActivityWizard() noexcept
Destructor. Do nothing.
Holds Activities configuration.
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
#define SLM_DEBUG_IF(message, cond)
Defines the service interface managing the editor service for object.
static FWACTIVITIES_API Activities::sptr getDefault()
Return the default global instance of Activities.
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
virtual void configuring() override
Initialize the editor.
This editor allows to select the data required by an activity in order to create the ActivitySeries...
std::string bundleVersion
Version of the bundle containing the activity.
std::string bundleId
Identifier of the bundle containing the activity.
#define SLM_ERROR(message)
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
static FWDATA_API::fwData::Object::sptr copy(const ::fwData::Object::csptr &source)
return a copy of the source. if source is a null pointer, return a null pointer.
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
static FWGUI_APIconst::fwCom::Slots::SlotKeyType s_SHOW_SLOT
Slot to show the container.
virtual void updating() override
Update the activity if it is defined in the configuration, else does nothing.
UIMEDDATAQT_API SActivityWizard() noexcept
Constructor. Do nothing.
FWGUI_API void initialize()
Initialize managers.
virtual FWSERVICES_API void info(std::ostream &_sstream)
Write information in a stream.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.