fw4spl
SSelector.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 "uiMedDataQt/editor/SSelector.hpp"
8 
9 #include "uiMedDataQt/widget/Selector.hpp"
10 
11 #include <fwCom/Signal.hpp>
12 #include <fwCom/Signal.hxx>
13 #include <fwCom/Slot.hpp>
14 #include <fwCom/Slot.hxx>
15 #include <fwCom/Slots.hpp>
16 #include <fwCom/Slots.hxx>
17 
18 #include <fwCore/base.hpp>
19 
20 #include <fwDataTools/helper/Vector.hpp>
21 
22 #include <fwGui/dialog/MessageDialog.hpp>
23 
24 #include <fwGuiQt/container/QtContainer.hpp>
25 
26 #include <fwMedData/Series.hpp>
27 #include <fwMedData/SeriesDB.hpp>
28 
29 #include <fwMedDataTools/helper/SeriesDB.hpp>
30 
31 #include <fwRuntime/operations.hpp>
32 
33 #include <fwServices/macros.hpp>
34 
35 #include <QVBoxLayout>
36 
37 namespace uiMedDataQt
38 {
39 
40 namespace editor
41 {
42 //------------------------------------------------------------------------------
43 
45 
46 //------------------------------------------------------------------------------
47 
48 const ::fwCom::Signals::SignalKeyType SSelector::s_SERIES_DOUBLE_CLICKED_SIG = "seriesDoubleClicked";
49 
50 const ::fwCom::Slots::SlotKeyType SSelector::s_ADD_SERIES_SLOT = "addSeries";
51 const ::fwCom::Slots::SlotKeyType SSelector::s_REMOVE_SERIES_SLOT = "removeSeries";
52 
53 //------------------------------------------------------------------------------
54 
56  m_allowedRemove(true),
57  m_selectionMode(QAbstractItemView::ExtendedSelection),
58  m_insertMode(false)
59 {
60  // Init
61  m_sigSeriesDoubleClicked = SeriesDoubleClickedSignalType::New();
62 
63  // Register
64  m_signals( s_SERIES_DOUBLE_CLICKED_SIG, m_sigSeriesDoubleClicked);
65 
66  newSlot(s_ADD_SERIES_SLOT, &SSelector::addSeries, this);
67  m_slotRemoveSeries = newSlot(s_REMOVE_SERIES_SLOT, &SSelector::removeSeries, this);
68 
69 }
70 
71 //------------------------------------------------------------------------------
72 
74 {
75 }
76 
77 //------------------------------------------------------------------------------
78 
79 void SSelector::info(std::ostream& _sstream )
80 {
81  // Update message
82  _sstream << std::string("SSelector");
83 }
84 
85 //------------------------------------------------------------------------------
86 
88 {
90 
91  ::fwGuiQt::container::QtContainer::sptr qtContainer = ::fwGuiQt::container::QtContainer::dynamicCast(
92  this->getContainer() );
93 
94  m_selectorWidget = new ::uiMedDataQt::widget::Selector();
95  m_selectorWidget->setSeriesIcons(m_seriesIcons);
96  m_selectorWidget->setSelectionMode(m_selectionMode);
97  m_selectorWidget->setAllowedRemove(m_allowedRemove);
98  m_selectorWidget->setInsertMode(m_insertMode);
99 
100  QVBoxLayout* layout = new QVBoxLayout();
101  layout->addWidget(m_selectorWidget);
102  qtContainer->setLayout(layout);
103 
104  QObject::connect(m_selectorWidget, SIGNAL(selectSeries(QVector< ::fwMedData::Series::sptr >,
105  QVector< ::fwMedData::Series::sptr >)),
106  this, SLOT(onSelectedSeries(QVector< ::fwMedData::Series::sptr >,
107  QVector< ::fwMedData::Series::sptr >)));
108 
109  if(!m_insertMode)
110  {
111  QObject::connect(m_selectorWidget, SIGNAL(doubleClicked(const QModelIndex&)),
112  this, SLOT(onDoubleClick(const QModelIndex&)));
113  }
114 
115  if(m_allowedRemove)
116  {
117  SLM_TRACE("CONNECT remove series slot");
118  QObject::connect(m_selectorWidget, SIGNAL(removeSeries(QVector< ::fwMedData::Series::sptr >)),
119  this, SLOT(onRemoveSeries(QVector< ::fwMedData::Series::sptr >)));
120  }
121 
122  this->updating();
123 }
124 
125 //------------------------------------------------------------------------------
126 
128 {
129  this->destroy();
130 }
131 
132 //------------------------------------------------------------------------------
133 
135 {
136  ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >("seriesDB");
137 
138  m_selectorWidget->clear();
139 
140  for(::fwMedData::Series::sptr series : seriesDB->getContainer())
141  {
142  m_selectorWidget->addSeries(series);
143  }
144 }
145 
146 //------------------------------------------------------------------------------
147 
149 {
151 
152  std::vector < ::fwRuntime::ConfigurationElement::sptr > selectionModeCfg = m_configuration->find("selectionMode");
153  if(!selectionModeCfg.empty())
154  {
155  const std::string& selectionMode = selectionModeCfg.front()->getValue();
156 
157  if(!selectionMode.empty())
158  {
159  if(selectionMode == "single")
160  {
161  m_selectionMode = QAbstractItemView::SingleSelection;
162  }
163  else if(selectionMode == "extended")
164  {
165  m_selectionMode = QAbstractItemView::ExtendedSelection;
166  }
167  else
168  {
169  SLM_WARN("value " + selectionMode + " is not managed for <selectionMode>");
170  }
171  }
172  }
173 
174  std::vector < ::fwRuntime::ConfigurationElement::sptr > allowedRemoveCfg = m_configuration->find("allowedRemove");
175  if(!allowedRemoveCfg.empty())
176  {
177  const std::string& allowedRemove = allowedRemoveCfg.front()->getValue();
178 
179  if(allowedRemove == "yes")
180  {
181  m_allowedRemove = true;
182  }
183  else if(allowedRemove == "no")
184  {
185  m_allowedRemove = false;
186  }
187  else
188  {
189  SLM_WARN("value " + allowedRemove + " is not managed for <allowedRemove>");
190  }
191  }
192 
193  std::vector < ::fwRuntime::ConfigurationElement::sptr > insertCfg = m_configuration->find("insertMode");
194  if(!insertCfg.empty())
195  {
196  const std::string& insert = insertCfg.front()->getValue();
197 
198  if(insert == "yes")
199  {
200  m_insertMode = true;
201  }
202  else if(insert == "no")
203  {
204  m_insertMode = false;
205  }
206  else
207  {
208  SLM_WARN("value " + insert + " is not managed for <insertMode>");
209  }
210  }
211 
212  std::vector < ::fwRuntime::ConfigurationElement::sptr > iconsCfg = m_configuration->find("icons");
213  if (!iconsCfg.empty())
214  {
215  SLM_ASSERT("Only one 'config' tag is allowed for SSelector configuration", iconsCfg.size() == 1);
216 
217  std::vector < ::fwRuntime::ConfigurationElement::sptr > cfg = iconsCfg.front()->find("icon");
218 
219  for(::fwRuntime::ConfigurationElement::sptr elt : cfg)
220  {
221  const std::string series = elt->getAttributeValue("series");
222  SLM_ASSERT("'series' attribute is missing", !series.empty());
223 
224  const std::string icon = elt->getAttributeValue("icon");
225  SLM_ASSERT("'icon' attribute is missing", !icon.empty());
226 
227  const auto file = ::fwRuntime::getResourceFilePath(icon);
228  m_seriesIcons[series] = file.string();
229  }
230  }
231 }
232 
233 //------------------------------------------------------------------------------
234 
235 void SSelector::onSelectedSeries(QVector< ::fwMedData::Series::sptr > selection,
236  QVector< ::fwMedData::Series::sptr > deselection)
237 {
238  ::fwData::Vector::sptr selectionVector = this->getSelection();
239  ::fwDataTools::helper::Vector vectorHelper(selectionVector);
240 
241  for( ::fwMedData::Series::sptr series : deselection)
242  {
243  vectorHelper.remove(series);
244  }
245 
246  for( ::fwMedData::Series::sptr series : selection)
247  {
248  vectorHelper.add(series);
249  }
250 
251  vectorHelper.notify();
252 }
253 
254 //------------------------------------------------------------------------------
255 
256 void SSelector::onDoubleClick(const QModelIndex& index)
257 {
258  m_selectorWidget->clearSelection();
259  m_selectorWidget->setCurrentIndex(index);
260 
261  ::fwData::Vector::sptr selectionVector = this->getSelection();
262 
263  if (m_selectorWidget->getItemType(index) == ::uiMedDataQt::widget::SelectorModel::STUDY)
264  {
265  std::stringstream str;
266  str << "Selected study. TODO";
267 
269  str.str());
270  }
271  else if (m_selectorWidget->getItemType(index) == ::uiMedDataQt::widget::SelectorModel::SERIES)
272  {
273  SLM_ASSERT("There must be only one object selected", selectionVector->size() == 1);
274  ::fwData::Object::sptr obj = selectionVector->front();
275  ::fwMedData::Series::sptr series = ::fwMedData::Series::dynamicCast(obj);
276  SLM_ASSERT("Object must be a '::fwMedData::Series'", series);
277 
278  m_sigSeriesDoubleClicked->asyncEmit(series);
279  }
280 }
281 
282 //------------------------------------------------------------------------------
283 
284 void SSelector::onRemoveSeries(QVector< ::fwMedData::Series::sptr > selection)
285 {
286  ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >("seriesDB");
287  ::fwMedDataTools::helper::SeriesDB seriesDBHelper(seriesDB);
288 
289  // Remove duplicated series
290  std::set< ::fwMedData::Series::sptr > seriesSet;
291  std::copy(selection.begin(), selection.end(), std::inserter(seriesSet, seriesSet.begin()));
292 
293  for( ::fwMedData::Series::sptr series : seriesSet)
294  {
295  seriesDBHelper.remove(series);
296  }
297 
298  {
299  auto sig = seriesDB->signal< ::fwMedData::SeriesDB::RemovedSeriesSignalType >(
301  ::fwCom::Connection::Blocker block(sig->getConnection(m_slotRemoveSeries));
302  seriesDBHelper.notify();
303  }
304 }
305 
306 //------------------------------------------------------------------------------
307 
308 ::fwData::Vector::sptr SSelector::getSelection()
309 {
310  ::fwData::Vector::sptr selection = this->getInOut< ::fwData::Vector >("selection");
311  SLM_ASSERT("Object " << m_selectionId << " is not a '::fwData::Vector'", selection);
312 
313  return selection;
314 }
315 
316 //------------------------------------------------------------------------------
317 
318 void SSelector::addSeries(::fwMedData::SeriesDB::ContainerType addedSeries)
319 {
320  for( ::fwMedData::Series::sptr series : addedSeries )
321  {
322  m_selectorWidget->addSeries(series);
323  }
324 }
325 
326 //------------------------------------------------------------------------------
327 
328 void SSelector::removeSeries(::fwMedData::SeriesDB::ContainerType removedSeries)
329 {
330  for( ::fwMedData::Series::sptr series : removedSeries )
331  {
332  m_selectorWidget->removeSeries(series);
333  }
334 }
335 
336 //------------------------------------------------------------------------------
337 
339 {
340  KeyConnectionsMap connections;
341  connections.push( "seriesDB", ::fwMedData::SeriesDB::s_ADDED_SERIES_SIG, s_ADD_SERIES_SLOT );
342  connections.push( "seriesDB", ::fwMedData::SeriesDB::s_REMOVED_SERIES_SIG, s_REMOVE_SERIES_SLOT );
343 
344  return connections;
345 }
346 
347 //------------------------------------------------------------------------------
348 
349 } // namespace editor
350 } // namespace uiMedDataQt
The namespace uiMedDataQt contains editors for medical data.
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
virtual void info(std::ostream &_sstream) override
Write information in a stream.
Definition: SSelector.cpp:79
void onSelectedSeries(QVector< ::fwMedData::Series::sptr > selection, QVector< ::fwMedData::Series::sptr > deselection)
Manages the selection vector according to selection/deselection.
Definition: SSelector.cpp:235
Class allowing to block a Connection.
Definition: Connection.hpp:20
Type to represent Study/Patient.
Defines the service interface managing the editor service for object.
Definition: IEditor.hpp:25
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.
void onRemoveSeries(QVector< ::fwMedData::Series::sptr > selection)
Removes series from seriesDB and notify.
Definition: SSelector.cpp:284
static UIMEDDATAQT_APIconst::fwCom::Signals::SignalKeyType s_SERIES_DOUBLE_CLICKED_SIG
Key in m_signals map of signal m_sigSeriesDoubleClicked.
Definition: SSelector.hpp:77
Defines an helper to modify an fwMedData::SeriesDB and create in parallel the message to announce thi...
#define SLM_WARN(message)
Definition: spyLog.hpp:261
virtual void starting() override
Installs GUI : create container and add selector.
Definition: SSelector.cpp:87
This editor shows information about the medical data. It allows to manipulate (select, erase, ...) studies and series.
Definition: SSelector.hpp:61
static FWMEDDATA_APIconst::fwCom::Signals::SignalKeyType s_ADDED_SERIES_SIG
Type of signal when series are added.
static FWMEDDATA_APIconst::fwCom::Signals::SignalKeyType s_REMOVED_SERIES_SIG
Type of signal when series are added.
FWDATATOOLS_API void remove(::fwData::Object::sptr _oldObject)
Remove an object in the vector.
#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
FWDATATOOLS_API void add(::fwData::Object::sptr _newObject)
Add an object in the vector.
virtual void configuring() override
Configures the service according to the xml tags found.
Definition: SSelector.cpp:148
::fwRuntime::ConfigurationElement::sptr m_configuration
Configuration element used to configure service internal state using a generic XML like structure TOD...
Definition: IService.hpp:670
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
virtual void stopping() override
Destroys GUI.
Definition: SSelector.cpp:127
#define SLM_TRACE(message)
Definition: spyLog.hpp:228
void onDoubleClick(const QModelIndex &index)
Send a &#39;seriesDoubleClicked&#39; signal when the user double click on a series. This signal holds the cli...
Definition: SSelector.cpp:256
virtual void updating() override
Fill selector with the series contained in SeriesDB.
Definition: SSelector.cpp:134
FWDATATOOLS_API void notify()
Send the signal of modification.
UIMEDDATAQT_API SSelector()
Constructor.
Definition: SSelector.cpp:55
Defines an helper to modify an fwData::Vector and create in parallel the message to announce this mod...
virtual UIMEDDATAQT_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
Definition: SSelector.cpp:338
FWGUI_API void initialize()
Initialize managers.
virtual UIMEDDATAQT_API ~SSelector() noexcept
Destructor.
Definition: SSelector.cpp:73