CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 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 
33 #include "cxLayoutRepository.h"
34 #include "cxLayoutData.h"
35 #include "cxTypeConversions.h"
36 
37 namespace cx
38 {
39 
41 {
42  this->addDefaults();
43 }
44 
45 LayoutData LayoutRepository::get(const QString uid) const
46 {
47  unsigned pos = this->indexOf(uid);
48  if (pos != mLayouts.size())
49  return mLayouts[pos];
50  return LayoutData();
51 }
52 
53 std::vector<QString> LayoutRepository::getAvailable() const
54 {
55  std::vector<QString> retval;
56  for (unsigned i = 0; i < mLayouts.size(); ++i)
57  {
58  retval.push_back(mLayouts[i].getUid());
59  }
60  return retval;
61 }
62 
64 {
65  unsigned pos = this->indexOf(data.getUid());
66  if (pos == mLayouts.size())
67  mLayouts.push_back(data);
68  else
69  mLayouts[pos] = data;
70  emit layoutChanged(data.getUid());
71 }
72 
74 {
75  int count = 0;
76 
77  for (LayoutDataVector::const_iterator iter = mLayouts.begin(); iter != mLayouts.end(); ++iter)
78  {
79  if (iter->getUid() == qstring_cast(count))
80  count = iter->getUid().toInt() + 1;
81  }
82  return qstring_cast(count);
83 }
84 
85 void LayoutRepository::erase(const QString uid)
86 {
87  mLayouts.erase(mLayouts.begin() + indexOf(uid));
88  emit layoutChanged(uid);
89 }
90 
91 unsigned LayoutRepository::indexOf(const QString uid) const
92 {
93  for (unsigned i = 0; i < mLayouts.size(); ++i)
94  {
95  if (mLayouts[i].getUid() == uid)
96  return i;
97  }
98  return mLayouts.size();
99 }
100 
101 bool LayoutRepository::isCustom(const QString& uid) const
102 {
103  bool isLayout = false;
104  for (unsigned i = 0; i < mLayouts.size(); ++i)
105  {
106  if (uid == mLayouts[i].getUid())
107  {
108  isLayout = true;
109  break;
110  }
111  }
112 
113  bool isDefaultLayout = std::count(mDefaultLayouts.begin(), mDefaultLayouts.end(), uid);
114 
115  bool retval = false;
116  if (isLayout && !isDefaultLayout)
117  retval = true;
118 
119  return retval;
120 }
121 
123 {
124  // load custom layouts:
125  mLayouts.clear();
126 
127  this->blockSignals(true);
128 
129  QDomElement layouts = file.getElement("layouts");
130  QDomNode layout = layouts.firstChild();
131  for (; !layout.isNull(); layout = layout.nextSibling())
132  {
133  if (layout.toElement().tagName() != "layout")
134  continue;
135 
136  LayoutData data;
137  data.parseXml(layout);
138 
139  this->insert(data);
140  }
141 
142  std::vector<QString> custom = this->getAvailable();
143  this->addDefaults(); // ensure we overwrite loaded layouts
144 
145  this->blockSignals(false);
146 
147  for (unsigned i=0; i<custom.size(); ++i)
148  emit layoutChanged(custom[i]);
149 }
150 
152 {
153  XmlOptionFile layoutsNode = file.descend("layouts");
154  layoutsNode.removeChildren();
155  for (LayoutDataVector::iterator iter = mLayouts.begin(); iter != mLayouts.end(); ++iter)
156  {
157  if (!this->isCustom(iter->getUid()))
158  continue; // dont store default layouts - they are created automatically.
159 
160  QDomElement layoutNode = file.getDocument().createElement("layout");
161  layoutsNode.getElement().appendChild(layoutNode);
162  iter->addXml(layoutNode);
163  }
164 }
165 
169 void LayoutRepository::addDefaults()
170 {
171  mDefaultLayouts.clear();
172 
173  /*
174  *
175  3D______________
176 
177  3D
178  3D AD
179  3D ACS
180 
181  Oblique ________
182 
183  3D AnyDual x1
184  3D AnyDual x2
185  AnyDual x3
186 
187  Orthogonal______
188 
189  3D ACS x1
190  3D ACS x2
191  ACS x3
192 
193  RT______________
194 
195  RT
196  Us Acq
197  */
198 
199  // ------------------------------------------------------
200  // --- group of 3D-based layouts ------------------------
201  // ------------------------------------------------------
202  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_3D", "3D"));
203  {
204  // 3D only
205  LayoutData layout = LayoutData::create("LAYOUT_3D", "3D", 1, 1);
206  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
207  this->addDefault(layout);
208  }
209  {
210  // 3D ACS
211  LayoutData layout = LayoutData::create("LAYOUT_3D_ACS", "3D ACS", 3, 4);
212  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
213  layout.setView(1, ptAXIAL, 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 Any
220  LayoutData layout = LayoutData::create("LAYOUT_3D_AD", "3D AnyDual", 2, 4);
221  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 3));
222  layout.setView(1, ptANYPLANE, LayoutRegion(0, 3));
223  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 3));
224  this->addDefault(layout);
225  }
226  {
227  // 3D ACS in a single view group
228  LayoutData layout = LayoutData::create("LAYOUT_3D_ACS_SINGLE", "3D ACS Connected", 3, 4);
229  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
230  layout.setView(0, ptAXIAL, LayoutRegion(0, 3));
231  layout.setView(0, ptCORONAL, LayoutRegion(1, 3));
232  layout.setView(0, ptSAGITTAL, LayoutRegion(2, 3));
233  this->addDefault(layout);
234  }
235  {
236  // 3D Any in a single view group
237  LayoutData layout = LayoutData::create("LAYOUT_3D_AD_SINGLE", "3D AnyDual Connected", 2, 4);
238  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 3));
239  layout.setView(0, ptANYPLANE, LayoutRegion(0, 3));
240  layout.setView(0, ptSIDEPLANE, LayoutRegion(1, 3));
241  this->addDefault(layout);
242  }
243 
244  // ------------------------------------------------------
245  // --- group of oblique (Anyplane-based) layouts --------
246  // ------------------------------------------------------
247  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_Oblique", "Oblique"));
248  {
249  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_3DAnyDual_x1", "3D Any Dual x1", 1, 3);
250  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
251  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
252  layout.setView(1, ptSIDEPLANE, LayoutRegion(0, 2));
253  this->addDefault(layout);
254  }
255  {
256  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_3DAnyDual_x2", "3D Any Dual x2", 2, 3);
257  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 1));
258  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
259  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 1));
260  layout.setView(2, ptANYPLANE, LayoutRegion(0, 2));
261  layout.setView(2, ptSIDEPLANE, LayoutRegion(1, 2));
262  this->addDefault(layout);
263  }
264  {
265  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_AnyDual_x3", "Any Dual x3", 2, 3);
266  layout.setView(0, ptANYPLANE, LayoutRegion(0, 0));
267  layout.setView(0, ptSIDEPLANE, LayoutRegion(1, 0));
268  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
269  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 1));
270  layout.setView(2, ptANYPLANE, LayoutRegion(0, 2));
271  layout.setView(2, ptSIDEPLANE, LayoutRegion(1, 2));
272  this->addDefault(layout);
273  }
274 
275  // ------------------------------------------------------
276  // --- group of orthogonal (ACS-based) layouts ----------
277  // ------------------------------------------------------
278  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_Orthogonal", "Orthogonal"));
279  {
280  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x1", "3D ACS x1", 2, 2);
281  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
282  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
283  layout.setView(1, ptCORONAL, LayoutRegion(1, 0));
284  layout.setView(1, ptSAGITTAL, LayoutRegion(1, 1));
285  this->addDefault(layout);
286  }
287  {
288  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x2", "3D ACS x2", 3, 3);
289  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 1));
290  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
291  layout.setView(1, ptCORONAL, LayoutRegion(1, 1));
292  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 1));
293  layout.setView(2, ptAXIAL, LayoutRegion(0, 2));
294  layout.setView(2, ptCORONAL, LayoutRegion(1, 2));
295  layout.setView(2, ptSAGITTAL, LayoutRegion(2, 2));
296  this->addDefault(layout);
297  }
298  {
299  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x3", "ACS x3", 3, 3);
300  layout.setView(0, ptAXIAL, LayoutRegion(0, 0));
301  layout.setView(0, ptCORONAL, LayoutRegion(1, 0));
302  layout.setView(0, ptSAGITTAL, LayoutRegion(2, 0));
303  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
304  layout.setView(1, ptCORONAL, LayoutRegion(1, 1));
305  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 1));
306  layout.setView(2, ptAXIAL, LayoutRegion(0, 2));
307  layout.setView(2, ptCORONAL, LayoutRegion(1, 2));
308  layout.setView(2, ptSAGITTAL, LayoutRegion(2, 2));
309  this->addDefault(layout);
310  }
311 
312  // ------------------------------------------------------
313  // --- group of RTsource-based layouts - single viewgroup
314  // ------------------------------------------------------
315  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_RT", "Realtime Source"));
316  {
317  LayoutData layout = LayoutData::create("LAYOUT_RT_1X1", "RT", 1, 1);
318  layout.setView(0, View::VIEW_REAL_TIME, LayoutRegion(0, 0));
319  this->addDefault(layout);
320  }
321  {
322  LayoutData layout = LayoutData::create("LAYOUT_US_Acquisition", "US Acquisition", 2, 3);
323  layout.setView(0, ptANYPLANE, LayoutRegion(1, 2, 1, 1));
324  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 2, 1, 1));
325  layout.setView(0, View::VIEW_REAL_TIME, LayoutRegion(0, 0, 2, 2));
326  this->addDefault(layout);
327  }
328 }
329 
330 void LayoutRepository::addDefault(LayoutData data)
331 {
332  mDefaultLayouts.push_back(data.getUid());
333  mLayouts.push_back(data);
334 }
335 
336 } // namespace cx
337 
338 
QString qstring_cast(const T &val)
void insert(const LayoutData &data)
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:56
static LayoutData createHeader(QString uid, QString name)
ptAXIAL
a slice seen from the top of the patient
Definition: cxDefinitions.h:56
QString getUid() const
Definition: cxLayoutData.h:108
QDomElement getElement()
return the current element
ptSAGITTAL
a slice seen from the side of the patient
Definition: cxDefinitions.h:56
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.
ptANYPLANE
a plane aligned with the tool base plane
Definition: cxDefinitions.h:56
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.
ptSIDEPLANE
z-rotated 90* relative to anyplane (dual anyplane)
Definition: cxDefinitions.h:56
XmlOptionFile descend(QString element) const
step one level down in the xml tree
QString generateUid() const