Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxLayoutRepository.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) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxLayoutRepository.h"
13 #include "cxLayoutData.h"
14 #include "cxTypeConversions.h"
15 #include "cxLogger.h"
16 
17 namespace cx
18 {
19 
21 {
22  this->addDefaults();
23 }
24 
25 LayoutData LayoutRepository::get(const QString uid) const
26 {
27  unsigned pos = this->indexOf(uid);
28  if (pos != mLayouts.size())
29  return mLayouts[pos];
30  if(!uid.isEmpty())
31  CX_LOG_WARNING() << "Layout don't exist: " << uid;
32  return LayoutData();
33 }
34 
35 bool LayoutRepository::exists(const QString uid) const
36 {
37  unsigned pos = this->indexOf(uid);
38  if (pos != mLayouts.size())
39  return true;
40  else
41  return false;
42 }
43 
44 std::vector<QString> LayoutRepository::getAvailable() const
45 {
46  std::vector<QString> retval;
47  for (unsigned i = 0; i < mLayouts.size(); ++i)
48  {
49  retval.push_back(mLayouts[i].getUid());
50  }
51  return retval;
52 }
53 
55 {
56  unsigned pos = this->indexOf(data.getUid());
57  if (pos == mLayouts.size())
58  mLayouts.push_back(data);
59  else
60  mLayouts[pos] = data;
61  emit layoutChanged(data.getUid());
62 }
63 
65 {
66  int count = 0;
67 
68  for (LayoutDataVector::const_iterator iter = mLayouts.begin(); iter != mLayouts.end(); ++iter)
69  {
70  if (iter->getUid() == qstring_cast(count))
71  count = iter->getUid().toInt() + 1;
72  }
73  return qstring_cast(count);
74 }
75 
76 void LayoutRepository::erase(const QString uid)
77 {
78  mLayouts.erase(mLayouts.begin() + indexOf(uid));
79  emit layoutChanged(uid);
80 }
81 
82 unsigned LayoutRepository::indexOf(const QString uid) const
83 {
84  for (unsigned i = 0; i < mLayouts.size(); ++i)
85  {
86  if (mLayouts[i].getUid() == uid)
87  return i;
88  }
89  return mLayouts.size();
90 }
91 
92 bool LayoutRepository::isCustom(const QString& uid) const
93 {
94  bool isLayout = false;
95  for (unsigned i = 0; i < mLayouts.size(); ++i)
96  {
97  if (uid == mLayouts[i].getUid())
98  {
99  isLayout = true;
100  break;
101  }
102  }
103 
104  bool isDefaultLayout = std::count(mDefaultLayouts.begin(), mDefaultLayouts.end(), uid);
105 
106  bool retval = false;
107  if (isLayout && !isDefaultLayout)
108  retval = true;
109 
110  return retval;
111 }
112 
114 {
115  // load custom layouts:
116  mLayouts.clear();
117 
118  this->blockSignals(true);
119 
120  QDomElement layouts = file.getElement("layouts");
121  QDomNode layout = layouts.firstChild();
122  for (; !layout.isNull(); layout = layout.nextSibling())
123  {
124  if (layout.toElement().tagName() != "layout")
125  continue;
126 
127  LayoutData data;
128  data.parseXml(layout);
129 
130  this->insert(data);
131  }
132 
133  std::vector<QString> custom = this->getAvailable();
134  this->addDefaults(); // ensure we overwrite loaded layouts
135 
136  this->blockSignals(false);
137 
138  for (unsigned i=0; i<custom.size(); ++i)
139  emit layoutChanged(custom[i]);
140 }
141 
143 {
144  XmlOptionFile layoutsNode = file.descend("layouts");
145  layoutsNode.removeChildren();
146  for (LayoutDataVector::iterator iter = mLayouts.begin(); iter != mLayouts.end(); ++iter)
147  {
148  if (!this->isCustom(iter->getUid()))
149  continue; // dont store default layouts - they are created automatically.
150 
151  QDomElement layoutNode = file.getDocument().createElement("layout");
152  layoutsNode.getElement().appendChild(layoutNode);
153  iter->addXml(layoutNode);
154  }
155 }
156 
160 void LayoutRepository::addDefaults()
161 {
162  mDefaultLayouts.clear();
163 
164  /*
165  *
166  3D______________
167 
168  3D
169  3D AD
170  3D ACS
171 
172  Oblique ________
173 
174  3D AnyDual x1
175  3D AnyDual x2
176  AnyDual x3
177 
178  Orthogonal______
179 
180  3D ACS x1
181  3D ACS x2
182  ACS x3
183 
184  RT______________
185 
186  RT
187  Us Acq
188  */
189 
190  // ------------------------------------------------------
191  // --- group of 3D-based layouts ------------------------
192  // ------------------------------------------------------
193  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_3D", "3D"));
194  {
195  // 3D only
196  LayoutData layout = LayoutData::create("LAYOUT_3D", "3D", 1, 1);
197  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
198  this->addDefault(layout);
199  }
200  {
201  // 3D ACS
202  LayoutData layout = LayoutData::create("LAYOUT_3D_ACS", "3D ACS", 3, 4);
203  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
204  layout.setView(1, ptAXIAL, LayoutRegion(0, 3));
205  layout.setView(1, ptCORONAL, LayoutRegion(1, 3));
206  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 3));
207  this->addDefault(layout);
208  }
209  {
210  // A 3DCS
211  LayoutData layout = LayoutData::create("LAYOUT_A_3DCS", "A 3DCS", 3, 4);
212  layout.setView(1, ptAXIAL, LayoutRegion(0, 0, 3, 3));
213  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 3));
214  layout.setView(1, ptCORONAL, LayoutRegion(1, 3));
215  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 3));
216  this->addDefault(layout);
217  }
218  {
219  // 3D 3DAC
220  LayoutData layout = LayoutData::create("LAYOUT_3D_3DAC", "3D 3DAC", 3, 5);
221  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
222  layout.setView(1, View::VIEW_3D, LayoutRegion(0, 3, 1, 2));
223  layout.setView(2, ptAXIAL, LayoutRegion(1, 3, 1, 2));
224  layout.setView(2, ptCORONAL, LayoutRegion(2, 3, 1, 2));
225  this->addDefault(layout);
226  }
227  {
228  // 3D Any
229  LayoutData layout = LayoutData::create("LAYOUT_3D_AD", "3D AnyDual", 2, 4);
230  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 3));
231  layout.setView(1, ptANYPLANE, LayoutRegion(0, 3));
232  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 3));
233  this->addDefault(layout);
234  }
235  {
236  // 3D ACS in a single view group
237  LayoutData layout = LayoutData::create("LAYOUT_3D_ACS_SINGLE", "3D ACS Connected", 3, 4);
238  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
239  layout.setView(0, ptAXIAL, LayoutRegion(0, 3));
240  layout.setView(0, ptCORONAL, LayoutRegion(1, 3));
241  layout.setView(0, ptSAGITTAL, LayoutRegion(2, 3));
242  this->addDefault(layout);
243  }
244  {
245  // 3D Any in a single view group
246  LayoutData layout = LayoutData::create("LAYOUT_3D_AD_SINGLE", "3D AnyDual Connected", 2, 4);
247  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 3));
248  layout.setView(0, ptANYPLANE, LayoutRegion(0, 3));
249  layout.setView(0, ptSIDEPLANE, LayoutRegion(1, 3));
250  this->addDefault(layout);
251  }
252 
253  // ------------------------------------------------------
254  // --- group of oblique (Anyplane-based) layouts --------
255  // ------------------------------------------------------
256  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_Oblique", "Oblique"));
257  {
258  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_3DAnyDual_x1", "3D Any Dual x1", 1, 3);
259  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
260  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
261  layout.setView(1, ptSIDEPLANE, LayoutRegion(0, 2));
262  this->addDefault(layout);
263  }
264  {
265  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_3DAnyDual_x2", "3D Any Dual x2", 2, 3);
266  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 1));
267  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
268  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 1));
269  layout.setView(2, ptANYPLANE, LayoutRegion(0, 2));
270  layout.setView(2, ptSIDEPLANE, LayoutRegion(1, 2));
271  this->addDefault(layout);
272  }
273  {
274  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_AnyDual_x3", "Any Dual x3", 2, 3);
275  layout.setView(0, ptANYPLANE, LayoutRegion(0, 0));
276  layout.setView(0, ptSIDEPLANE, LayoutRegion(1, 0));
277  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
278  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 1));
279  layout.setView(2, ptANYPLANE, LayoutRegion(0, 2));
280  layout.setView(2, ptSIDEPLANE, LayoutRegion(1, 2));
281  this->addDefault(layout);
282  }
283 
284  // ------------------------------------------------------
285  // --- group of orthogonal (ACS-based) layouts ----------
286  // ------------------------------------------------------
287  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_Orthogonal", "Orthogonal"));
288  {
289  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x1", "3D ACS x1", 2, 2);
290  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
291  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
292  layout.setView(1, ptCORONAL, LayoutRegion(1, 0));
293  layout.setView(1, ptSAGITTAL, LayoutRegion(1, 1));
294  this->addDefault(layout);
295  }
296  {
297  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x2", "3D ACS x2", 3, 3);
298  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 1));
299  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
300  layout.setView(1, ptCORONAL, LayoutRegion(1, 1));
301  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 1));
302  layout.setView(2, ptAXIAL, LayoutRegion(0, 2));
303  layout.setView(2, ptCORONAL, LayoutRegion(1, 2));
304  layout.setView(2, ptSAGITTAL, LayoutRegion(2, 2));
305  this->addDefault(layout);
306  }
307  {
308  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x3", "ACS x3", 3, 3);
309  layout.setView(0, ptAXIAL, LayoutRegion(0, 0));
310  layout.setView(0, ptCORONAL, LayoutRegion(1, 0));
311  layout.setView(0, ptSAGITTAL, LayoutRegion(2, 0));
312  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
313  layout.setView(1, ptCORONAL, LayoutRegion(1, 1));
314  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 1));
315  layout.setView(2, ptAXIAL, LayoutRegion(0, 2));
316  layout.setView(2, ptCORONAL, LayoutRegion(1, 2));
317  layout.setView(2, ptSAGITTAL, LayoutRegion(2, 2));
318  this->addDefault(layout);
319  }
320 
321  // ------------------------------------------------------
322  // --- group of RTsource-based layouts - single viewgroup
323  // ------------------------------------------------------
324  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_RT", "Realtime Source"));
325  {
326  LayoutData layout = LayoutData::create("LAYOUT_RT_1X1", "RT", 1, 1);
327  layout.setView(0, View::VIEW_REAL_TIME, LayoutRegion(0, 0));
328  this->addDefault(layout);
329  }
330  {
331  LayoutData layout = LayoutData::create("LAYOUT_US_Acquisition", "US Acquisition", 2, 3);
332  layout.setView(0, ptANYPLANE, LayoutRegion(1, 2, 1, 1));
333  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 2, 1, 1));
334  layout.setView(0, View::VIEW_REAL_TIME, LayoutRegion(0, 0, 2, 2));
335  this->addDefault(layout);
336  }
337 }
338 
340 {
341  mDefaultLayouts.push_back(data.getUid());
342  mLayouts.push_back(data);
343 }
344 
345 } // namespace cx
346 
347 
QString qstring_cast(const T &val)
void insert(const LayoutData &data)
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:39
static LayoutData createHeader(QString uid, QString name)
bool exists(const QString uid) const
ptAXIAL
a slice seen from the top of the patient
Definition: cxDefinitions.h:39
QString getUid() const
Definition: cxLayoutData.h:88
QDomElement getElement()
return the current element
ptSAGITTAL
a slice seen from the side of the patient
Definition: cxDefinitions.h:39
LayoutData get(const QString uid) const
bool isCustom(const QString &uid) const
void layoutChanged(QString uid)
void setView(int group, PLANE_TYPE type, LayoutRegion region)
void parseXml(QDomNode node)
load state from xml
void save(XmlOptionFile file)
QDomDocument getDocument()
returns the document
void load(XmlOptionFile file)
void erase(const QString uid)
void removeChildren()
remove all child nodes of the current element.
#define CX_LOG_WARNING
Definition: cxLogger.h:98
ptANYPLANE
a plane aligned with the tool base plane
Definition: cxDefinitions.h:39
std::vector< QString > getAvailable() const
static LayoutData create(QString uid, QString name, int rows, int cols)
Helper class for xml files used to store ssc/cx data.
void addDefault(LayoutData data)
ptSIDEPLANE
z-rotated 90* relative to anyplane (dual anyplane)
Definition: cxDefinitions.h:39
XmlOptionFile descend(QString element) const
step one level down in the xml tree
QString generateUid() const
Namespace for all CustusX production code.