Fraxinus  16.5.0-fx-rc1
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxTreeRepository.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 #include "cxTreeRepository.h"
33 #include "cxPatientModelService.h"
34 #include "cxDefinitions.h"
35 #include "cxData.h"
36 #include "cxTreeNode.h"
37 #include "cxDataTreeNode.h"
38 #include "cxSpaceTreeNode.h"
39 #include "cxGroupTreeNode.h"
40 #include "cxTopTreeNode.h"
41 #include "cxToolTreeNode.h"
42 #include "cxLogger.h"
43 #include "cxTrackingService.h"
44 #include "cxActiveData.h"
45 #include "cxVisServices.h"
46 #include "cxShowDataTreeNode.h"
47 #include "cxViewServiceTreeNode.h"
48 #include "cxViewGroupTreeNode.h"
49 #include "cxViewService.h"
50 #include "cxStringListProperty.h"
51 #include "cxStringProperty.h"
52 
53 namespace cx
54 {
55 
56 void WidgetTypeRepository::add(QWidget *widget)
57 {
58  mWidgets.push_back(widget);
59 }
60 
61 //---------------------------------------------------------
62 //---------------------------------------------------------
63 //---------------------------------------------------------
64 
66 {
67  TreeRepositoryPtr retval(new TreeRepository(options, services));
68  retval->mSelf = retval;
69  retval->insertTopNode();
70  return retval;
71 }
72 
73 TreeRepository::TreeRepository(XmlOptionFile options, VisServicesPtr services) :
74  mInvalid(true),
75  mServices(services),
76  mOptions(options)
77 {
78  this->createVisibilityProperty();
79  this->createModeProperty();
80 
81  mWidgetTypeRepository.reset(new WidgetTypeRepository());
82 
83  this->startListen();
84 }
85 
86 void TreeRepository::createVisibilityProperty()
87 {
88  QStringList allNodeTypes = QStringList() << "data" << "metric" << "image" << "model" << "tool" << "view";
89  mVisibilityProperty = StringListProperty::initialize("visible_node_types",
90  "Visibility",
91  "Select visible node types",
92  allNodeTypes,
93  allNodeTypes,
94  mOptions.getElement());
95  connect(mVisibilityProperty.get(), &StringListProperty::changed, this, &TreeRepository::invalidate);
96 }
97 
98 void TreeRepository::createModeProperty()
99 {
100  QStringList allModes = QStringList() << "spaces" << "flat";
101 
102  mModeProperty = StringProperty::initialize("mode",
103  "mode",
104  "Node display mode",
105  allModes.front(),
106  allModes,
107  mOptions.getElement());
108  connect(mModeProperty.get(), &Property::changed, this, &TreeRepository::loaded);
109 }
110 
112 {
113  this->stopListen();
114 }
115 
117 {
118 // CX_LOG_CHANNEL_DEBUG("CA") << "TreeRepository::update(), invalid=" << mInvalid;
119  if (mInvalid)
120  this->rebuild();
121  mInvalid = true;
122 }
123 
125 {
126 // CX_LOG_CHANNEL_DEBUG("CA") << "TreeRepository::invalidate()";
127  mInvalid = true;
128  emit invalidated();
129 }
130 
131 void TreeRepository::startListen()
132 {
133  connect(this->getServices()->patient().get(), &PatientModelService::patientChanged, this, &TreeRepository::loaded);
134  connect(this->getServices()->patient().get(), &PatientModelService::dataAddedOrRemoved, this, &TreeRepository::invalidate);
135  connect(this->getServices()->tracking().get(), &TrackingService::stateChanged, this, &TreeRepository::loaded);
136  connect(this->getServices()->patient()->getActiveData().get(), &ActiveData::activeDataChanged, this, &TreeRepository::changed);
137 }
138 
139 void TreeRepository::stopListen()
140 {
141  disconnect(this->getServices()->patient().get(), &PatientModelService::patientChanged, this, &TreeRepository::loaded);
142  disconnect(this->getServices()->patient().get(), &PatientModelService::dataAddedOrRemoved, this, &TreeRepository::invalidate);
143  disconnect(this->getServices()->tracking().get(), &TrackingService::stateChanged, this, &TreeRepository::loaded);
144  disconnect(this->getServices()->patient()->getActiveData().get(), &ActiveData::activeDataChanged, this, &TreeRepository::changed);
145 }
146 
147 std::vector<TreeNodePtr> TreeRepository::getNodes()
148 {
149  return mNodes;
150 }
151 
153 {
154  for (unsigned i=0; i<mNodes.size(); ++i)
155  {
156  if (mNodes[i]->getUid()==uid)
157  return mNodes[i];
158  }
159  return TreeNodePtr();
160 }
161 
163 {
164  std::vector<TreeNodePtr> all = this->getNodes();
165  for (unsigned i=0; i<all.size(); ++i)
166  if (all[i]->getUid() == "node::invisible_top")
167  return all[i];
168  CX_LOG_CHANNEL_DEBUG("CA") << "invalid tree - did not find top node";
169  return TreeNodePtr();
170 }
171 
173 {
174  return mServices;
175 }
176 
178 {
179  return mWidgetTypeRepository;
180 }
181 
182 QString TreeRepository::getMode() const
183 {
184  return mModeProperty->getValue();
185 }
186 
188 {
189  return mVisibilityProperty->getValue();
190 }
191 
193 {
194  return mVisibilityProperty->getValueRange();
195 }
196 
197 void TreeRepository::insertTopNode()
198 {
199  // TreeNodePtr topnode(new TopTreeNode(mSelf));
200 // mNodes.push_back(topnode);
201  this->appendNode(new TopTreeNode(mSelf));
202 // CX_LOG_CHANNEL_DEBUG("CA") << " - built topnode";
203 }
204 
205 void TreeRepository::rebuild()
206 {
207  mNodes.clear();
208  for (unsigned i=0; i<mNodes.size(); ++i)
209  disconnect(mNodes[i].get(), &TreeNode::changed, this, &TreeRepository::changed);
210 
211 
212  this->insertTopNode();
213 
214  QStringList groups = QStringList() << "tool" << "data" << "space" << "view";
215  for (unsigned i=0; i<groups.size(); ++i)
216  this->insertGroupNode(groups[i]);
217 
218  this->insertSpaceNode(CoordinateSystem(csREF));
219 
220  std::map<QString, DataPtr> source = this->getServices()->patient()->getData();
221  for (std::map<QString, DataPtr>::const_iterator iter = source.begin(); iter != source.end(); ++iter)
222  {
223  this->insertDataNode(iter->second);
224  }
225  for (std::map<QString, DataPtr>::const_iterator iter = source.begin(); iter != source.end(); ++iter)
226  {
227  QString space = iter->second->getParentSpace();
228  if (space.isEmpty())
229  continue;
230  if (source.count(space))
231  continue;
232  this->insertSpaceNode(CoordinateSystem(csDATA, space));
233  }
234 
235  this->insertSpaceNode(CoordinateSystem(csPATIENTREF));
236 
237  std::map<QString, ToolPtr> tools = this->getServices()->tracking()->getTools();
238  for (std::map<QString, ToolPtr>::const_iterator iter = tools.begin(); iter != tools.end(); ++iter)
239  {
240  this->insertToolNode(iter->second);
241  }
242 
243  for (unsigned i=0; i<this->getServices()->view()->groupCount(); ++i)
244  {
245  this->appendNode(new ViewGroupTreeNode(mSelf, i));
246  }
247 
248 // for (unsigned i=0; i<mNodes.size(); ++i)
249 // CX_LOG_CHANNEL_DEBUG("CA") << " node: " << mNodes[i]->getUid();
250 }
251 
252 void TreeRepository::insertGroupNode(QString groupname)
253 {
254  if (this->getNodeForGroup(groupname))
255  return;
256  if (groupname=="view")
257  this->appendNode(new ViewServiceTreeNode(mSelf));
258  else
259  this->appendNode(new GroupTreeNode(mSelf, groupname));
260 }
261 
263 {
264  return this->getNode(QString("group_%1").arg(groupname));
265 }
266 
267 void TreeRepository::insertToolNode(ToolPtr tool)
268 {
269  if (this->getNode(tool->getUid()))
270  return;
271  this->appendNode(new ToolTreeNode(mSelf, tool));
272 }
273 
274 void TreeRepository::insertDataNode(DataPtr data)
275 {
276  if (this->getNode(data->getUid()))
277  return;
278 
279  this->appendNode(new DataTreeNode(mSelf, data));
280 
281  this->appendNode(new ShowVolumeDataTreeNode(mSelf, data));
282  this->appendNode(new ShowSlice2DDataTreeNode(mSelf, data));
283  this->appendNode(new ShowSlice3DDataTreeNode(mSelf, data));
284 }
285 
286 void TreeRepository::appendNode(TreeNode* rawNode)
287 {
288  TreeNodePtr bnode(rawNode);
289  TreeNodePtr node(new CachedTreeNode(bnode));
290 
291  if (!this->getNode(node->getUid()))
292  {
293  connect(node.get(), &TreeNode::changed, this, &TreeRepository::changed);
294  connect(node.get(), &TreeNode::changed, this, &TreeRepository::invalidated);
295 // connect(node.get(), &TreeNode::changed, this, &TreeRepository::onChanged);
296  mNodes.push_back(node);
297  }
298 }
299 
300 //void TreeRepository::onChanged()
301 //{
302 // CX_LOG_CHANNEL_DEBUG("CA") << "TreeRepository::onChanged()";
303 //}
304 
305 void TreeRepository::insertSpaceNode(CoordinateSystem space)
306 {
307  if (this->getNode(space.toString()) || this->getNode(space.mRefObject))
308  return;
309  this->appendNode(new SpaceTreeNode(mSelf, space));
310 }
311 
312 
313 } // namespace cx
boost::shared_ptr< class TreeRepository > TreeRepositoryPtr
TreeNodePtr getNodeForGroup(QString groupname)
boost::shared_ptr< TreeNode > TreeNodePtr
void changed()
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:62
csREF
the data reference space (r) using LPS (left-posterior-superior) coordinates.
QDomElement getElement()
return the current element
csDATA
a datas space (d)
static StringListPropertyPtr initialize(const QString &uid, QString name, QString help, QStringList value, QStringList range, QDomNode root=QDomNode())
csPATIENTREF
the patient/tool reference space (pr)
boost::shared_ptr< class Data > DataPtr
QStringList getVisibleNodeTypes() const
std::vector< TreeNodePtr > getNodes()
void activeDataChanged(const QString &uId)
TreeNodePtr getTopNode()
QString getMode() const
#define CX_LOG_CHANNEL_DEBUG(channel)
Definition: cxLogger.h:122
boost::shared_ptr< class WidgetTypeRepository > WidgetTypeRepositoryPtr
static TreeRepositoryPtr create(XmlOptionFile options, VisServicesPtr services)
void changed()
emit when the underlying data value is changed: The user interface will be updated.
static StringPropertyPtr initialize(const QString &uid, QString name, QString help, QString value, QStringList range, QDomNode root=QDomNode())
void add(QWidget *widget)
QStringList getAllNodeTypes() const
VisServicesPtr getServices()
WidgetTypeRepositoryPtr getWidgetTypeRepository()
Helper class for xml files used to store ssc/cx data.
TreeNodePtr getNode(QString uid)
boost::shared_ptr< class Tool > ToolPtr