7 #include "guiQt/editor/SDynamicView.hpp" 9 #include <fwActivities/IActivityValidator.hpp> 10 #include <fwActivities/IValidator.hpp> 12 #include <fwCom/Signal.hxx> 13 #include <fwCom/Slot.hxx> 14 #include <fwCom/Slots.hxx> 16 #include <fwData/Boolean.hpp> 17 #include <fwData/Composite.hpp> 18 #include <fwData/String.hpp> 20 #include <fwDataCamp/getObject.hpp> 22 #include <fwGui/dialog/MessageDialog.hpp> 23 #include <fwGui/GuiRegistry.hpp> 25 #include <fwRuntime/operations.hpp> 27 #include <fwServices/macros.hpp> 28 #include <fwServices/registry/AppConfig.hpp> 30 #include <fwTools/dateAndTime.hpp> 31 #include <fwTools/UUID.hpp> 33 #include <boost/foreach.hpp> 44 static const ::fwCom::Slots::SlotKeyType s_CREATE_TAB_SLOT =
"createTab";
46 static const ::fwCom::Signals::SignalKeyType s_ACTIVITY_SELECTED_SLOT =
"activitySelected";
47 static const ::fwCom::Signals::SignalKeyType s_NOTHING_SELECTED_SLOT =
"nothingSelected";
54 m_mainActivityClosable(true)
56 m_dynamicConfigStartStop =
false;
58 newSlot(s_CREATE_TAB_SLOT, &SDynamicView::createTab,
this);
60 m_sigActivitySelected = newSignal< ActivitySelectedSignalType >(s_ACTIVITY_SELECTED_SLOT);
61 m_sigNothingSelected = newSignal< NothingSelectedSignalType >(s_NOTHING_SELECTED_SLOT);
76 typedef ::fwRuntime::ConfigurationElement::sptr ConfigType;
78 ConfigType activityConfig =
m_configuration->findConfigurationElement(
"mainActivity");
81 const std::string closableStr = activityConfig->getAttributeValue(
"closable");
82 SLM_ASSERT(
"main activity 'closable' attribute value must be 'yes', 'true', 'no' or 'false'",
83 closableStr ==
"yes" || closableStr ==
"true" ||
84 closableStr ==
"no" || closableStr ==
"false");
85 const bool closable = (closableStr ==
"yes" || closableStr ==
"true");
86 m_mainActivityClosable = closable;
96 ::fwGuiQt::container::QtContainer::sptr parentContainer
97 = ::fwGuiQt::container::QtContainer::dynamicCast( this->getContainer() );
99 m_tabWidget =
new QTabWidget();
100 m_tabWidget->setTabsClosable(
true );
101 m_tabWidget->setDocumentMode(
true );
102 m_tabWidget->setMovable(
true );
104 QObject::connect(m_tabWidget, SIGNAL(tabCloseRequested(
int)),
this, SLOT(
closeTabSignal(
int)));
105 QObject::connect(m_tabWidget, SIGNAL(currentChanged(
int)),
this, SLOT(
changedTab(
int)));
107 QBoxLayout* layout =
new QBoxLayout(QBoxLayout::TopToBottom);
108 layout->addWidget( m_tabWidget );
110 parentContainer->setLayout(layout);
116 this->buildMainActivity();
125 while(m_tabWidget->count())
127 this->closeTab(0,
true);
129 m_tabWidget->clear();
149 void SDynamicView::launchActivity(::fwMedData::ActivitySeries::sptr activitySeries)
153 SDynamicViewInfo viewInfo = this->createViewInfo(activitySeries);
154 viewInfo.closable =
true;
156 this->launchTab(viewInfo);
164 SDynamicViewInfo viewInfo;
174 this->launchTab(viewInfo);
179 void SDynamicView::launchTab(SDynamicViewInfo& info)
181 static int count = 0;
182 ActivityIdType::iterator iter = std::find(m_activityIds.begin(), m_activityIds.end(), info.activitySeries->getID());
184 if (iter != m_activityIds.end())
187 "The current activity is already launched. \n" 188 "It cannot be launched twice.",
189 ::fwGui::dialog::IMessageDialog::WARNING);
193 if ( m_titleToCount.find( info.title ) != m_titleToCount.end() )
195 m_titleToCount[ info.title ]++;
199 m_titleToCount[ info.title ] = 1;
202 QString finalTitle = QString(
"%1 %2").arg( info.title.c_str(),
"(%1)" ).arg( m_titleToCount[ info.title ] );
203 info.wid = QString(
"SDynamicView-%1").arg(count++).toStdString();
205 ::fwGuiQt::container::QtContainer::sptr subContainer = ::fwGuiQt::container::QtContainer::New();
206 QWidget* widget =
new QWidget(m_tabWidget);
207 subContainer->setQtContainer(widget);
210 info.replaceMap[
"WID_PARENT" ] = info.wid;
212 info.replaceMap[
"GENERIC_UID"] = genericUidAdaptor;
218 helper->setConfig( info.viewConfigID, info.replaceMap );
219 if (!m_dynamicConfigStartStop)
228 catch( std::exception& e )
232 ::fwGui::dialog::IMessageDialog::CRITICAL);
237 info.container = subContainer;
238 info.helper = helper;
239 m_activityIds.insert(info.activitySeries->getID());
241 m_dynamicInfoMap[widget] =
info;
242 m_tabIDList.insert(info.tabID);
244 int index = m_tabWidget->addTab(widget, finalTitle );
245 if(!info.tooltip.empty())
247 m_tabWidget->setTabToolTip(index, QString::fromStdString(info.tooltip));
249 if(!info.icon.empty())
251 m_tabWidget->setTabIcon(index, QIcon(QString::fromStdString(info.icon)) );
253 m_tabWidget->setCurrentWidget(widget);
266 closeTab( index,
false );
271 void SDynamicView::closeTab(
int index,
bool forceClose )
273 QWidget* widget = m_tabWidget->widget(index);
275 SLM_ASSERT(
"Widget is not in dynamicInfoMap", m_dynamicInfoMap.find(widget) != m_dynamicInfoMap.end());
276 SDynamicViewInfo info = m_dynamicInfoMap[widget];
277 if ( info.closable || forceClose )
279 m_tabIDList.erase(info.tabID);
280 if (!m_dynamicConfigStartStop)
282 info.helper->stopAndDestroy();
286 if (info.helper->isStarted())
290 info.helper->destroy();
296 m_tabWidget->removeTab(index);
300 info.container->destroyContainer();
301 info.container.reset();
302 m_dynamicInfoMap.erase(widget);
303 m_activityIds.erase(info.activitySeries->getID());
308 "The tab " + info.title +
" can not be closed.",
309 ::fwGui::dialog::IMessageDialog::INFO);
317 QWidget* widget = m_tabWidget->widget(index);
319 if (m_dynamicConfigStartStop && widget != m_currentWidget)
323 SDynamicViewInfo oldinfo = m_dynamicInfoMap[m_currentWidget];
324 oldinfo.helper->stop();
329 SDynamicViewInfo newinfo = m_dynamicInfoMap[widget];
330 if (!newinfo.helper->isStarted())
332 newinfo.helper->start();
333 newinfo.helper->update();
337 m_currentWidget = widget;
341 SDynamicViewInfo info = m_dynamicInfoMap[widget];
342 m_sigActivitySelected->asyncEmit(info.activitySeries);
346 m_sigNothingSelected->asyncEmit();
352 void SDynamicView::buildMainActivity()
358 SDynamicViewInfo viewInfo;
359 viewInfo = this->createViewInfo(actSeries);
360 viewInfo.closable = m_mainActivityClosable;
362 this->launchTab(viewInfo);
368 SDynamicView::SDynamicViewInfo SDynamicView::createViewInfo(::fwMedData::ActivitySeries::sptr activitySeries)
370 ReplaceMapType replaceMap;
377 if(info.tabInfo.empty())
379 tabInfo = info.title;
383 std::string newTabInfo = info.tabInfo;
384 ::boost::regex e(
"(!(([[:word:]]+\\.?)+[[:word:]]))");
385 ::boost::smatch what;
386 if(boost::regex_search(newTabInfo, what, e))
388 std::string submatch(what[1].first, what[1].second);
390 submatch.replace(0, 1,
"@");
392 ::fwData::Object::sptr obj = ::fwDataCamp::getObject(activitySeries->getData(), submatch);
393 OSLM_ASSERT(
"Invalid seshat path : '" << submatch <<
"'", obj);
395 ::fwData::String::sptr stringParameter = ::fwData::String::dynamicCast(obj);
397 std::string tabInfoSeshat;
401 tabInfoSeshat = stringParameter->getValue();
405 OSLM_WARN(
"Seshat path '" << submatch <<
"' doesn't reference an fwData::String");
408 submatch.replace(0, 1,
"!");
409 ::boost::algorithm::replace_all(newTabInfo, submatch, tabInfoSeshat);
412 tabInfo = newTabInfo;
415 this->
translateParameters(activitySeries->getData(), info.appConfig.parameters, replaceMap);
416 replaceMap[
"AS_UID"] = activitySeries->getID();
418 SDynamicViewInfo viewInfo;
419 viewInfo.title = info.title;
420 viewInfo.icon = info.icon;
421 viewInfo.tooltip = tabInfo;
422 viewInfo.viewConfigID = info.appConfig.id;
423 viewInfo.activitySeries = activitySeries;
424 viewInfo.replaceMap = replaceMap;
const std::string & getTitle() const
Return activity title.
This editor manages tabs containing activities.
virtual GUIQT_API ~SDynamicView() noexcept
Destructor. Do nothing.
virtual void stopping() override
Destroy the container.
static FWGUI_API void unregisterWIDContainer(std::string wid)
Unregisters container associate with window ID.
const ReplaceMapType & getReplaceMap() const
Return the map of the string association to replace in config.
Holds Activities configuration.
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
virtual void configuring() override
Configure the view.
#define SLM_TRACE_FUNC()
Trace contextual function signature.
static FWGUI_API IMessageDialog::Buttons showMessageDialog(const std::string &title, const std::string &message,::fwGui::dialog::IMessageDialog::Icons icon=INFO)
static FWACTIVITIES_API Activities::sptr getDefault()
Return the default global instance of Activities.
virtual void starting() override
Install the container.
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
std::string m_mainActivityId
configuration id of the main activity
virtual void info(std::ostream &_sstream) override
Write information in a stream.
ParametersType m_parameters
parameters given in configuration
void closeTabSignal(int index)
Called when the tab close button is clicked: close the tab if it is "closable".
virtual FWGUI_API bool validateActivity(::fwMedData::ActivitySeries::sptr activitySeries) const
Check if the activity is valid by calling the activity validator.
const std::string & getTabID() const
Return tab identifier.
virtual FWGUI_API::fwMedData::ActivitySeries::sptr createMainActivity() const
Create the activity series given in 'mainActivity' configuration.
static FWGUI_API void registerWIDContainer(std::string wid,::fwGui::container::fwContainer::sptr container)
Registers container associate with window ID.
virtual void swapping() override
Swap.
void changedTab(int index)
Called when the current tab selection changed.
Activity information sent by signal to launch new activities in a tab.
const std::string & getAppConfigID() const
Return appConfig identifier.
#define OSLM_ERROR(message)
#define OSLM_WARN(message)
const std::string & getIconPath() const
Return activity icon path.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
GUIQT_API SDynamicView() noexcept
Constructor. Do nothing.
::fwRuntime::ConfigurationElement::sptr m_configuration
Configuration element used to configure service internal state using a generic XML like structure TOD...
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
bool isClosable() const
Return if the activity can be closed.
virtual FWGUI_API void configuring() override
Parse the configuration.
static FWSERVICES_API std::shared_ptr< IAppConfigManager > New()
const ::fwMedData::ActivitySeries::sptr & getActivitySeries() const
Return activity series.
Defines the base class for services displaying activity view.
static FWSERVICES_API std::string getUniqueIdentifier(const std::string &serviceUid="")
Create an unique identifier.
virtual void updating() override
Update.
const std::string & getToolTip() const
Return tooltip.
The namespace guiQt contains the basic services to build the application IHM with Qt...
virtual FWGUI_API void translateParameters(::fwData::Object::sptr sourceObj, const ParametersType ¶meters, ReplaceMapType &replaceMap)
Translate parameters from source object.