Fraxinus  16.5.0-fx-rc9
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 #include "cxLogger.h"
37 
38 namespace cx
39 {
40 
42 {
43  this->addDefaults();
44 }
45 
46 LayoutData LayoutRepository::get(const QString uid) const
47 {
48  unsigned pos = this->indexOf(uid);
49  if (pos != mLayouts.size())
50  return mLayouts[pos];
51  if(!uid.isEmpty())
52  CX_LOG_WARNING() << "Layout don't exist: " << uid;
53  return LayoutData();
54 }
55 
56 bool LayoutRepository::exists(const QString uid) const
57 {
58  unsigned pos = this->indexOf(uid);
59  if (pos != mLayouts.size())
60  return true;
61  else
62  return false;
63 }
64 
65 std::vector<QString> LayoutRepository::getAvailable() const
66 {
67  std::vector<QString> retval;
68  for (unsigned i = 0; i < mLayouts.size(); ++i)
69  {
70  retval.push_back(mLayouts[i].getUid());
71  }
72  return retval;
73 }
74 
76 {
77  unsigned pos = this->indexOf(data.getUid());
78  if (pos == mLayouts.size())
79  mLayouts.push_back(data);
80  else
81  mLayouts[pos] = data;
82  emit layoutChanged(data.getUid());
83 }
84 
86 {
87  int count = 0;
88 
89  for (LayoutDataVector::const_iterator iter = mLayouts.begin(); iter != mLayouts.end(); ++iter)
90  {
91  if (iter->getUid() == qstring_cast(count))
92  count = iter->getUid().toInt() + 1;
93  }
94  return qstring_cast(count);
95 }
96 
97 void LayoutRepository::erase(const QString uid)
98 {
99  mLayouts.erase(mLayouts.begin() + indexOf(uid));
100  emit layoutChanged(uid);
101 }
102 
103 unsigned LayoutRepository::indexOf(const QString uid) const
104 {
105  for (unsigned i = 0; i < mLayouts.size(); ++i)
106  {
107  if (mLayouts[i].getUid() == uid)
108  return i;
109  }
110  return mLayouts.size();
111 }
112 
113 bool LayoutRepository::isCustom(const QString& uid) const
114 {
115  bool isLayout = false;
116  for (unsigned i = 0; i < mLayouts.size(); ++i)
117  {
118  if (uid == mLayouts[i].getUid())
119  {
120  isLayout = true;
121  break;
122  }
123  }
124 
125  bool isDefaultLayout = std::count(mDefaultLayouts.begin(), mDefaultLayouts.end(), uid);
126 
127  bool retval = false;
128  if (isLayout && !isDefaultLayout)
129  retval = true;
130 
131  return retval;
132 }
133 
135 {
136  // load custom layouts:
137  mLayouts.clear();
138 
139  this->blockSignals(true);
140 
141  QDomElement layouts = file.getElement("layouts");
142  QDomNode layout = layouts.firstChild();
143  for (; !layout.isNull(); layout = layout.nextSibling())
144  {
145  if (layout.toElement().tagName() != "layout")
146  continue;
147 
148  LayoutData data;
149  data.parseXml(layout);
150 
151  this->insert(data);
152  }
153 
154  std::vector<QString> custom = this->getAvailable();
155  this->addDefaults(); // ensure we overwrite loaded layouts
156 
157  this->blockSignals(false);
158 
159  for (unsigned i=0; i<custom.size(); ++i)
160  emit layoutChanged(custom[i]);
161 }
162 
164 {
165  XmlOptionFile layoutsNode = file.descend("layouts");
166  layoutsNode.removeChildren();
167  for (LayoutDataVector::iterator iter = mLayouts.begin(); iter != mLayouts.end(); ++iter)
168  {
169  if (!this->isCustom(iter->getUid()))
170  continue; // dont store default layouts - they are created automatically.
171 
172  QDomElement layoutNode = file.getDocument().createElement("layout");
173  layoutsNode.getElement().appendChild(layoutNode);
174  iter->addXml(layoutNode);
175  }
176 }
177 
181 void LayoutRepository::addDefaults()
182 {
183  mDefaultLayouts.clear();
184 
185  /*
186  *
187  3D______________
188 
189  3D
190  3D AD
191  3D ACS
192 
193  Oblique ________
194 
195  3D AnyDual x1
196  3D AnyDual x2
197  AnyDual x3
198 
199  Orthogonal______
200 
201  3D ACS x1
202  3D ACS x2
203  ACS x3
204 
205  RT______________
206 
207  RT
208  Us Acq
209  */
210 
211  // ------------------------------------------------------
212  // --- group of 3D-based layouts ------------------------
213  // ------------------------------------------------------
214  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_3D", "3D"));
215  {
216  // 3D only
217  LayoutData layout = LayoutData::create("LAYOUT_3D", "3D", 1, 1);
218  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
219  this->addDefault(layout);
220  }
221  {
222  // 3D ACS
223  LayoutData layout = LayoutData::create("LAYOUT_3D_ACS", "3D ACS", 3, 4);
224  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
225  layout.setView(1, ptAXIAL, LayoutRegion(0, 3));
226  layout.setView(1, ptCORONAL, LayoutRegion(1, 3));
227  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 3));
228  this->addDefault(layout);
229  }
230  {
231  // A 3DCS
232  LayoutData layout = LayoutData::create("LAYOUT_A_3DCS", "A 3DCS", 3, 4);
233  layout.setView(1, ptAXIAL, LayoutRegion(0, 0, 3, 3));
234  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 3));
235  layout.setView(1, ptCORONAL, LayoutRegion(1, 3));
236  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 3));
237  this->addDefault(layout);
238  }
239  {
240  // 3D 3DAC
241  LayoutData layout = LayoutData::create("LAYOUT_3D_3DAC", "3D 3DAC", 3, 5);
242  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
243  layout.setView(1, View::VIEW_3D, LayoutRegion(0, 3, 1, 2));
244  layout.setView(2, ptAXIAL, LayoutRegion(1, 3, 1, 2));
245  layout.setView(2, ptCORONAL, LayoutRegion(2, 3, 1, 2));
246  this->addDefault(layout);
247  }
248  {
249  // 3D Any
250  LayoutData layout = LayoutData::create("LAYOUT_3D_AD", "3D AnyDual", 2, 4);
251  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 3));
252  layout.setView(1, ptANYPLANE, LayoutRegion(0, 3));
253  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 3));
254  this->addDefault(layout);
255  }
256  {
257  // 3D ACS in a single view group
258  LayoutData layout = LayoutData::create("LAYOUT_3D_ACS_SINGLE", "3D ACS Connected", 3, 4);
259  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 3));
260  layout.setView(0, ptAXIAL, LayoutRegion(0, 3));
261  layout.setView(0, ptCORONAL, LayoutRegion(1, 3));
262  layout.setView(0, ptSAGITTAL, LayoutRegion(2, 3));
263  this->addDefault(layout);
264  }
265  {
266  // 3D Any in a single view group
267  LayoutData layout = LayoutData::create("LAYOUT_3D_AD_SINGLE", "3D AnyDual Connected", 2, 4);
268  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 3));
269  layout.setView(0, ptANYPLANE, LayoutRegion(0, 3));
270  layout.setView(0, ptSIDEPLANE, LayoutRegion(1, 3));
271  this->addDefault(layout);
272  }
273 
274  // ------------------------------------------------------
275  // --- group of oblique (Anyplane-based) layouts --------
276  // ------------------------------------------------------
277  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_Oblique", "Oblique"));
278  {
279  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_3DAnyDual_x1", "3D Any Dual x1", 1, 3);
280  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
281  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
282  layout.setView(1, ptSIDEPLANE, LayoutRegion(0, 2));
283  this->addDefault(layout);
284  }
285  {
286  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_3DAnyDual_x2", "3D Any Dual x2", 2, 3);
287  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 2, 1));
288  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
289  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 1));
290  layout.setView(2, ptANYPLANE, LayoutRegion(0, 2));
291  layout.setView(2, ptSIDEPLANE, LayoutRegion(1, 2));
292  this->addDefault(layout);
293  }
294  {
295  LayoutData layout = LayoutData::create("LAYOUT_OBLIQUE_AnyDual_x3", "Any Dual x3", 2, 3);
296  layout.setView(0, ptANYPLANE, LayoutRegion(0, 0));
297  layout.setView(0, ptSIDEPLANE, LayoutRegion(1, 0));
298  layout.setView(1, ptANYPLANE, LayoutRegion(0, 1));
299  layout.setView(1, ptSIDEPLANE, LayoutRegion(1, 1));
300  layout.setView(2, ptANYPLANE, LayoutRegion(0, 2));
301  layout.setView(2, ptSIDEPLANE, LayoutRegion(1, 2));
302  this->addDefault(layout);
303  }
304 
305  // ------------------------------------------------------
306  // --- group of orthogonal (ACS-based) layouts ----------
307  // ------------------------------------------------------
308  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_Orthogonal", "Orthogonal"));
309  {
310  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x1", "3D ACS x1", 2, 2);
311  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0));
312  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
313  layout.setView(1, ptCORONAL, LayoutRegion(1, 0));
314  layout.setView(1, ptSAGITTAL, LayoutRegion(1, 1));
315  this->addDefault(layout);
316  }
317  {
318  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x2", "3D ACS x2", 3, 3);
319  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 0, 3, 1));
320  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
321  layout.setView(1, ptCORONAL, LayoutRegion(1, 1));
322  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 1));
323  layout.setView(2, ptAXIAL, LayoutRegion(0, 2));
324  layout.setView(2, ptCORONAL, LayoutRegion(1, 2));
325  layout.setView(2, ptSAGITTAL, LayoutRegion(2, 2));
326  this->addDefault(layout);
327  }
328  {
329  LayoutData layout = LayoutData::create("LAYOUT_ORTHOGONAL_3DACS_x3", "ACS x3", 3, 3);
330  layout.setView(0, ptAXIAL, LayoutRegion(0, 0));
331  layout.setView(0, ptCORONAL, LayoutRegion(1, 0));
332  layout.setView(0, ptSAGITTAL, LayoutRegion(2, 0));
333  layout.setView(1, ptAXIAL, LayoutRegion(0, 1));
334  layout.setView(1, ptCORONAL, LayoutRegion(1, 1));
335  layout.setView(1, ptSAGITTAL, LayoutRegion(2, 1));
336  layout.setView(2, ptAXIAL, LayoutRegion(0, 2));
337  layout.setView(2, ptCORONAL, LayoutRegion(1, 2));
338  layout.setView(2, ptSAGITTAL, LayoutRegion(2, 2));
339  this->addDefault(layout);
340  }
341 
342  // ------------------------------------------------------
343  // --- group of RTsource-based layouts - single viewgroup
344  // ------------------------------------------------------
345  this->addDefault(LayoutData::createHeader("LAYOUT_GROUP_RT", "Realtime Source"));
346  {
347  LayoutData layout = LayoutData::create("LAYOUT_RT_1X1", "RT", 1, 1);
348  layout.setView(0, View::VIEW_REAL_TIME, LayoutRegion(0, 0));
349  this->addDefault(layout);
350  }
351  {
352  LayoutData layout = LayoutData::create("LAYOUT_US_Acquisition", "US Acquisition", 2, 3);
353  layout.setView(0, ptANYPLANE, LayoutRegion(1, 2, 1, 1));
354  layout.setView(0, View::VIEW_3D, LayoutRegion(0, 2, 1, 1));
355  layout.setView(0, View::VIEW_REAL_TIME, LayoutRegion(0, 0, 2, 2));
356  this->addDefault(layout);
357  }
358 }
359 
361 {
362  mDefaultLayouts.push_back(data.getUid());
363  mLayouts.push_back(data);
364 }
365 
366 } // namespace cx
367 
368 
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)
bool exists(const QString uid) const
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.
#define CX_LOG_WARNING
Definition: cxLogger.h:113
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.
void addDefault(LayoutData 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