]> Creatis software - clitk.git/commitdiff
first developments for PacsConnection
authorcervenansky <frederic.cervenansky@creatis.insa-lyon.fr>
Fri, 28 Jun 2013 08:24:10 +0000 (10:24 +0200)
committercervenansky <frederic.cervenansky@creatis.insa-lyon.fr>
Fri, 28 Jun 2013 08:24:10 +0000 (10:24 +0200)
common/CMakeLists.txt
vv/CMakeLists.txt
vv/icons/basket_download.png [new file with mode: 0644]
vv/icons/bullet_info.png [new file with mode: 0644]
vv/icons/edit.png [new file with mode: 0644]
vv/qt_ui/vvPacsConnection.ui [new file with mode: 0644]
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvQPacsConnection.cxx [new file with mode: 0644]
vv/vvQPacsConnection.h [new file with mode: 0644]

index 95a1023733734e2e18037763c6fa1247a22b8426..ba65d2821b390e3124bb50885193433df3b1bec0 100644 (file)
@@ -66,7 +66,8 @@ ENDIF(CLITK_MEMORY_INFO)
 IF (CLITK_USE_SYSTEM_GDCM)
   FIND_PACKAGE(GDCM REQUIRED)
   include(${GDCM_USE_FILE})
-  TARGET_LINK_LIBRARIES(clitkCommon vtkgdcm gdcmDICT gdcmMSFF)
+  TARGET_LINK_LIBRARIES(clitkCommon vtkgdcm)
+  # gdcmDICT gdcmMSFF)
 ENDIF()
 #=========================================================
 
index 98955708a30d5b09d0ae0f0f96d63776ad2981bd..c901fabf4ce7dcb1bf4cb6c7a06826ba15a76086 100644 (file)
@@ -71,6 +71,7 @@ SET(vv_COMMON_WITH_UI
 SET(vv_SRCS
   vvQProgressDialogITKCommand.cxx
   vvQDicomSeriesSelector.cxx
+  vvQPacsConnection.cxx
   QTreePushButton.cxx
   vvMainWindowBase.cxx
   vvImageWarp.cxx
@@ -113,6 +114,7 @@ QT4_WRAP_CPP(vv_SRCS
   vvDocumentation.h  
   vvHelpDialog.h  
   vvQDicomSeriesSelector.h 
+  vvQPacsConnection.h
   vvSlicerManager.h
   vvStructureSetActor.h
   vvROIActor.h
@@ -123,6 +125,7 @@ QT4_WRAP_UI(vv_UI_CXX
   qt_ui/vvHelpDialog.ui 
   qt_ui/vvDocumentation.ui 
   qt_ui/vvDicomSeriesSelector.ui 
+   qt_ui/vvPacsConnection.ui 
   qt_ui/vvDummyWindow.ui #For testing
   )
 
diff --git a/vv/icons/basket_download.png b/vv/icons/basket_download.png
new file mode 100644 (file)
index 0000000..0038c1c
Binary files /dev/null and b/vv/icons/basket_download.png differ
diff --git a/vv/icons/bullet_info.png b/vv/icons/bullet_info.png
new file mode 100644 (file)
index 0000000..326cf65
Binary files /dev/null and b/vv/icons/bullet_info.png differ
diff --git a/vv/icons/edit.png b/vv/icons/edit.png
new file mode 100644 (file)
index 0000000..c97e3a3
Binary files /dev/null and b/vv/icons/edit.png differ
diff --git a/vv/qt_ui/vvPacsConnection.ui b/vv/qt_ui/vvPacsConnection.ui
new file mode 100644 (file)
index 0000000..086b50a
--- /dev/null
@@ -0,0 +1,759 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>vvPacsConnection</class>
+ <widget class="QWidget" name="vvPacsConnection">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>923</width>
+    <height>783</height>
+   </rect>
+  </property>
+  <property name="font">
+   <font>
+    <family>Calibri</family>
+    <pointsize>9</pointsize>
+    <weight>75</weight>
+    <bold>true</bold>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <widget class="QLabel" name="label_ID">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>10</y>
+     <width>91</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Patient ID</string>
+   </property>
+  </widget>
+  <widget class="QTextEdit" name="text_ID">
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>30</y>
+     <width>101</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="verticalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="horizontalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="readOnly">
+    <bool>false</bool>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="scanButton">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>40</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>SCAN</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="clearButton">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>70</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>CLEAR</string>
+   </property>
+  </widget>
+  <widget class="QTextEdit" name="text_NAME">
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>30</y>
+     <width>101</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="verticalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="horizontalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="readOnly">
+    <bool>false</bool>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_NAME">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>10</y>
+     <width>91</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Patient name</string>
+   </property>
+  </widget>
+  <widget class="QToolButton" name="importButton">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>160</y>
+     <width>51</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string notr="true">...</string>
+   </property>
+   <property name="icon">
+    <iconset>
+     <normaloff>basket_download.png</normaloff>basket_download.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QGroupBox" name="groupBox">
+   <property name="geometry">
+    <rect>
+     <x>70</x>
+     <y>130</y>
+     <width>311</width>
+     <height>271</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>11</pointsize>
+    </font>
+   </property>
+   <property name="title">
+    <string>Patients</string>
+   </property>
+   <widget class="QTreeView" name="patientTreeView">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>20</y>
+      <width>281</width>
+      <height>231</height>
+     </rect>
+    </property>
+    <property name="verticalScrollBarPolicy">
+     <enum>Qt::ScrollBarAlwaysOn</enum>
+    </property>
+    <property name="sortingEnabled">
+     <bool>true</bool>
+    </property>
+    <property name="expandsOnDoubleClick">
+     <bool>false</bool>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="groupBox_2">
+   <property name="geometry">
+    <rect>
+     <x>390</x>
+     <y>130</y>
+     <width>451</width>
+     <height>271</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>11</pointsize>
+    </font>
+   </property>
+   <property name="title">
+    <string>Studies</string>
+   </property>
+  </widget>
+  <widget class="QTreeView" name="studyTreeView">
+   <property name="geometry">
+    <rect>
+     <x>410</x>
+     <y>150</y>
+     <width>411</width>
+     <height>231</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QTreeView" name="seriesTreeView">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>440</y>
+     <width>281</width>
+     <height>311</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QTreeView" name="imagesTreeView">
+   <property name="geometry">
+    <rect>
+     <x>410</x>
+     <y>440</y>
+     <width>411</width>
+     <height>311</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QGroupBox" name="groupBox_3">
+   <property name="geometry">
+    <rect>
+     <x>70</x>
+     <y>420</y>
+     <width>321</width>
+     <height>341</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>11</pointsize>
+    </font>
+   </property>
+   <property name="title">
+    <string>Series</string>
+   </property>
+  </widget>
+  <widget class="QGroupBox" name="groupBox_4">
+   <property name="geometry">
+    <rect>
+     <x>380</x>
+     <y>420</y>
+     <width>451</width>
+     <height>341</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>11</pointsize>
+    </font>
+   </property>
+   <property name="title">
+    <string>Images</string>
+   </property>
+  </widget>
+  <widget class="QTextEdit" name="text_PHYS">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>80</y>
+     <width>101</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="verticalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="horizontalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="readOnly">
+    <bool>false</bool>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_PHYS">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>60</y>
+     <width>91</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Physician Ref.</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_SDESC">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>60</y>
+     <width>91</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Study Description</string>
+   </property>
+  </widget>
+  <widget class="QTextEdit" name="text_SDESC">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>80</y>
+     <width>101</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="verticalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="horizontalScrollBarPolicy">
+    <enum>Qt::ScrollBarAlwaysOff</enum>
+   </property>
+   <property name="readOnly">
+    <bool>false</bool>
+   </property>
+  </widget>
+  <widget class="QTabWidget" name="tabFilter">
+   <property name="geometry">
+    <rect>
+     <x>390</x>
+     <y>0</y>
+     <width>271</width>
+     <height>131</height>
+    </rect>
+   </property>
+   <property name="currentIndex">
+    <number>1</number>
+   </property>
+   <widget class="QWidget" name="modalityTab">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <attribute name="title">
+     <string>Modalities</string>
+    </attribute>
+    <widget class="QWidget" name="layoutWidget">
+     <property name="geometry">
+      <rect>
+       <x>0</x>
+       <y>10</y>
+       <width>264</width>
+       <height>72</height>
+      </rect>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QCheckBox" name="check_MR">
+          <property name="text">
+           <string>MR</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_CR">
+          <property name="text">
+           <string>CR</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_OT">
+          <property name="text">
+           <string>OT</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_RF">
+          <property name="text">
+           <string>RF</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_SC">
+          <property name="text">
+           <string>SC</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_CT">
+          <property name="text">
+           <string>CT</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <item>
+         <widget class="QCheckBox" name="check_US">
+          <property name="text">
+           <string>US</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_NM">
+          <property name="text">
+           <string>NM</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_DR">
+          <property name="text">
+           <string>DR</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_SR">
+          <property name="text">
+           <string>SR</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_XA">
+          <property name="text">
+           <string>XA</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="check_MG">
+          <property name="text">
+           <string>MG</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="check_ModAll">
+        <property name="text">
+         <string>All</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </widget>
+   <widget class="QWidget" name="dateTab">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <attribute name="title">
+     <string>Date</string>
+    </attribute>
+    <widget class="QComboBox" name="comboDate">
+     <property name="geometry">
+      <rect>
+       <x>20</x>
+       <y>20</y>
+       <width>101</width>
+       <height>22</height>
+      </rect>
+     </property>
+     <item>
+      <property name="text">
+       <string>Before</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>After</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Between</string>
+      </property>
+     </item>
+    </widget>
+    <widget class="QDateEdit" name="dateEdit">
+     <property name="geometry">
+      <rect>
+       <x>130</x>
+       <y>20</y>
+       <width>110</width>
+       <height>22</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QDateEdit" name="dateBetweenEdit">
+     <property name="geometry">
+      <rect>
+       <x>130</x>
+       <y>50</y>
+       <width>110</width>
+       <height>22</height>
+      </rect>
+     </property>
+    </widget>
+   </widget>
+  </widget>
+  <widget class="QTabWidget" name="tabNetwork">
+   <property name="geometry">
+    <rect>
+     <x>680</x>
+     <y>0</y>
+     <width>231</width>
+     <height>131</height>
+    </rect>
+   </property>
+   <property name="currentIndex">
+    <number>1</number>
+   </property>
+   <widget class="QWidget" name="networkSelect">
+    <attribute name="title">
+     <string>Network</string>
+    </attribute>
+    <widget class="QCheckBox" name="checkBox">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>10</y>
+       <width>101</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>HCL Neuro</string>
+     </property>
+    </widget>
+    <widget class="QCheckBox" name="checkBox_2">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>40</y>
+       <width>70</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>conquest</string>
+     </property>
+    </widget>
+   </widget>
+   <widget class="QWidget" name="networkConfig">
+    <attribute name="title">
+     <string>Network management</string>
+    </attribute>
+    <widget class="QPushButton" name="NetworkButton">
+     <property name="geometry">
+      <rect>
+       <x>180</x>
+       <y>40</y>
+       <width>41</width>
+       <height>23</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>OK</string>
+     </property>
+    </widget>
+    <widget class="QWidget" name="">
+     <property name="geometry">
+      <rect>
+       <x>0</x>
+       <y>0</y>
+       <width>179</width>
+       <height>100</height>
+      </rect>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_ID_3">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>Name</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="NameEdit"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_ID_2">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>AE Title</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="AETitleEdit"/>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_ID_4">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>Adress</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="AdressEdit"/>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="label_ID_5">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>Port</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QLineEdit" name="PortEdit"/>
+      </item>
+     </layout>
+    </widget>
+   </widget>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>210</y>
+     <width>71</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Import Data</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_help">
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>530</y>
+     <width>51</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Help</string>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignCenter</set>
+   </property>
+  </widget>
+  <widget class="QToolButton" name="helpButton">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>480</y>
+     <width>51</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string notr="true">...</string>
+   </property>
+   <property name="icon">
+    <iconset>
+     <normaloff>bullet_info.png</normaloff>bullet_info.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QToolButton" name="optionsButton">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>400</y>
+     <width>51</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string notr="true">...</string>
+   </property>
+   <property name="icon">
+    <iconset>
+     <normaloff>edit.png</normaloff>edit.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_email_2">
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>450</y>
+     <width>41</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Options</string>
+   </property>
+  </widget>
+ </widget>
+ <resources>
+  <include location="icones.qrc"/>
+ </resources>
+ <connections/>
+</ui>
index 42107987512a3c78686455c9e0f266ebb253b4e3..12d8d27f621bde8102a642c14d635e11b98cb55d 100644 (file)
@@ -235,6 +235,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   documentation = new vvDocumentation();
   help_dialog = new vvHelpDialog();
   dicomSeriesSelector = new vvDicomSeriesSelector();
+  PacsConnection = new vvPacsConnection();
 
   inverseButton->setEnabled(0);
   actionAdd_overlay_image_to_current_image->setEnabled(0);
@@ -744,6 +745,17 @@ void vvMainWindow::OpenDicom()
     files = *(dicomSeriesSelector->GetFilenames());
     LoadImages(files, vvImageReader::DICOM);
   }
+
+  void vvMainWindow::ConnectPacs()
+{
+  std::vector<std::string> files;
+
+  //std::cout << "dicomSeriesSelector " << std::endl;
+  if (PacsConnection->exec() == QDialog::Accepted) {
+    files = *(PacsConnection->GetFilenames());
+    LoadImages(files, vvImageReader::DICOM);
+  }
+
 }
 //------------------------------------------------------------------------------
 
index e5e315509b1924c2392358cc36c6fe80c4e14fa4..eee1d64b807eadea3582532b08c898bf21067710 100644 (file)
@@ -91,6 +91,7 @@ public slots:
   void SliceImages();
   void MergeImagesWithTime();
   void OpenDicom();
+  void PacsConnection();
   ///Open a vtkPolyData surface mesh and display it over the current image
   void OpenVTKContour();
   void SaveAs();
@@ -193,6 +194,7 @@ private:
   vvHelpDialog *help_dialog;
   vvDocumentation *documentation;
   vvDicomSeriesSelector *dicomSeriesSelector;
+  vvPacsConnection *PacsConnection;
 
   bool viewMode;
   bool playMode;
diff --git a/vv/vvQPacsConnection.cxx b/vv/vvQPacsConnection.cxx
new file mode 100644 (file)
index 0000000..0f3f916
--- /dev/null
@@ -0,0 +1,482 @@
+#include "vvQPacsConnection.h"
+#include "gdcmCompositeNetworkFunctions.h"
+#include <QtGui/qlistview.h>
+#include <qfile.h>
+#include <QDate>
+#include <QDateTime>
+
+
+       vvQPacsConnection::vvQPacsConnection(QWidget *i_parent)
+               :QWidget(i_parent)
+       {
+                setupUi(this);
+                setWindowTitle(QString::fromUtf8("DCM API PACS"));
+                createTreeView();
+                tabFilter->setTabText(0,QString(tr("Modality")));
+                tabFilter->setTabText(1,QString(tr("Date")));
+
+                tabNetwork->setTabText(0,QString(tr("Network")));
+                tabNetwork->setTabText(1,QString(tr("Configuration")));
+                check_ModAll->setChecked(true);
+                on_check_ModAll_clicked(true);
+                QIcon icon;
+                icon.addFile("basket_download.png",QSize(),QIcon::Normal,QIcon::Off);
+                importButton->setIcon(icon);
+                icon.addFile("file_upload.png",QSize(),QIcon::Normal,QIcon::Off);
+               // exportButton->setIcon(icon);
+                icon.addFile("email_forward.png",QSize(),QIcon::Normal,QIcon::Off);
+                icon.addFile("edit.png",QSize(),QIcon::Normal,QIcon::Off);
+                optionsButton->setIcon(icon);
+                icon.addFile("bullet_info.png",QSize(),QIcon::Normal,QIcon::Off);
+                helpButton->setIcon(icon);
+                update();
+       }
+
+
+       void vvQPacsConnection::on_clearButton_clicked()
+       {
+               Patientmodel->removeRows(0, Patientmodel->rowCount(),QModelIndex());
+               Studymodel->removeRows(0, Studymodel->rowCount(),QModelIndex());
+               Seriesmodel->removeRows(0, Seriesmodel->rowCount(),QModelIndex());
+               Imagesmodel->removeRows(0, Imagesmodel->rowCount(),QModelIndex());
+       }
+
+       void vvQPacsConnection::on_scanButton_clicked()
+       {
+               //on_clearButton_clicked();
+               manageStudiesFilter(true);
+               #if defined (USE_GDCM2)
+           bool didItWork = gdcm::CompositeNetworkFunctions::CEcho( "127.0.0.1", 5678,
+                       "CREATIS", "CONQUESTSRV1" );
+                               /*  tag.SetElement(8);
+                 tag.SetGroup(8);*/
+               std::vector< std::pair<gdcm::Tag, std::string> > keys = getKeys();
+
+               //std::pair<gdcm::Tag, std::string> pa;
+               //pa.first = tag;
+               //pa.second = "";
+               ////keys.push_back(std::make_pair(tag, ""));
+               gdcm::EQueryLevel theLevel = gdcm::eStudy;
+               gdcm::ERootType theRoot  = gdcm::eStudyRootType;//ePatientRootType;
+               //gdcm::SmartPointer<gdcm::BaseRootQuery> theQuery =  gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,keys);
+
+       
+                   std::vector<gdcm::DataSet> theDataSet;
+
+                         theLevel = gdcm::ePatient;
+  theRoot  = gdcm::ePatientRootType;//ePatientRootType;
+  gdcm::SmartPointer<gdcm::BaseRootQuery> theQuery =  gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,getPatientKeys(""));
+
+//     
+//theDataSet.clear();
+//  gdcm::CompositeNetworkFunctions::CFind("127.0.0.1", 5678, theQuery, theDataSet,
+//       "CREATIS", "CONQUESTSRV1");
+//   keys.clear();
+//   keys.push_back(std::make_pair(gdcm::Tag(0x0010,0x0010), ""));                     
+//                     
+                       gdcm::CompositeNetworkFunctions::CFind("127.0.0.1", 5678, theQuery, theDataSet,
+       "CREATIS", "CONQUESTSRV1");
+  std::vector<gdcm::DataSet>::iterator it_ds = theDataSet.begin();
+//
+  for(; it_ds != theDataSet.end(); it_ds++)
+  {
+
+         QList<QStandardItem *> items;
+         const gdcm::DataSet ds = (*it_ds);
+         std::vector< std::pair<gdcm::Tag, std::string> >::iterator it_key = keys.begin();
+         int ind = 0;
+         for(; it_key != keys.end(); it_key++, ind++)
+         {
+                 gdcm::DataElement de = ds.GetDataElement((*it_key).first);
+                 QStandardItem *item = new QStandardItem;
+                 const gdcm::ByteValue *bv = (de).GetByteValue();
+                 if( !de.IsEmpty() )
+                 {
+                         std::string buffer = std::string( bv->GetPointer(), bv->GetLength() );
+                         item->setText(tr(buffer.c_str()));
+                 }
+                 else
+                 {
+                         item->setText(tr(""));
+                 }
+                 if(ind ==0)
+                 {
+                       item->setCheckable(true);
+                 }
+                 items.push_back(item);
+         }
+         Patientmodel->appendRow(items);
+        }
+//   gdcm::Tag tagtest(0x0020,0x1208);
+//   keys.clear();
+//   keys.push_back(std::make_pair(gdcm::Tag(0x0010,0x0010), ""));
+////  keys.push_back(std::make_pair(tagtest, ""));
+//  theLevel = gdcm::ePatient;
+//  theRoot  = gdcm::ePatientRootType;//ePatientRootType;
+//  theQuery =  gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,keys);
+//
+//     
+//theDataSet.clear();
+//  gdcm::CompositeNetworkFunctions::CFind("127.0.0.1", 5678, theQuery, theDataSet,
+//       "CREATIS", "CONQUESTSRV1");
+#endif
+       }
+
+
+       void vvQPacsConnection::on_importButton_clicked()
+       {
+               QModelIndex index;
+               QVariant elt= Patientmodel->data(index.sibling(patientTreeView->selectionModel()->selectedRows().first().row(),1));
+               
+               gdcm::EQueryLevel theLevel = gdcm::ePatient;
+               gdcm::ERootType theRoot  = gdcm::ePatientRootType;//ePatientRootType;
+               std::vector<gdcm::DataSet> theDataSet;
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               
+               // Study Description
+               gdcm::Tag tagsdc(0x0010,0x0020);
+               keys.push_back(std::make_pair(tagsdc, elt.toString().toStdString()));
+                               gdcm::SmartPointer<gdcm::BaseRootQuery> theQuery =  gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,keys);
+               gdcm::CompositeNetworkFunctions::CFind("127.0.0.1", 5678, theQuery, theDataSet, "CREATIS", "CONQUESTSRV1");
+       
+                bool didItWork =  gdcm::CompositeNetworkFunctions::CMove( "127.0.0.1", 5678, theQuery, 0,
+       "CREATIS", "CONQUESTSRV1", "d:\\temp_pacs_import\\" );
+       }
+
+       void vvQPacsConnection::convertDataSet(std::vector<gdcm::DataSet> i_ds, QStandardItemModel *i_model, std::vector< std::pair<gdcm::Tag, std::string> > keys)
+       {
+               gdcm::Tag tagdb(0x0008,0x0020);
+               std::vector<gdcm::DataSet>::iterator it_ds = i_ds.begin();
+               for(; it_ds != i_ds.end(); it_ds++)
+               {
+                       QList<QStandardItem *> items;
+                       const gdcm::DataSet ds = (*it_ds);
+                       std::vector< std::pair<gdcm::Tag, std::string> >::iterator it_key = keys.begin();
+                   int ind = 0;
+                   for(; it_key != keys.end(); it_key++, ind++)
+                   {
+                           gdcm::DataElement de = ds.GetDataElement((*it_key).first);
+                           QStandardItem *item = new QStandardItem;
+                           const gdcm::ByteValue *bv = (de).GetByteValue();
+                           if( !de.IsEmpty() )
+                           {
+                                   std::string buffer = std::string( bv->GetPointer(), bv->GetLength() );
+                                       /*if((*it_key).first == tagdb)
+                                       {
+                                               QDate date;
+                                               date.fromString(tr(buffer.c_str()),"yyyy'MM'd");
+                                               item->setText(date.toString());
+                                       }
+                                       else
+                                       {*/
+                                               item->setText(tr(buffer.c_str()));
+                                       //}
+                           }
+                           else
+                           {
+                                   item->setText(tr(""));
+                           }
+                           if(ind ==0)
+                           {
+                                  item->setCheckable(true);
+                           }
+                           items.push_back(item);
+                   }
+                       i_model->appendRow(items);
+               }
+               
+       }
+
+
+       void vvQPacsConnection::createTreeView()
+       {
+               // Patient Tree View
+               Patientmodel = new QStandardItemModel(0,2,this); 
+               QStringList Patientlist;
+               Patientlist.push_back(tr("PATIENT NAME"));
+               Patientlist.push_back(tr("PATIENT ID"));
+               Patientmodel->setHorizontalHeaderLabels(Patientlist);
+               patientTreeView->setModel(Patientmodel);
+               patientTreeView->setEnabled(true);
+               connect(patientTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectStudies(QModelIndex)));
+               
+               // Study Tree View
+               Studymodel = new QStandardItemModel(0,3,this); 
+               QStringList Studylist;
+               Studylist.push_back(tr("DESCRIPTION"));
+               Studylist.push_back(tr("DATE"));
+               Studylist.push_back(tr("HOUR"));
+               Studymodel->setHorizontalHeaderLabels(Studylist);
+               studyTreeView->setModel(Studymodel);
+               connect(studyTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectSeries(QModelIndex)));
+
+
+               // Series Tree View
+               Seriesmodel = new QStandardItemModel(0,2,this); 
+               QStringList Serieslist;
+               Serieslist.push_back(tr("MODALITY"));
+               Serieslist.push_back(tr("DESCRIPTION"));
+               Serieslist.push_back(tr("no. accept."));
+               Seriesmodel->setHorizontalHeaderLabels(Serieslist);
+               seriesTreeView->setModel(Seriesmodel);
+               connect(seriesTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectImages(QModelIndex)));
+
+               // Images Tree View
+               Imagesmodel = new QStandardItemModel(0,1,this); 
+               QStringList Imageslist;
+               Imageslist.push_back(tr("instance number"));
+               Imagesmodel->setHorizontalHeaderLabels(Imageslist);
+               imagesTreeView->setModel(Imagesmodel);
+
+               //model->setHeaderData(0, Qt::Horizontal,tr("test"),Qt::DisplayRole);
+               /*QFileSystemModel *filemodel = new   QFileSystemModel;
+               filemodel->insertColumn(1);
+               filemodel->setHeaderData(1, Qt::Horizontal,"test",0);*/
+
+       }
+
+       void vvQPacsConnection::selectStudies(const QModelIndex &index)
+       {
+               Studymodel->removeRows(0, Studymodel->rowCount(),QModelIndex());
+               QVariant elt= Patientmodel->data(index.sibling(index.row(),1));
+               m_patient=elt.toString().toStdString();
+               manageSeriesFilter(true);
+               gdcm::EQueryLevel theLevel = gdcm::eStudy;
+               gdcm::ERootType theRoot  = gdcm::ePatientRootType;//ePatientRootType;
+               std::vector<gdcm::DataSet> theDataSet;
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               
+               // Study Description
+               gdcm::Tag tagsd(0x0010,0x0020);
+               keys.push_back(std::make_pair(tagsd, m_patient));
+               // Study Description
+               gdcm::Tag tagsdc(0x0008,0x1030);
+               keys.push_back(std::make_pair(tagsdc, ""));
+               // Study date
+               gdcm::Tag tagdb(0x0008,0x0020);
+               keys.push_back(std::make_pair(tagdb, ""));
+               // Study Hour
+               gdcm::Tag tagsdh(0x0008,0x0030);
+               keys.push_back(std::make_pair(tagsdh, ""));
+               gdcm::SmartPointer<gdcm::BaseRootQuery> theQuery =  gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,keys);
+               gdcm::CompositeNetworkFunctions::CFind("127.0.0.1", 5678, theQuery, theDataSet, "CREATIS", "CONQUESTSRV1");
+               convertDataSet(theDataSet, Studymodel, getStudyKeys(""));
+       }
+
+
+       void vvQPacsConnection::selectSeries(const QModelIndex &index)
+       {
+               Seriesmodel->removeRows(0, Seriesmodel->rowCount(),QModelIndex());
+               QVariant elt= Studymodel->data(index.sibling(index.row(),3));
+               QVariant elt2= Patientmodel->data(index.sibling(patientTreeView->selectionModel()->selectedRows().first().row(),1));
+
+               //manageImagesFilter(true);
+               gdcm::EQueryLevel theLevel = gdcm::eSeries;
+               gdcm::ERootType theRoot  = gdcm::ePatientRootType;//ePatientRootType;
+               std::vector<gdcm::DataSet> theDataSet;
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               
+               //Patient Unique key
+               keys.push_back(std::make_pair(gdcm::Tag(0x0010,0x0020), m_patient));
+
+               //Study Unique Key
+               keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000d), elt.toString().toStdString()));
+
+               
+               // Modality
+               keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x0060), elt.toString().toStdString()));
+               // Description
+               keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x0060), elt.toString().toStdString()));
+               // Acceptance NUmber????
+               keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000e), elt.toString().toStdString()));
+               
+               gdcm::SmartPointer<gdcm::BaseRootQuery> theQuery =  gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,keys);
+               keys.clear();
+               // Modality
+               keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x0060), elt.toString().toStdString()));
+               // Description
+               keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x0060), elt.toString().toStdString()));
+               // Acceptance NUmber????
+               keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000e), elt.toString().toStdString()));
+
+
+
+               gdcm::CompositeNetworkFunctions::CFind("127.0.0.1", 5678, theQuery, theDataSet, "CREATIS", "CONQUESTSRV1");
+               convertDataSet(theDataSet, Seriesmodel, keys);
+       }
+
+       void vvQPacsConnection::selectImages(const QModelIndex &index)
+       {
+               Imagesmodel->removeRows(0, Imagesmodel->rowCount(),QModelIndex());
+               QVariant elt= Seriesmodel->data(index.sibling(index.row(),2));
+               QVariant elt2= Patientmodel->data(index.sibling(patientTreeView->selectionModel()->selectedRows().first().row(),1));
+
+               //manageImagesFilter(true);
+               gdcm::EQueryLevel theLevel = gdcm::eImageOrFrame;
+               gdcm::ERootType theRoot  = gdcm::ePatientRootType;//ePatientRootType;
+               std::vector<gdcm::DataSet> theDataSet;
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               
+               gdcm::Tag tagsd(0x0010,0x0020);
+               keys.push_back(std::make_pair(tagsd, m_patient));
+
+               gdcm::Tag tagss(0x0020,0x000e);
+               keys.push_back(std::make_pair(tagss, elt.toString().toStdString()));
+               //= getStudyKeys(elt.toString().toStdString());
+               
+               // Study Description
+               gdcm::Tag tagsdc(0x0020,0x0013);
+               keys.push_back(std::make_pair(tagsdc, ""));
+               
+
+               gdcm::SmartPointer<gdcm::BaseRootQuery> theQuery =  gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,keys);
+               keys.clear();
+               // Study Description
+
+               keys.push_back(std::make_pair(tagsdc, ""));
+               
+
+               gdcm::CompositeNetworkFunctions::CFind("127.0.0.1", 5678, theQuery, theDataSet, "CREATIS", "CONQUESTSRV1");
+               convertDataSet(theDataSet, Seriesmodel, keys);
+       }
+
+
+       void vvQPacsConnection::manageStudiesFilter(bool i_enable)
+       {
+               text_PHYS->setEnabled(i_enable);
+               text_SDESC->setEnabled(i_enable);
+               dateTab->setEnabled(i_enable);
+
+       }
+
+       void vvQPacsConnection::manageSeriesFilter(bool i_enable)
+       {
+               modalityTab->setEnabled(i_enable);
+       }
+
+       std::vector< std::pair<gdcm::Tag, std::string> > vvQPacsConnection::getPatientKeys(const std::string i_val)
+       {
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               // Patient Name
+                gdcm::Tag tag(0x0010,0x0010);
+               keys.push_back(std::make_pair(tag, ""));
+
+               //// Patient ID
+               gdcm::Tag tagpid(0x0010,0x0020);
+               keys.push_back(std::make_pair(tagpid, i_val));
+               return keys;
+       }
+
+       std::vector< std::pair<gdcm::Tag, std::string> > vvQPacsConnection::getStudyKeys(const std::string i_val)
+       {
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               // Study Description
+               gdcm::Tag tagsdc(0x0008,0x1030);
+               keys.push_back(std::make_pair(tagsdc, ""));
+               // Study date
+               gdcm::Tag tagdb(0x0008,0x0020);
+               keys.push_back(std::make_pair(tagdb, ""));
+               // Study Hour
+               gdcm::Tag tagsdh(0x0008,0x0030);
+               keys.push_back(std::make_pair(tagsdh, ""));
+               // Study Instance UID
+               gdcm::Tag tagsid(0x0020,0x000d);
+               keys.push_back(std::make_pair(tagsid, i_val));
+
+               return keys;
+       }
+
+
+       std::vector< std::pair<gdcm::Tag, std::string> > vvQPacsConnection::getSeriesKeys(const std::string i_val)
+       {
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               // Modality
+               gdcm::Tag tagsm(0x0008,0x0060);
+               keys.push_back(std::make_pair(tagsm, ""));
+               // Study date
+               gdcm::Tag tagdb(0x0008,0x103e);
+               keys.push_back(std::make_pair(tagdb, ""));
+               // Study Hour
+               gdcm::Tag tagsdh(0x0020,0x000e);
+               keys.push_back(std::make_pair(tagsdh, ""));
+               // Study Instance UID
+               gdcm::Tag tagsid(0x0020,0x1209);
+               keys.push_back(std::make_pair(tagsid, i_val));
+
+               return keys;
+       }
+       std::vector< std::pair<gdcm::Tag, std::string> > vvQPacsConnection::getKeys()
+       {
+               std::vector< std::pair<gdcm::Tag, std::string> > keys;
+               // Patient Name
+                gdcm::Tag tag(0x0010,0x0010);
+               keys.push_back(std::make_pair(tag, ""));
+
+               //// Patient ID
+               gdcm::Tag tagpid(0x0010,0x0020);
+               keys.push_back(std::make_pair(tagpid, ""));
+
+               // Modality
+               gdcm::Tag tagmod(0x0008,0x0061);
+               keys.push_back(std::make_pair(tagmod, ""));
+
+               // date of birth
+               gdcm::Tag tagdb(0x0010,0x0030);
+               keys.push_back(std::make_pair(tagdb, ""));
+
+               // Study Date
+               gdcm::Tag tagsd(0x0020,0x000D);
+               keys.push_back(std::make_pair(tagsd, ""));
+
+               //// Study Time
+               //gdcm::Tag tagst(8,30);
+               //keys.push_back(std::make_pair(tagst, ""));
+
+               //// Study Description
+               //gdcm::Tag tagsdc(8,1030);
+               //keys.push_back(std::make_pair(tagsdc, ""));
+
+               //// Accession n°
+               //gdcm::Tag tagacc(8,50);
+               //keys.push_back(std::make_pair(tagacc, ""));
+
+               return keys;
+       }
+
+       void vvQPacsConnection::on_check_ModAll_clicked(bool state)
+       {
+               check_MR->setEnabled(!state);
+               check_CR->setEnabled(!state);
+               check_OT->setEnabled(!state);
+               check_RF->setEnabled(!state);
+               check_SC->setEnabled(!state);
+               check_CT->setEnabled(!state);
+               check_US->setEnabled(!state);
+               check_NM->setEnabled(!state);
+               check_DR->setEnabled(!state);
+               check_US->setEnabled(!state);
+               check_NM->setEnabled(!state);
+               check_DR->setEnabled(!state);
+               check_SR->setEnabled(!state);
+               check_XA->setEnabled(!state);
+               check_MG->setEnabled(!state);
+               if(state)
+               {
+                       check_MR->setChecked(state);
+                       check_CR->setChecked(state);
+                       check_OT->setChecked(state);
+                       check_RF->setChecked(state);
+                       check_SC->setChecked(state);
+                       check_CT->setChecked(state);
+                       check_US->setChecked(state);
+                       check_NM->setChecked(state);
+                       check_DR->setChecked(state);
+                       check_US->setChecked(state);
+                       check_NM->setChecked(state);
+                       check_DR->setChecked(state);
+                       check_SR->setChecked(state);
+                       check_XA->setChecked(state);
+                       check_MG->setChecked(state);
+               }
+
+       }
\ No newline at end of file
diff --git a/vv/vvQPacsConnection.h b/vv/vvQPacsConnection.h
new file mode 100644 (file)
index 0000000..fbbdbeb
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef __vvQPacsConnection_h_INCLUDED__
+#define __vvQPacsConnection_h_INCLUDED__
+
+#include <QTGUI/QWidget>
+#include "ui_vvPacsConnection.h"
+#include "gdcmCompositeNetworkFunctions.h"
+#include <QtGui/QStandardItemModel.h>
+#include <QtGui/QStringListModel.h>
+
+
+  /**
+   * \ingroup GUI
+   */
+  //=====================================================================
+ //=====================================================================
+  class vvQPacsConnection : public QWidget , public Ui_vvPacsConnection
+  {
+         Q_OBJECT
+  public:
+         vvQPacsConnection(){}    
+         vvQPacsConnection(QWidget *parent);
+    
+         ~vvQPacsConnection(){}
+       ///Queries the PACS
+        //void OnQueryPACS(wxCommandEvent& event);  
+public slots:
+       void selectStudies(const QModelIndex &index);
+       void selectSeries(const QModelIndex &index);
+       void selectImages(const QModelIndex &index);
+  private slots:
+    void on_scanButton_clicked();
+       void on_clearButton_clicked();
+       void on_importButton_clicked();
+       void on_check_ModAll_clicked(bool state);
+
+
+  private :
+       std::vector< std::pair<gdcm::Tag, std::string> > getKeys();
+       std::vector< std::pair<gdcm::Tag, std::string> > getPatientKeys(const std::string );
+       std::vector< std::pair<gdcm::Tag, std::string> > getStudyKeys(const std::string);
+       std::vector< std::pair<gdcm::Tag, std::string> > getSeriesKeys(const std::string i_val);
+       std::vector< std::pair<gdcm::Tag, std::string> > getImageKeys(const std::string i_val);
+       void manageStudiesFilter(bool i_enable);
+       void createTreeView();
+       QStandardItemModel *Patientmodel;
+       QStandardItemModel *Studymodel;
+       QStandardItemModel *Seriesmodel;
+       QStandardItemModel *Imagesmodel;
+       void convertDataSet(std::vector<gdcm::DataSet> i_ds, QStandardItemModel *i_model, std::vector< std::pair<gdcm::Tag, std::string> > keys);
+       void manageSeriesFilter(bool i_enable);
+       std::string m_patient;
+       std::string m_study;
+       std::string m_series;
+       
+       std::string m_ip;
+       std::string m_aetitle;
+       std::string m_adress;
+       std::string m_name;
+       //wxDialog* dialog;
+       
+  }; // class vvQPacsConnection
+  //=====================================================================
+
+  
+
+#endif // __vvQPacsConnection_h_INCLUDED__
+
+