]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Merge from V6_main_20120808 08Aug12
authorvsr <vsr@opencascade.com>
Thu, 9 Aug 2012 06:41:59 +0000 (06:41 +0000)
committervsr <vsr@opencascade.com>
Thu, 9 Aug 2012 06:41:59 +0000 (06:41 +0000)
119 files changed:
doc/salome/tui/input/index.doc [new file with mode: 0644]
src/GUI_PY/Makefile.am [new file with mode: 0644]
src/GUI_PY/SelectVarsDialog.ui [new file with mode: 0644]
src/GUI_PY/__init__.py [new file with mode: 0644]
src/GUI_PY/genericdialog.py [new file with mode: 0644]
src/GUI_PY/genericdialog.ui [new file with mode: 0644]
src/GUI_PY/helper.py [new file with mode: 0644]
src/GUI_PY/mytestdialog.py [new file with mode: 0644]
src/GUI_PY/mytestdialog.ui [new file with mode: 0644]
src/GUI_PY/selectvars.py [new file with mode: 0644]
src/GuiHelpers/Makefile.am [new file with mode: 0644]
src/GuiHelpers/QtHelper.hxx [new file with mode: 0644]
src/GuiHelpers/SALOME_AppStudyEditor.cxx [new file with mode: 0644]
src/GuiHelpers/SALOME_AppStudyEditor.hxx [new file with mode: 0644]
src/GuiHelpers/SALOME_GuiServices.cxx [new file with mode: 0644]
src/GuiHelpers/SALOME_GuiServices.hxx [new file with mode: 0644]
src/GuiHelpers/StandardApp_Module.cxx [new file with mode: 0644]
src/GuiHelpers/StandardApp_Module.hxx [new file with mode: 0644]
src/LightApp/images/en.png [new file with mode: 0644]
src/LightApp/images/fr.png [new file with mode: 0644]
src/OpenGLUtils/Makefile.am [new file with mode: 0755]
src/OpenGLUtils/OpenGLUtils.h [new file with mode: 0755]
src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx [new file with mode: 0755]
src/OpenGLUtils/OpenGLUtils_FrameBuffer.h [new file with mode: 0755]
src/Qtx/resources/Qtx_msg_fr.ts [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/Makefile.am [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_GUILight.h [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_GUILight.sip [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyInterp.cxx [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyInterp.h [new file with mode: 0644]
src/SalomeApp/pluginsdemo/Makefile.am [new file with mode: 0644]
src/SalomeApp/pluginsdemo/minmax.ui [new file with mode: 0644]
src/SalomeApp/pluginsdemo/minmax_dialog.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/minmax_plugin.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/salome_plugins.py [new file with mode: 0755]
src/SalomeApp/pluginsdemo/smesh_plugins.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/trihedron.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/tubebuilder.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/tubedialog.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/tubedialog_ui.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/xalome.py [new file with mode: 0644]
src/TreeData/DataModel.cxx [new file with mode: 0644]
src/TreeData/DataModel.hxx [new file with mode: 0644]
src/TreeData/DataObject.cxx [new file with mode: 0644]
src/TreeData/DataObject.hxx [new file with mode: 0644]
src/TreeData/DataProcessor.cxx [new file with mode: 0644]
src/TreeData/DataProcessor.hxx [new file with mode: 0644]
src/TreeData/DockWidgets.cxx [new file with mode: 0644]
src/TreeData/DockWidgets.hxx [new file with mode: 0644]
src/TreeData/Makefile.am [new file with mode: 0644]
src/TreeData/Test/Makefile.am [new file with mode: 0644]
src/TreeData/Test/MyDataModel.cxx [new file with mode: 0644]
src/TreeData/Test/MyDataModel.hxx [new file with mode: 0644]
src/TreeData/Test/data.txt [new file with mode: 0755]
src/TreeData/Test/guitester.cxx [new file with mode: 0644]
src/TreeData/Test/mainwindow.cxx [new file with mode: 0644]
src/TreeData/Test/mainwindow.hxx [new file with mode: 0644]
src/TreeData/Test/mainwindow.ui [new file with mode: 0644]
src/TreeData/Test/tester.cxx [new file with mode: 0644]
src/TreeData/Test/testhelper.cxx [new file with mode: 0644]
src/TreeData/Test/testhelper.hxx [new file with mode: 0644]
src/TreeData/TreeData.hxx [new file with mode: 0755]
src/TreeData/TreeGuiManager.cxx [new file with mode: 0644]
src/TreeData/TreeGuiManager.hxx [new file with mode: 0644]
src/TreeData/TreeItem.cxx [new file with mode: 0644]
src/TreeData/TreeItem.hxx [new file with mode: 0644]
src/TreeData/TreeModel.cxx [new file with mode: 0644]
src/TreeData/TreeModel.hxx [new file with mode: 0644]
src/TreeData/TreeObserver.cxx [new file with mode: 0644]
src/TreeData/TreeObserver.hxx [new file with mode: 0644]
src/TreeData/TreeView.cxx [new file with mode: 0644]
src/TreeData/TreeView.hxx [new file with mode: 0644]
src/VTKViewer/textures/texture1.dat [new file with mode: 0644]
src/VTKViewer/textures/texture2.dat [new file with mode: 0644]
src/VTKViewer/textures/texture3.dat [new file with mode: 0644]
src/VTKViewer/textures/texture4.dat [new file with mode: 0644]
src/VTKViewer/textures/texture5.dat [new file with mode: 0644]
src/VTKViewer/textures/texture6.dat [new file with mode: 0644]
src/VTKViewer/textures/texture7.dat [new file with mode: 0644]
src/VTKViewer/textures/texture8.dat [new file with mode: 0644]
src/VTKViewer/textures/texture9.dat [new file with mode: 0644]
src/ViewerTools/Makefile.am [new file with mode: 0755]
src/ViewerTools/ViewerTools.h [new file with mode: 0644]
src/ViewerTools/ViewerTools_CubeAxesDlgBase.cxx [new file with mode: 0644]
src/ViewerTools/ViewerTools_CubeAxesDlgBase.h [new file with mode: 0644]
src/ViewerTools/ViewerTools_DialogBase.cxx [new file with mode: 0644]
src/ViewerTools/ViewerTools_DialogBase.h [new file with mode: 0644]
src/ViewerTools/ViewerTools_FontWidgetBase.cxx [new file with mode: 0644]
src/ViewerTools/ViewerTools_FontWidgetBase.h [new file with mode: 0644]
src/ViewerTools/resources/ViewerTools_msg_en.ts [new file with mode: 0644]
src/ViewerTools/resources/ViewerTools_msg_fr.ts [new file with mode: 0755]
tools/Makefile.am [new file with mode: 0644]
tools/dlgfactory/GenericDialog.cxx [new file with mode: 0644]
tools/dlgfactory/GenericDialog.hxx [new file with mode: 0644]
tools/dlgfactory/GenericDialog.ui [new file with mode: 0644]
tools/dlgfactory/Makefile.am [new file with mode: 0644]
tools/dlgfactory/README.txt [new file with mode: 0644]
tools/dlgfactory/__GDIALOG__.cxx [new file with mode: 0644]
tools/dlgfactory/__GDIALOG__.hxx [new file with mode: 0644]
tools/dlgfactory/__GDIALOG__.ui [new file with mode: 0644]
tools/dlgfactory/__QDIALOG__.cxx [new file with mode: 0644]
tools/dlgfactory/__QDIALOG__.hxx [new file with mode: 0644]
tools/dlgfactory/__QDIALOG__.ui [new file with mode: 0644]
tools/dlgfactory/dlgfactory.py [new file with mode: 0755]
tools/dlgfactory/dlgfactory.sh [new file with mode: 0755]
tools/dlgfactory/gtester.cxx [new file with mode: 0644]
tools/dlgfactory/qtester.cxx [new file with mode: 0644]
tools/vtkEDFOverloads/Makefile.am [new file with mode: 0755]
tools/vtkEDFOverloads/vtkEDFCutter.cxx [new file with mode: 0755]
tools/vtkEDFOverloads/vtkEDFCutter.h [new file with mode: 0755]
tools/vtkEDFOverloads/vtkEDFFactory.cxx [new file with mode: 0755]
tools/vtkEDFOverloads/vtkEDFFactory.h [new file with mode: 0755]
tools/vtkEDFOverloads/vtkEDFOverloadsDefines.h [new file with mode: 0755]

diff --git a/doc/salome/tui/input/index.doc b/doc/salome/tui/input/index.doc
new file mode 100644 (file)
index 0000000..678dda8
--- /dev/null
@@ -0,0 +1,12 @@
+/*! \mainpage
+
+\image html guiscreen.png
+
+To browse the \b SALOME GUI module Developer Documentation, follow the links below or use navigation menu at the top of the page:
+<ul>
+<li> <a href="namespaces.html">Packages</a> - list of GUI module packages and scripts.</li>
+<li> <a href="annotated.html">Data Structures</a> - list of all data structures and classes with brief descriptions.</li>
+<li> <a href="files.html">Files</a> - list of all files with brief descriptions.</li>
+</ul>
+
+*/
\ No newline at end of file
diff --git a/src/GUI_PY/Makefile.am b/src/GUI_PY/Makefile.am
new file mode 100644 (file)
index 0000000..782e15a
--- /dev/null
@@ -0,0 +1,55 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+mypkgpythondir = $(salomepythondir)/salome/gui
+
+# Python modules to be installed
+mypkgpython_PYTHON = \
+       __init__.py            \
+       selectvars.py          \
+       genericdialog.py       \
+       mytestdialog.py        \
+       helper.py
+
+PYUIC_FILES = \
+       SelectVarsDialog_ui.py \
+       genericdialog_ui.py    \
+       mytestdialog_ui.py
+
+nodist_mypkgpython_PYTHON = $(PYUIC_FILES)
+CLEANFILES = $(PYUIC_FILES)
+
+EXTRA_DIST += \
+       SelectVarsDialog.ui \
+       genericdialog.ui    \
+       mytestdialog.ui
+
+# This rule indicates that some python files are generated from ui
+# files using the PYUIC utility. The convention is to create a file
+# name <basename>_ui.py when the ui file name is <basename>.ui. When
+# implementing the dialog, you generally create a third file named
+# <basename>.py that uses the UI_<basename> classe defined in the
+# generated file <basename>_ui.py.
+%_ui.py:%.ui
+       $(PYUIC) -x $< -o $@
diff --git a/src/GUI_PY/SelectVarsDialog.ui b/src/GUI_PY/SelectVarsDialog.ui
new file mode 100644 (file)
index 0000000..3dd9334
--- /dev/null
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SelectVarsDialog</class>
+ <widget class="QDialog" name="SelectVarsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>611</width>
+    <height>743</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Select Variables of Interest</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Potential Variables List</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="QLabel" name="label_6">
+       <property name="text">
+        <string>Selected Variables List</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="2">
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <spacer name="horizontalSpacer_6">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="loadVarsButton">
+         <property name="text">
+          <string>Import...</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="saveVarsButton">
+         <property name="text">
+          <string>Export...</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_5">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label_4">
+       <property name="text">
+        <string>All Input Variables</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="2">
+      <widget class="QLabel" name="label_5">
+       <property name="text">
+        <string>Selected Input Variables</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QListWidget" name="allInputVarListWidget">
+       <property name="selectionMode">
+        <enum>QAbstractItemView::MultiSelection</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <layout class="QVBoxLayout" name="verticalLayout_6">
+       <item>
+        <spacer name="verticalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="addInputVarButton">
+         <property name="text">
+          <string>Add</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="removeInputVarButton">
+         <property name="text">
+          <string>Remove</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="newInputVarButton">
+         <property name="text">
+          <string>New...</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item row="3" column="2">
+      <widget class="QListWidget" name="selectedInputVarListWidget">
+       <property name="selectionMode">
+        <enum>QAbstractItemView::MultiSelection</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>All Output Variables</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="2">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Selected Output Variables</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="0">
+      <widget class="QListWidget" name="allOutputVarListWidget">
+       <property name="selectionMode">
+        <enum>QAbstractItemView::MultiSelection</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="1">
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <spacer name="verticalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="addOutputVarButton">
+         <property name="text">
+          <string>Add</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="removeOutputVarButton">
+         <property name="text">
+          <string>Remove</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="newOutputVarButton">
+         <property name="text">
+          <string>New...</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item row="5" column="2">
+      <widget class="QListWidget" name="selectedOutputVarListWidget">
+       <property name="selectionMode">
+        <enum>QAbstractItemView::MultiSelection</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <layout class="QHBoxLayout" name="horizontalLayout_5">
+       <item>
+        <spacer name="horizontalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="varListObjLineEdit">
+         <property name="readOnly">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="selectButton">
+         <property name="text">
+          <string>Select</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="OKButton">
+       <property name="text">
+        <string>OK</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="cancelButton">
+       <property name="text">
+        <string>Cancel</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/GUI_PY/__init__.py b/src/GUI_PY/__init__.py
new file mode 100644 (file)
index 0000000..24ceaf5
--- /dev/null
@@ -0,0 +1,21 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
diff --git a/src/GUI_PY/genericdialog.py b/src/GUI_PY/genericdialog.py
new file mode 100644 (file)
index 0000000..6d13c92
--- /dev/null
@@ -0,0 +1,129 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+__author__="gboulant"
+__date__ ="$31 mars 2010 17:09:53$"
+
+from PyQt4.QtGui import QDialog, QMessageBox
+
+from genericdialog_ui import Ui_GenericDialog
+
+class GenericDialog(QDialog):
+    """
+    This is an abstract generic dialog box for implementing default and
+    generic behaviour of dialog windows.
+    Note that this class can be instantiated but can't be used because the
+    OK behaviour is a default one indicating that the checkData function should
+    be implemented in a derived class. The general interface that should be
+    implemented in derived class is the MVC pattern:
+
+    - setData(<a_data_model_object>):
+      to initiate the values of the dialog windows from a given data model.
+
+    - boolean checkData():
+      to verify that the data are valid and notify user if not.
+
+    - <a_data_model_object> getData():
+      to get the valid data model from values read in the dialog window.
+    """
+
+    __wasOk = False
+    checkDataMessage = ""
+
+    def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+        QDialog.__init__(self,parent)
+        # Set up the user interface from Designer.
+        self.__ui = Ui_GenericDialog()
+        self.__ui.setupUi(self)
+
+    def getPanel(self):
+        '''
+        This returns the central panel where to draw the custom dialog
+        widgets.
+        '''
+        return self.__ui.myCenterPanel
+
+    def getButtonBox(self):
+        return self.__ui.buttonBox
+
+    def accept(self):
+        """
+        Slot function connected to the button OK
+        """
+        if not self.checkData():
+            QMessageBox.warning( self, "Alerte", self.checkDataMessage)
+            return
+        self.__wasOk = True
+        self.hide()
+
+    def displayAndWait(self):
+        """
+        This function can be used to display the dialog in the case
+        where the dialog is modal and does not need interactivity with
+        parent windows and other part of the application. When called,
+        the dialog is raised visible and keep waiting until the button
+        OK or the button CANCEL is pressed. Then the flow can go on
+        (see an example of implementation in the tests functions at
+        the end of this file).
+        In the general case, in particular if you need interaction
+        with the graphical framework (clic on widgets embedded in
+        other dialogs), you should used instead the show() command
+        (for a non modal dialog) or the open() command (for a window
+        modal dialog, i.e. a dialog that can not interact with its
+        direct parent but can interact with the other parts).
+        """
+        self.__wasOk = False
+        self.exec_()
+
+    def wasOk(self):
+        """
+        Return True if the button OK was pressed to close the dialog windows.
+        """
+        return self.__wasOk
+
+    def checkData(self):
+        """
+        This function should be implemented in a derived class. It should return
+        True in the case where the data are estimated to be valid data.
+        """
+        self.checkDataMessage = "The checkData() function is not implemented yet"
+        return True
+
+#
+# ==============================================================================
+# Basic use cases and unit test functions
+# ==============================================================================
+#
+def TEST_GenericDialog():
+    import sys
+    from PyQt4.QtGui import QApplication
+    from PyQt4.QtCore import QObject, SIGNAL, SLOT
+    app = QApplication(sys.argv)
+    QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+    dlg=GenericDialog()
+    dlg.displayAndWait()
+    if dlg.wasOk():
+        print "OK has been pressed"
+    else:
+        print "Cancel has been pressed"
+        
+if __name__ == "__main__":
+    TEST_GenericDialog()
diff --git a/src/GUI_PY/genericdialog.ui b/src/GUI_PY/genericdialog.ui
new file mode 100644 (file)
index 0000000..3b151e5
--- /dev/null
@@ -0,0 +1,89 @@
+<ui version="4.0" >
+ <class>GenericDialog</class>
+ <widget class="QDialog" name="GenericDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>498</width>
+    <height>352</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <layout class="QHBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <layout class="QVBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <widget class="QFrame" name="myCenterPanel" >
+       <property name="frameShape" >
+        <enum>QFrame::NoFrame</enum>
+       </property>
+       <property name="frameShadow" >
+        <enum>QFrame::Raised</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox" >
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons" >
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>GenericDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>GenericDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/GUI_PY/helper.py b/src/GUI_PY/helper.py
new file mode 100644 (file)
index 0000000..f294c0b
--- /dev/null
@@ -0,0 +1,150 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Author: Guillaume Boulant (EDF/R&D)
+
+# ==================================================================
+# This file provides helper functions to drive some gui features of a
+# SALOME Application (the selection in the object browser for now,
+# further development coming soon). Note that some of these helper
+# functions are specialized for a GEOM or SMESH context (see the
+# guihelper.py modules comming with the packages salome.geom and
+# salome.smesh.
+# ==================================================================
+
+#
+# ==================================================================
+# Definition of usefull objects and functions to deal with the SALOME
+# technical context.
+# ==================================================================
+#
+
+from salome.kernel import services
+
+#
+# Get SALOME PyQt interface to manipulate the GUI context
+# (Get the active study for example. Note that the active study is a
+# GUI concept only: it is the study that is currently active in the
+# desktop)
+#
+import SalomePyQt
+sgPyQt=SalomePyQt.SalomePyQt()
+
+#
+# Get SALOME Swig interface to manipulate the GUI widget
+#
+import libSALOME_Swig
+SalomeGUI = libSALOME_Swig.SALOMEGUI_Swig()
+
+#
+# ==================================================================
+# General helper function for GUI programming actions
+# ==================================================================
+# 
+# Get the active study
+#
+def getActiveStudy():
+    """
+    This returns a study object that corresponds to the active
+    study. The active study is a GUI concept: it's the study currently
+    active on the desktop.
+    """
+    studyId = sgPyQt.getStudyId()
+    study = services.getStudyManager().GetStudyByID( studyId )
+    return study
+
+#
+# ==================================================================
+# Functions to manipulate the objects in the browser (generic)
+# ==================================================================
+#
+def getSObjectSelected():
+    '''
+    Returns the sobject and the entry of the item currently selected
+    in the objects browser. Returns "None, None" if no item is
+    selected. If several objects are selected, it returns the first
+    one of the list.
+    '''
+    sobj = None
+    entry = None
+    study = getActiveStudy()
+    if SalomeGUI.SelectedCount() == 1:
+        # We only considere the first element of the list. If you need
+        # something else, create another function in your own context.
+        entry = SalomeGUI.getSelected( 0 )
+        if entry != '':
+            sobj = study.FindObjectID( entry )
+    return sobj, entry
+
+def showSObjectSelected():
+    '''
+    This function print the attributes of the selected object.
+    (this function is  only for test purpose)
+    '''
+    sobj, entry = getSObjectSelected()
+    if ( sobj ):
+        test, attr = sobj.FindAttribute( "AttributeName" )
+        if test:
+            message = "My name is '%s'" % attr.Value()
+            print message
+    pass
+
+def deleteSObjectSelected(): 
+    '''
+    This function deletes the selected object.
+    '''
+    sobj, entry = getSObjectSelected()
+    if ( sobj ):
+        study = getActiveStudy()
+        builder = study.NewBuilder()
+        builder.RemoveObject( sobj )
+        SalomeGUI.updateObjBrowser(True)
+    pass
+
+#
+# ==================================================================
+# Use cases and demo functions
+# ==================================================================
+#
+
+# CAUTION: Before running this test functions, you first have to
+# create (or import) an object and select this object in the objects
+# browser.
+
+#
+# Definitions:
+# - the SObject is an item in the active study (Study Object).
+# - the entry is the identifier of an item.
+# - the object (geom object or smesh object) is a CORBA servant
+#   embedded in the SALOME component container and with a reference in
+#   the SALOME study, so that it can be retrieved.
+#
+
+def TEST_getSObjectSelected():
+    mySObject, myEntry = getSObjectSelected()
+    myName = mySObject.GetName()
+    print "The name of the selected object is %s"%myName
+
+def TEST_showSObjectSelected():
+    showSObjectSelected()
+
+if __name__ == "__main__":
+    TEST_getSObjectSelected()
+    TEST_showSObjectSelected()
diff --git a/src/GUI_PY/mytestdialog.py b/src/GUI_PY/mytestdialog.py
new file mode 100644 (file)
index 0000000..82898c5
--- /dev/null
@@ -0,0 +1,152 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+__author__="gboulant"
+__date__ ="$31 mars 2010 17:09:53$"
+
+from mytestdialog_ui import Ui_MyTestDialog
+from genericdialog import GenericDialog
+
+class MyTestDialog(GenericDialog):
+    """
+    This class is to illustrate the usage of the GenericDialog to implement
+    the dialog windows of the application with a common design template provided
+    by the generic class GenericDialog.
+    """
+    def __init__(self, parent=None, name="MyTestDialog"):
+        GenericDialog.__init__(self, parent, name)
+        # Set up the user interface from Designer.
+        self.ui = Ui_MyTestDialog()
+        # BE CAREFULL HERE, the ui form is NOT put in the global dialog (already
+        # containing some generic widgets) but in the center panel created in the
+        # GenericDialog as a void container for the form. The MyTestDialog form
+        # is supposed here to create only the widgets to be placed in the center
+        # panel
+        self.ui.setupUi(self.getPanel())
+
+    #
+    # We implement here the interface of the MVC pattern
+    #
+    def setData(self, name):
+        """
+        This function implements the mapping from the data model to the widgets
+        """
+        self.ui.txtName.setText(name)
+
+    def checkData(self):
+        """
+        This function implements the control to be done on the values contained
+        in the widgets when trying to validate the dialog window (click OK first
+        trigs this function).
+        """
+        if ( self.ui.txtName.text().trimmed() == "" ):
+            self.checkDataMessage = "The name can't be void"
+            return False
+        return True
+
+    def getData(self):
+        """
+        This function implements the mapping from the widgets to the data model
+        """
+        name = str(self.ui.txtName.text().trimmed().toUtf8())
+        # _MEM_: note here that (i) the utf8 format is used and (ii) we must not
+        # forget to convert to a standard python string (instead of a QString).
+        return name
+
+
+from PyQt4.QtCore import SIGNAL
+class MyTestDialogWithSignals(MyTestDialog):
+    """
+    This class is to illustrate the usage of the GenericDialog in the
+    case where the dialog windows is not modal. In such a case, the
+    controller must be warn of close events using Qt signals.
+    """
+    def __init__(self, parent=None, name="MyTestDialogWithSignals"):
+        MyTestDialog.__init__(self, parent, name)
+
+    def accept(self):
+        """
+        This function is the slot connected to the the OK button
+        (click event of the OK button). 
+        """
+        # The dialog is raised in a non modal mode (for example, to
+        # get interactivity with the parents windows. Then we have to
+        # emit a signal to warn the parent observer that the dialog
+        # has been validated so that it can process the event
+        MyTestDialog.accept(self)
+        if self.wasOk():
+            self.emit(SIGNAL('inputValidated()'))
+
+
+
+#
+# ==============================================================================
+# Basic use case
+# ==============================================================================
+#
+
+def TEST_MyTestDialog_modal():
+    import sys
+    from PyQt4.QtCore import QObject, SIGNAL, SLOT
+    from PyQt4.QtGui import QApplication
+    app = QApplication(sys.argv)
+    QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+    dlg=MyTestDialog()
+    dlg.setData("A default name")
+    dlg.displayAndWait()
+    if dlg.wasOk():
+        name = dlg.getData()
+        print "The name has been modified to",name
+
+
+class DialogListener:
+    def onProcessEvent(self):
+        print "onProcessEvent(): OK has been pressed"
+        import sys
+        sys.exit(0)
+        
+
+def TEST_MyTestDialog_non_modal():
+    import sys
+    from PyQt4.QtCore import QObject, SIGNAL, SLOT
+    from PyQt4.QtGui import QApplication
+    app = QApplication(sys.argv)
+    QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+    dlg=MyTestDialogWithSignals()
+    # This dialog window will emit a inputValidated() signal when the
+    # OK button is pressed and the data are validated. Then, we
+    # connect this signal to a local slot so that the event can be
+    # processed.
+    dlgListener = DialogListener()
+    app.connect(dlg, SIGNAL('inputValidated()'), dlgListener.onProcessEvent)
+    # This connect instruction means that the signal inputValidated()
+    # emited by the dlg Qt object will raise a call to the slot
+    # dlgListener.onProcessEvent
+
+    dlg.setData("A default name")
+    dlg.show()
+
+    app.exec_()
+
+if __name__ == "__main__":
+    #TEST_MyTestDialog_modal()
+    TEST_MyTestDialog_non_modal()
diff --git a/src/GUI_PY/mytestdialog.ui b/src/GUI_PY/mytestdialog.ui
new file mode 100644 (file)
index 0000000..ca89393
--- /dev/null
@@ -0,0 +1,69 @@
+<ui version="4.0" >
+ <class>MyTestDialog</class>
+ <widget class="QDialog" name="MyTestDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <layout class="QHBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <layout class="QVBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <layout class="QHBoxLayout" >
+       <property name="margin" >
+        <number>0</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item>
+        <widget class="QLabel" name="lblName" >
+         <property name="text" >
+          <string>TextLabel</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="txtName" />
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/GUI_PY/selectvars.py b/src/GUI_PY/selectvars.py
new file mode 100644 (file)
index 0000000..40456c6
--- /dev/null
@@ -0,0 +1,153 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import os
+from PyQt4 import QtGui, QtCore
+from PyQt4.QtCore import Qt
+
+import salome
+from salome.kernel.studyedit import getStudyEditor
+from salome.kernel.parametric import study_exchange_vars
+
+# ---------------------------------- #
+# Dialog box for variables selection #
+# ---------------------------------- #
+
+from SelectVarsDialog_ui import Ui_SelectVarsDialog
+
+class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog):
+
+    def __init__(self, parent = None, modal = 0):
+        QtGui.QDialog.__init__(self, parent)
+        Ui_SelectVarsDialog.__init__(self)
+        self.setupUi(self)
+        self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self.close)
+        self.connect(self.OKButton, QtCore.SIGNAL("clicked()"), self.accept)
+        self.connect(self.selectButton, QtCore.SIGNAL("clicked()"), self.initPotentialVariablesFromSelection)
+        self.connect(self.addInputVarButton, QtCore.SIGNAL("clicked()"), self.addSelectedInputVar)
+        self.connect(self.removeInputVarButton, QtCore.SIGNAL("clicked()"), self.removeSelectedInputVar)
+        self.connect(self.newInputVarButton, QtCore.SIGNAL("clicked()"), self.newInputVar)
+        self.connect(self.addOutputVarButton, QtCore.SIGNAL("clicked()"), self.addSelectedOutputVar)
+        self.connect(self.removeOutputVarButton, QtCore.SIGNAL("clicked()"), self.removeSelectedOutputVar)
+        self.connect(self.newOutputVarButton, QtCore.SIGNAL("clicked()"), self.newOutputVar)
+        self.connect(self.loadVarsButton, QtCore.SIGNAL("clicked()"), self.loadVars)
+        self.connect(self.saveVarsButton, QtCore.SIGNAL("clicked()"), self.saveVars)
+        self.refEntry = None
+
+    def setExchangeVariables(self, exchangeVariables):
+        if exchangeVariables.refEntry is not None:
+            self._initPotentialVariables(exchangeVariables.refEntry)
+        self.selectedInputVarListWidget.addItems([x.name for x in exchangeVariables.inputVarList])
+        self.selectedOutputVarListWidget.addItems([x.name for x in exchangeVariables.outputVarList])
+
+    def initPotentialVariablesFromSelection(self):
+        entries = salome.sg.getAllSelected()
+        if len(entries) != 1 :
+            QtGui.QMessageBox.warning(self, self.tr("Error"),
+                                      self.tr("One item must be selected in the object browser"))
+            return
+        selectedEntry = entries[0]
+        self._initPotentialVariables(selectedEntry)
+
+    def _initPotentialVariables(self, entry):
+        sobj = getStudyEditor().study.FindObjectID(entry)
+        if sobj is None:
+            QtGui.QMessageBox.warning(self, self.tr("Error"),
+                                      self.tr('No item at entry %s' % entry))
+            return
+        exchangeVariables = study_exchange_vars.getExchangeVariablesFromSObject(sobj)
+        if exchangeVariables is None:
+            QtGui.QMessageBox.warning(self, self.tr("Error"),
+                                      self.tr('Item at entry %s is not a valid '
+                                              '"Variable List" object' % entry))
+            return
+        self.refEntry = entry
+        self.varListObjLineEdit.setText(sobj.GetName())
+        self.allInputVarListWidget.clear()
+        self.allOutputVarListWidget.clear()
+        self.allInputVarListWidget.addItems([x.name for x in exchangeVariables.inputVarList])
+        self.allOutputVarListWidget.addItems([x.name for x in exchangeVariables.outputVarList])
+
+    def addSelectedInputVar(self):
+        for item in self.allInputVarListWidget.selectedItems():
+            self.selectedInputVarListWidget.addItem(QtGui.QListWidgetItem(item))
+
+    def removeSelectedInputVar(self):
+        for item in self.selectedInputVarListWidget.selectedItems():
+            self.selectedInputVarListWidget.takeItem(self.selectedInputVarListWidget.row(item))
+
+    def newInputVar(self):
+        newItem = QtGui.QListWidgetItem("TO EDIT!")
+        newItem.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsUserCheckable|Qt.ItemIsEnabled)
+        self.selectedInputVarListWidget.addItem(newItem);
+
+    def addSelectedOutputVar(self):
+        for item in self.allOutputVarListWidget.selectedItems():
+            self.selectedOutputVarListWidget.addItem(QtGui.QListWidgetItem(item))
+
+    def removeSelectedOutputVar(self):
+        for item in self.selectedOutputVarListWidget.selectedItems():
+            self.selectedOutputVarListWidget.takeItem(self.selectedOutputVarListWidget.row(item))
+
+    def newOutputVar(self):
+        newItem = QtGui.QListWidgetItem("TO EDIT!")
+        newItem.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsUserCheckable|Qt.ItemIsEnabled)
+        self.selectedOutputVarListWidget.addItem(newItem);
+
+    def getSelectedExchangeVariables(self):
+        inputVarList = []
+        outputVarList = []
+        for row in range(self.selectedInputVarListWidget.count()):
+            name = str(self.selectedInputVarListWidget.item(row).text())
+            inputVarList.append(study_exchange_vars.Variable(name))
+        for row in range(self.selectedOutputVarListWidget.count()):
+            name = str(self.selectedOutputVarListWidget.item(row).text())
+            outputVarList.append(study_exchange_vars.Variable(name))
+        return study_exchange_vars.ExchangeVariables(inputVarList, outputVarList, self.refEntry)
+
+    def loadVars(self):
+        filename = QtGui.QFileDialog.getOpenFileName(self, self.tr("Import variables from file"),
+                                                     os.getenv("HOME"),
+                                                     self.tr("XML Files (*.xml)"))
+        if not filename:
+            return
+        try:
+            filename = str(filename)
+            exchange_variables = study_exchange_vars.loadExchangeVariablesFromXmlFile(filename)
+            self.setExchangeVariables(exchange_variables)
+        except Exception, e:
+            QtGui.QMessageBox.critical(self, self.tr("Error"),
+                                       self.tr("Cannot load file %s:\n%s" % (filename, e)))
+
+    def saveVars(self):
+        default = os.path.join(os.getenv("HOME"), "vars.xml")
+        filename = QtGui.QFileDialog.getSaveFileName(self, self.tr("Export variables to file"),
+                                                     default, self.tr("XML Files (*.xml)"))
+        if not filename:
+            return
+        try:
+            filename = str(filename)
+            exchange_variables = self.getSelectedExchangeVariables()
+            exchange_variables.saveToXmlFile(filename)
+        except Exception, e:
+            QtGui.QMessageBox.critical(self, self.tr("Error"),
+                                       self.tr("Cannot save file %s:\n%s" % (filename, e)))
diff --git a/src/GuiHelpers/Makefile.am b/src/GuiHelpers/Makefile.am
new file mode 100644 (file)
index 0000000..dc45c3c
--- /dev/null
@@ -0,0 +1,82 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF/R&D) 
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# header files 
+salomeinclude_HEADERS =        \
+       QtHelper.hxx           \
+       SALOME_GuiServices.hxx       \
+       SALOME_AppStudyEditor.hxx     \
+       StandardApp_Module.hxx
+
+# Libraries targets
+lib_LTLIBRARIES = libSalomeGuiHelpers.la
+
+dist_libSalomeGuiHelpers_la_SOURCES = \
+       SALOME_GuiServices.cxx         \
+       SALOME_AppStudyEditor.cxx       \
+       StandardApp_Module.cxx
+
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+CAS_CXXFLAGS=@CAS_CPPFLAGS@ @CAS_CXXFLAGS@
+BOOST_CPPFLAGS=@BOOST_CPPFLAGS@
+BOOST_LIBS=@BOOST_LIBS@
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+
+libSalomeGuiHelpers_la_CPPFLAGS =   \
+       $(QT_CXXFLAGS)              \
+       $(CAS_CXXFLAGS)             \
+       $(BOOST_CPPFLAGS)           \
+       $(CORBA_CXXFLAGS)           \
+       $(KERNEL_CXXFLAGS)          \
+       -I$(srcdir)/../SalomeApp    \
+       -I$(srcdir)/../LightApp     \
+       -I$(srcdir)/../SUIT         \
+       -I$(srcdir)/../Qtx          \
+       -I$(srcdir)/../CAM          \
+       -I$(srcdir)/../STD          \
+       -I$(srcdir)/../OBJECT
+
+
+libSalomeGuiHelpers_la_LDFLAGS  = \
+       ../SalomeApp/libSalomeApp.la \
+       $(KERNEL_LDFLAGS) -lSalomeKernelHelpers \
+       $(CORBA_LIBS)
+
+#
+# =======================================================
+# Specific definitions for Qt MOC files
+#
+
+# moc-files generation
+%_moc.cxx: %.hxx
+       $(MOC) $< -o $@
+
+# MOC pre-processing
+MOC_FILES_HXX = \
+       StandardApp_Module_moc.cxx
+
+nodist_libSalomeGuiHelpers_la_SOURCES = $(MOC_FILES_HXX)
+
+EXTRA_DIST+=$(MOC_FILES_HXX:%_moc.cxx=%.hxx)
diff --git a/src/GuiHelpers/QtHelper.hxx b/src/GuiHelpers/QtHelper.hxx
new file mode 100644 (file)
index 0000000..de40c7a
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _QT_HELPER_HXX_
+#define _QT_HELPER_HXX_
+
+//
+// =============================================================
+// Macro and template functions for type conversions.
+// =============================================================
+//
+#include "Basics_Utils.hxx" // To get ToString macro
+#include <QString>
+
+// This can be used to convert QString into char *.
+#define QCHARSTAR(qstring) qstring.toLatin1().data()
+// This converts a string into a QString
+#define S2QS(string) QString(string.c_str())
+// This converts a QString into a string
+#define QS2S(qstring) ToString(QCHARSTAR(qstring))
+#define QSTRING(any) S2QS(ToString(any))
+
+//
+// =============================================================
+// General helper macros for manipulating widgets values
+// =============================================================
+//
+#define GETTEXT(widget) ToString(QCHARSTAR(widget->text().trimmed()))
+#define SETTEXT(widget,str) widget->setText(str.c_str())
+
+//
+// =============================================================
+// Qt Logger macros
+// =============================================================
+//
+
+// We can use the macros defined by SALOMELocalTrace/utilities.h
+// as proposed in the file KERNEL_helper.hxx. But we can use instead
+// the Qt debug function:
+#include <QDebug>
+#define QDEBUG qWarning()
+//#define QDEBUG qDebug()
+#define QLOG(data) QDEBUG << "[XSALOME] " << data
+#ifdef LOG
+#undef LOG
+#endif
+#define LOG QLOG
+
+#endif // __QT_HELPER_H_
diff --git a/src/GuiHelpers/SALOME_AppStudyEditor.cxx b/src/GuiHelpers/SALOME_AppStudyEditor.cxx
new file mode 100644 (file)
index 0000000..f2e9bb4
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "SALOME_AppStudyEditor.hxx"
+
+#include <SalomeApp_Study.h>
+#include <SALOME_ListIO.hxx>
+#include <LightApp_SelectionMgr.h>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+SALOME_AppStudyEditor::SALOME_AppStudyEditor(SalomeApp_Application * salomeApp)
+  : SALOME_StudyEditor()
+{
+  _salomeApp = salomeApp;
+  updateActiveStudy();
+}
+
+/**
+ * This updates the editor with the current active study. If the
+ * active study id is identical to the study id currently associated
+ * to this object, then no update is performed.
+ */
+int SALOME_AppStudyEditor::updateActiveStudy() {
+  int activeStudyId = SALOME_AppStudyEditor::getActiveStudyId(_salomeApp);
+  if ( activeStudyId != this->getStudyId() ) {
+    this->setStudyById(activeStudyId);
+  }
+  return activeStudyId;
+}
+
+// GUI context only
+int SALOME_AppStudyEditor::getActiveStudyId(SalomeApp_Application * salomeApp) {
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*> (salomeApp->activeStudy());
+  _PTR(Study) aCStudy = appStudy->studyDS();
+  int studyId = aCStudy->StudyId();
+  return studyId;
+}
+
+SALOMEDS::SObject_ptr SALOME_AppStudyEditor::IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject) {
+  if (!iobject.IsNull()) {
+    if (iobject->hasEntry()) {
+      SALOMEDS::SObject_var sobject = _study->FindObjectID(iobject->getEntry());
+      return sobject._retn();
+    }
+  }
+  return SALOMEDS::SObject::_nil();
+}
+
+/**
+ * This function creates a list of all the "study objects" (SObject)
+ * that map with the selection in the object browser (the "interactive
+ * objects", IObjects). Please note that the objects belongs to the
+ * active study.
+ */
+SALOME_StudyEditor::SObjectList * SALOME_AppStudyEditor::getSelectedObjects() {
+
+  // _GBO_: please note that the use of this function can be
+  // underoptimal in the case where the number of selected objects is
+  // high, because we create a vector list of SObjects while the list
+  // of IObject can be processed directly. In the case where a high
+  // number of objects is selected (~1000), it's certainly better to
+  // use directly the SALOME_ListIO and iterators on it.
+
+  LightApp_SelectionMgr* aSelectionMgr = _salomeApp->selectionMgr();
+  SALOME_ListIO selectedIObjects;
+  aSelectionMgr->selectedObjects(selectedIObjects);
+  /* 
+   * This returns a list containing the selected objects of the objects
+   * browser. Please note that the objects of the browser ARE NOT the
+   * objects of the study. What is returned by this function is a list
+   * of "interactive objects" (IObject) which are objects of the
+   * graphical context. Each of this IObject is characterized by an
+   * entry string that corresponds to the entry string of an associated
+   * "study object" (SObject) in the active study. The mapping can be
+   * done using the function IObjectToSObject.
+   */
+
+  SObjectList * listOfSObject = new SObjectList();
+  SALOME_ListIteratorOfListIO It (selectedIObjects);
+  for (; It.More(); It.Next()) {
+    SALOMEDS::SObject_ptr sobject = this->IObjectToSObject(It.Value());
+    if (!sobject->_is_nil()) {
+      listOfSObject->push_back(sobject);
+    }
+  }
+
+  return listOfSObject;
+}
diff --git a/src/GuiHelpers/SALOME_AppStudyEditor.hxx b/src/GuiHelpers/SALOME_AppStudyEditor.hxx
new file mode 100644 (file)
index 0000000..5eb0c0e
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef __APP_STUDY_EDITOR_HXX__
+#define __APP_STUDY_EDITOR_HXX__
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include <SalomeApp_Application.h>
+#include <SALOME_InteractiveObject.hxx>
+
+#include "SALOME_StudyEditor.hxx"
+
+class SALOME_AppStudyEditor: public SALOME_StudyEditor {
+public:
+  SALOME_AppStudyEditor(SalomeApp_Application * salomeApp);
+  int updateActiveStudy();
+  
+  SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject);
+  SALOME_StudyEditor::SObjectList * getSelectedObjects();
+
+  static int getActiveStudyId(SalomeApp_Application * salomeApp);
+
+private:
+  SalomeApp_Application * _salomeApp;
+
+};
+
+#endif // __APP_STUDY_EDITOR_HXX__
diff --git a/src/GuiHelpers/SALOME_GuiServices.cxx b/src/GuiHelpers/SALOME_GuiServices.cxx
new file mode 100644 (file)
index 0000000..fcb5b98
--- /dev/null
@@ -0,0 +1,134 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "SALOME_GuiServices.hxx"
+#include <SUIT_Session.h>
+
+namespace GUI {
+  /*!
+   * Get the SALOME application, i.e. the main GUI framework of
+   * SALOME. This function returns a pointer to the singleton instance
+   * of the SalomeApp_Application.
+   * 
+   * The SALOME application can be used to get reference to
+   * the SALOME KERNEL services such that the naming service, the
+   * lifeCycleCORBA, ... Theses services can be retrieved using static
+   * functions (not required to get the singleton instance):
+   *
+   *   SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
+   *
+   * Please note that this usage can be done only from within the
+   * SALOME session server process, i.e. the process that embed the
+   * SALOME application.
+   */
+  SalomeApp_Application * getSalomeApplication() {
+    static SalomeApp_Application * app;
+    if ( app == NULL ) {
+      app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+    }
+    return app;
+  }
+
+  /*!
+   * Get the selection manager of the SALOME application. The
+   * selection manager can be used to get the selected items in the
+   * objects browser that is a GUI display of the active study.
+   * The function returns a pointer to the selectionMgr attribute of
+   * the SalomeApp_Application singleton instance.
+   */
+  LightApp_SelectionMgr * getSelectionManager() {
+    SalomeApp_Application* anApp = GUI::getSalomeApplication();
+    if ( anApp == NULL ) return NULL;
+    return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
+  }
+
+
+  SUIT_ResourceMgr * getResourcesManager() {
+    return SUIT_Session::session()->resourceMgr();
+  }
+  // Note that the resource manager can be also retrieved from the
+  // SALOME application using the resourceMgr() method:
+  // 
+
+  /**
+   * This returns the current active study id if an active study is
+   * defined in the SALOME session, returns -1 otherwise. Note that
+   * the active study doesn't make sense outside of the GUI SALOME
+   * process, i.e. the SALOME_SessionServer embedding the
+   * SalomeApp_Application.
+   */
+  int getActiveStudyId() {
+    SALOME::Session_var aSession = KERNEL::getSalomeSession();
+    if ( CORBA::is_nil(aSession) ) {
+      INFOS("ERR: can't request for active study because the session is NULL");
+      return -1;
+    }
+    return aSession->GetActiveStudyId();
+  }
+
+  /**
+   * This returns the current active study if an active study is
+   * defined in the SALOME session, returns null otherwise.
+   */
+  SALOMEDS::Study_ptr getActiveStudy() {
+    return KERNEL::getStudyById(getActiveStudyId());
+  }
+
+
+  // __GBO__ Question: what is the difference between a
+  // SALOMEDS::Study and a SalomeApp_Study?
+  SalomeApp_Study* getSalomeAppActiveStudy() {
+    SUIT_Application* app = getSalomeApplication();
+    if( app )
+      return dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+    else
+      return NULL;
+  }
+
+
+  SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject) {
+    if (!iobject.IsNull()) {
+      if (iobject->hasEntry()) {
+        SalomeApp_Study* appStudy = getSalomeAppActiveStudy();
+        if ( appStudy != NULL ) {
+          //
+          // IMPORTANT NOTE:
+          //
+          // Note that the SalomeApp_Study give acces to shared
+          // pointer (i.e. _PTR(<BaseClassName>)) that points to proxy
+          // objects (i.e. SALOMEDSClien_<BaseClassName>) that embeds
+          // the CORBA servants (i.e. SALOMEDS::<BaseClassName>_ptr).
+          // Then to retrieve the corba servant, a method is to
+          // retrieve the SALOMEDS::Study servant first and the to
+          // request this servant to get the SObject given its entry.
+          //
+          _PTR(Study) studyClient = appStudy->studyDS();
+          SALOMEDS::Study_var study = KERNEL::getStudyManager()->GetStudyByID(studyClient->StudyId());
+          SALOMEDS::SObject_ptr sobject = study->FindObjectID(iobject->getEntry());
+          return sobject;
+        }
+      }
+    }
+    return SALOMEDS::SObject::_nil();
+  }
+
+}
+
diff --git a/src/GuiHelpers/SALOME_GuiServices.hxx b/src/GuiHelpers/SALOME_GuiServices.hxx
new file mode 100644 (file)
index 0000000..990596c
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef __GUI_SERVICES_H__
+#define __GUI_SERVICES_H__
+
+#include <SalomeApp_Application.h>
+#include <SalomeApp_Study.h>
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_ResourceMgr.h>
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOMEDS)
+#include <SALOME_InteractiveObject.hxx>
+#include <SALOME_KernelServices.hxx>
+
+namespace GUI {
+
+  // SALOME GUI main services
+  SalomeApp_Application * getSalomeApplication();
+  LightApp_SelectionMgr * getSelectionManager();
+  SUIT_ResourceMgr      * getResourcesManager();
+
+  // Helper functions to deal with the study in a GUI context.
+  //
+  // First of all, in a GUI context, there is one of the opened
+  // studies that is considered as active. Please note that the active
+  // study is a GUI concept and it can be obtained only in the
+  // SALOME_SessionServer process, i.e. the process that embeds the
+  // SalomeApp_Application. The concept of active study doesn't make
+  // sense outside of the GUI context.
+  //
+  // The active study is associated with an GUI Objects Browser that
+  // displays a graphical representation of the study. The items that
+  // can be selected in the Objects Browser are name Interactive
+  // Objects (instance of class SALOME_InteractiveObject). To work
+  // with data, we have to retrieve from this Interactive Object (IO)
+  // the underlying Study Object (instance of class SALOMEDS::SObject)
+  // and from this last the data object that can be anything (that
+  // depends of the SALOME module technical choices). In general, on
+  // of the attribute of a SObject is a CORBA servant that handles the
+  // data to work with
+  SALOMEDS::Study_ptr getActiveStudy();
+  int                 getActiveStudyId();
+
+  // Another way to get the active study (to be converted in
+  // SALOMEDS::Study):
+  SalomeApp_Study   * getSalomeAppActiveStudy();
+
+  SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject);
+
+  template<class TInterface> typename TInterface::_var_type
+  IObjectToInterface(const Handle(SALOME_InteractiveObject)& iobject) {
+    SALOMEDS::SObject_ptr sobject = IObjectToSObject(iobject);
+    return KERNEL::SObjectToInterface<TInterface>(sobject);
+  }
+  // _MEM_: note that template functions have to be declared AND
+  // implemented in the header because they are not compiled in this
+  // library but in every client library that includes this header
+  // file. The effective compilation depends on the particular class
+  // used for TInterface.
+
+
+}
+
+#endif // GUI_SERVICES
diff --git a/src/GuiHelpers/StandardApp_Module.cxx b/src/GuiHelpers/StandardApp_Module.cxx
new file mode 100644 (file)
index 0000000..6ace494
--- /dev/null
@@ -0,0 +1,338 @@
+// Copyright (C) 2011-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Guillaume Boulant (EDF) 
+
+#include "StandardApp_Module.hxx"
+
+#include <SUIT_Desktop.h>
+#include <SUIT_Study.h>
+#include <SalomeApp_Application.h>
+#include <SALOME_LifeCycleCORBA.hxx>
+#include "QtxPopupMgr.h"
+
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
+
+// QT Includes
+#include <QIcon>
+#include <QAction>
+
+#include <Basics_Utils.hxx>
+#include "QtHelper.hxx"
+
+// Constructor
+StandardApp_Module::StandardApp_Module() :
+  SalomeApp_Module( "" ),
+  LightApp_Module( "" )
+{
+  // Note that it's no use to specify here the moduleName because it's
+  // automatically determined by the name of the GUI library
+  // (lib<moduleName>.so) just before initialize step. If you want
+  // nevertheless to setup the module name you should specified this
+  // name in the initialize function below using the CAM_module
+  // function setModuleName(QString&). You are warn then that the
+  // loading of resource files may be incorect and should be manually
+  // managed. In conclusion, if you don't need a special
+  // configuration, please conform to the standard convention: if
+  // <moduleName> is the name of the module as declared in the GUI
+  // configuration file (SalomeApp.xml), then you just have to provide
+  // a library whose name is lib<moduleName>.so and which contains a
+  // factory "extern C" function 'CAM_Module* createModule()'
+}
+
+int StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE = 910;
+int StandardApp_Module::ACTIONID_UNDEFINED = -1;
+
+// Module's initialization
+void StandardApp_Module::initialize( CAM_Application* app )
+{
+  //
+  // ----------------------------------------------------------------
+  // Standard initialization
+  // ----------------------------------------------------------------
+  //
+  SalomeApp_Module::initialize( app );
+  _resourceMgr = app->resourceMgr();
+  // Please note that the moduleName() function is inherited from
+  // CAM_module classe, and that its value is determined automatically
+  // from the name specified in the SalomeApp.xml associated to this
+  // module and which corresponds to the name of the GUI library
+  // (lib<moduleName>.so). For XSALOME, see
+  // share/salome/resources/xsalome/SalomeApp.xml in the install
+  // directory.
+  _defaultMenuId = this->createMenu( QCHARSTAR(moduleName()), -1, -1, 30 );
+  _defaultToolbarId = this->createTool ( QCHARSTAR(moduleName()) );
+  _actionId_internalCount = StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE;
+
+  //
+  // ----------------------------------------------------------------
+  // The following initializes the GUI widget and associated actions
+  // ----------------------------------------------------------------
+  // These functions may be redefined in specialized version of this class
+  this->createModuleWidgets();
+  this->createModuleActions();
+}
+
+QIcon StandardApp_Module::createIcon(const QString& iconName) {
+  // The icon file is supposed to be available througth the resource
+  // manager, i.e. in the folder containing the XSALOME resources (see
+  // specification in the module file SalomeApp.xml).
+  QPixmap aPixmap = _resourceMgr->loadPixmap( QCHARSTAR(moduleName()), iconName );
+  return QIcon( aPixmap );
+}
+
+int StandardApp_Module::newActionId() {
+  _actionId_internalCount++;
+  return _actionId_internalCount;
+}
+
+/*!
+ * This function creates an action and connects it to a button in the
+ * toolbar and to an item in the menu associated to this module.  This
+ * function applies a common and standard procedure with a maximum of
+ * default values. If no identifier is specified, then a static
+ * internal counter is used to associate an identifier to the created
+ * action. In any case, the action identifier is returned.
+ *
+ * Note that the action (object of type QAction) can be retrieved
+ * using the method "QAction * action(int identifier)" of the super
+ * class.
+ */
+int StandardApp_Module::createStandardAction(const QString& label,
+                                            QObject * slotobject,
+                                            const char* slotmember,
+                                            const QString& iconName,
+                                            const QString& tooltip,
+                                            const int identifier)
+{
+
+  // If the tooltip is not defined, we choose instead the label text.
+  QString effToolTip(tooltip);
+  if ( effToolTip.isEmpty() )
+    effToolTip = label;
+
+  QIcon actionIcon = this->createIcon(iconName);
+
+  // If the identifier is not specified, then we use an internal
+  // counter.
+  int effIdentifier = identifier;
+  if ( effIdentifier == StandardApp_Module::ACTIONID_UNDEFINED ) {
+    effIdentifier=newActionId();
+  }
+
+  // Creating the action
+  QAction * action= this->createAction( effIdentifier, label, actionIcon, 
+                                        label, effToolTip, 0, getApp()->desktop(),
+                                        false, slotobject, slotmember);
+
+  return effIdentifier;
+}
+
+/**
+ * Integrate the action in the default toolbar
+ */
+void StandardApp_Module::addActionInToolbar(int actionId) {
+  this->createTool( actionId, _defaultToolbarId );
+}
+
+/**
+ * Integrate the action in the default menu
+ */
+void StandardApp_Module::addActionInMenubar(int actionId) {
+  this->createMenu( actionId, _defaultMenuId, 10 );
+}
+
+/**
+ * Add the specified action as an item in the popup menu, with the
+ * specified visible rule. The default is "visible for object browser".
+ */
+void StandardApp_Module::addActionInPopupMenu(int actionId,const QString& rule) {
+  // _GBO_ for a fine customization of the rule (for example with a
+  // test on the type of the selected object), see the LIGTH module:
+  // implement "LightApp_Selection*    createSelection() const;"
+  int parentId = -1;
+  QtxPopupMgr* mgr = this->popupMgr();
+  mgr->insert ( this->action( actionId ), parentId, 0 );
+  mgr->setRule( this->action( actionId ), rule, QtxPopupMgr::VisibleRule );
+}
+
+/*!
+ * This function can be used to create additionnal widget for this
+ * module GUI (e.g. docked widget). It can be redefined in a
+ * specialized version of this class.
+ */
+void StandardApp_Module::createModuleWidgets() {
+  // Nothing to do in this default gui
+}
+
+/*!
+ * This function can be used to defined the list of actions for this
+ * module GUI.  It can be redefined in a specialized version of this
+ * class.
+ * Depending on wether you use the method "createStandardAction" or
+ * not, the actions will be automatically plugged in the toolbar and
+ * the menu associated to the module.
+ */
+void StandardApp_Module::createModuleActions() {
+  int actionId = this->createStandardAction("Test", this, SLOT(OnTest()),
+                                           "f1.png", "Run the default test function");
+  this->addActionInToolbar(actionId);
+}
+
+// Get compatible dockable windows.
+void StandardApp_Module::windows( QMap<int, int>& theMap ) const
+{
+  theMap.clear();
+  theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+  theMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
+}
+
+// Module's engine IOR
+QString StandardApp_Module::engineIOR() const
+{
+  CORBA::String_var anIOR = getApp()->orb()->object_to_string(getEngine());
+  return QString( anIOR.in() );
+}
+
+/*!
+ * This specifies the filename for the icon to be used for the study
+ * component associated to the module. Note that this icon could be
+ * different than the module icon which is defined by the
+ * SalomeApp.xml file dedicated to this module (see the shared
+ * resources folder dedicated to the module) and which is used for the
+ * toolbar of the SALOME application.
+ */
+QString StandardApp_Module::studyIconName()
+{
+  // By default, we return the module icone name
+  return iconName(); // inherited from CAM_Module
+}
+
+/*!
+ * This can be used to switch the layout of main application
+ * dockwidgets to one of the predefined configuration (see enum
+ * DockLayoutType). When a layout is set, the previous layout is
+ * memorized and can be restored using the unsetDockLayout function (1
+ * step undo). It is typically to be used in the functions
+ * activateModule to setup the layout and deactivateModule to unset
+ * the layout, i.e. restore to the previous state.
+ */
+void StandardApp_Module::setDockLayout(DockLayoutType layoutType) {
+  SUIT_Desktop* desk = getApp()->desktop();
+  _areaAtBottomLeftCorner = desk->corner(Qt::BottomLeftCorner);
+  _areaAtBottomRightCorner = desk->corner(Qt::BottomRightCorner);
+  
+  if ( layoutType == DOCKLAYOUT_LEFT_VLARGE ) {
+    desk->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+    desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+  } else {
+    desk->setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
+    desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);    
+  }
+}
+
+/*!
+ * This function restores the layout state that was previously in
+ * place before the last setDockLayout call.
+ */
+void StandardApp_Module::unsetDockLayout() {
+  SUIT_Desktop* desk = getApp()->desktop();
+  desk->setCorner(Qt::BottomLeftCorner, _areaAtBottomLeftCorner);
+  desk->setCorner(Qt::BottomRightCorner, _areaAtBottomRightCorner);
+}
+
+// Module's activation
+bool StandardApp_Module::activateModule( SUIT_Study* theStudy )
+{
+  bool bOk = SalomeApp_Module::activateModule( theStudy );
+
+  setMenuShown( true );
+  setToolShown( true );
+
+  if ( this->createStudyComponentAtActivation() ) {
+    this->createStudyComponent(theStudy);
+  }
+
+  return bOk;
+}
+
+/*!
+ * This function should be implemented in a specialized class and must
+ * return true if you want to automatically create a study component
+ * for this module at activation step (when you first load the module
+ * for a given study). The default function return true.
+ */
+bool StandardApp_Module::createStudyComponentAtActivation() {
+  return true;
+}
+
+/*!
+ * This creates a root entry in the active study for this module, i.e
+ * a SComponent with the name of the module and the icon specified for
+ * the module. This component is associated to the engine (return by
+ * getEngine()) if the engine is a SALOMEDS::Driver.
+ */
+void StandardApp_Module::createStudyComponent(SUIT_Study* theStudy) {
+
+  SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
+  CORBA::Object_var aSMObject = aNamingService->Resolve("/myStudyManager");
+  SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(aSMObject);
+  SALOMEDS::Study_var aDSStudy = aStudyManager->GetStudyByID(theStudy->id());
+
+  SALOMEDS::SComponent_var aFather = aDSStudy->FindComponent(QCHARSTAR(moduleName()));
+  if (aFather->_is_nil())
+    {
+      SALOMEDS::StudyBuilder_var aStudyBuilder = aDSStudy->NewBuilder();
+      aFather = aStudyBuilder->NewComponent(QCHARSTAR(moduleName()));
+      SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
+      SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
+      aName->SetValue(QCHARSTAR(moduleName()));
+      aName->Destroy();
+      anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
+      SALOMEDS::AttributePixMap_var aPixMap = SALOMEDS::AttributePixMap::_narrow(anAttr);
+      aPixMap->SetPixMap(QCHARSTAR(studyIconName()));
+
+      // WARN: The engine should be associated to the SComponent IF
+      // AND ONLY IF it is a SALOMEDS::Driver. Otherwise, there is no
+      // need to do that, and it could even lead to exception
+      // raising (eh, you work on SALOME isn't it?)
+      SALOMEDS::Driver_var driver = SALOMEDS::Driver::_narrow(this->getEngine());
+      if ( ! driver->_is_nil() ) {
+       STDLOG("Associate the SComponent to the engine");
+       aStudyBuilder->DefineComponentInstance(aFather, this->getEngine());
+      }
+    }
+
+}
+
+// Module's deactivation
+bool StandardApp_Module::deactivateModule( SUIT_Study* theStudy )
+{
+  setMenuShown( false );
+  setToolShown( false );
+
+  return SalomeApp_Module::deactivateModule( theStudy );
+}
+
+void StandardApp_Module::OnTest()
+{
+  // Just for test
+  STDLOG("OnTest: engine IOR = "<<QCHARSTAR(engineIOR()));
+}
+
diff --git a/src/GuiHelpers/StandardApp_Module.hxx b/src/GuiHelpers/StandardApp_Module.hxx
new file mode 100644 (file)
index 0000000..1094463
--- /dev/null
@@ -0,0 +1,145 @@
+// Copyright (C) 2011-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Guillaume Boulant (EDF) 
+
+#ifndef _STANDARDAPP_MODULE_HXX_
+#define _STANDARDAPP_MODULE_HXX_
+
+#include <SUIT_ResourceMgr.h>
+#include <SalomeApp_Module.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Component)
+
+#include <QString>
+
+/*!
+ * This class is provided as the base class for the standard gui part
+ * of a SALOME module. To define a gui part, you just have to
+ * implement the virtual functions:
+ * - getEngine() to specify the engine component associated to this module
+ * - createModuleActions(...) to specify the action functions
+ * - createModuleWidgets(...) to specify special additionnal widgets
+ *
+ * The gui part of a SALOME module is an extension of the SALOME
+ * client Application for this module. Technically speaking, it
+ * consists in a plugin that provides a derived class of CAM_Module
+ * (provided by the GUI module).
+ *
+ * A standard gui is the standard design for most of SALOME module
+ * (object browser on the left, viewer on the rigth, python console on
+ * the bottom, and toolbox in the toolbar with standard definition of
+ * the tool function). This standard design suggests also to specify
+ * the engine associated to the module by implementing the virtual
+ * pure function getEngine(). The engine of a module is the SALOME
+ * component that is associated to the study component for this
+ * module, and generally which is responsible for the persistency
+ * functions or data management for the module.
+ *
+ * See a use case example in the test module Xsalome provided by the
+ * test package (tst/module/gui/Xsalome.hxx and
+ * tst/module/gui/factory.cxx in the XSALOME library).
+ */
+class StandardApp_Module: public SalomeApp_Module
+{
+  Q_OBJECT
+
+public:
+
+  // ================================================================
+  // This part defines the standard interface of the SalomeApp_Module
+  // ================================================================
+
+  StandardApp_Module();
+  void    initialize( CAM_Application* );
+  QString engineIOR() const;
+  virtual void  windows( QMap<int, int>& theMap ) const;
+
+public slots:
+  bool    deactivateModule( SUIT_Study* );
+  bool    activateModule( SUIT_Study* );
+
+  // ================================================================
+  // This part defines the specific interface of this class
+  // ================================================================
+
+public:
+  /* Creates an action with standard default values */
+  int createStandardAction(const QString& label,
+                          QObject * slotobject,
+                           const char* slotmember,
+                           const QString& iconName=QString(),
+                           const QString& tooltip=QString(),
+                           const int identifier=ACTIONID_UNDEFINED);
+
+  void addActionInToolbar(int actionId);
+  void addActionInMenubar(int actionId);
+  void addActionInPopupMenu(int actionId,const QString& rule="client='ObjectBrowser'");
+
+protected:
+  /* Implement this to create additionnal widget (e.g. docked widget) */
+  virtual void createModuleWidgets();
+  /* Implement this to define the actions for this gui */
+  virtual void createModuleActions();
+
+  /* Use this to create a root entry in the study for this module */
+  void createStudyComponent(SUIT_Study*);
+  /* Implement this to say if study component entry should be created
+     at activation step */
+  virtual bool createStudyComponentAtActivation();
+
+  /* The engine is the SALOME component associated to the study */
+  virtual Engines::EngineComponent_ptr getEngine() const = 0;
+  // Note that the function getEngine() is virtual pure and must be
+  // implemented in the specific inherited classes. Note also that the
+  // const flag is required because getEngine is used by functions
+  // with const flags (see for ex: engineIOR()).
+  virtual QString studyIconName();
+
+  QIcon createIcon(const QString& iconName);
+  int newActionId();
+
+  enum DockLayoutType {
+    DOCKLAYOUT_BOTTOM_HLARGE, // Bottom is Horizontal Large
+    DOCKLAYOUT_LEFT_VLARGE,   // Left is Vertical Large
+  };
+  virtual void setDockLayout(DockLayoutType layoutType);
+  virtual void unsetDockLayout();
+  
+  SUIT_ResourceMgr* _resourceMgr;
+  int _defaultMenuId;
+  int _defaultToolbarId;
+
+  static int ACTIONID_DEFAULT_INIT_VALUE;
+  static int ACTIONID_UNDEFINED;
+
+private:
+  int _actionId_internalCount;
+  Qt::DockWidgetArea _areaAtBottomLeftCorner;
+  Qt::DockWidgetArea _areaAtBottomRightCorner;
+
+  // =========================================================
+  // This part defines slots for test purposes
+  // =========================================================
+
+protected slots:
+  void OnTest();
+};
+
+#endif
diff --git a/src/LightApp/images/en.png b/src/LightApp/images/en.png
new file mode 100644 (file)
index 0000000..ff701e1
Binary files /dev/null and b/src/LightApp/images/en.png differ
diff --git a/src/LightApp/images/fr.png b/src/LightApp/images/fr.png
new file mode 100644 (file)
index 0000000..8332c4e
Binary files /dev/null and b/src/LightApp/images/fr.png differ
diff --git a/src/OpenGLUtils/Makefile.am b/src/OpenGLUtils/Makefile.am
new file mode 100755 (executable)
index 0000000..665488d
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#  File   : Makefile.am
+#  Author : Oleg UVAROV
+#  Module : SALOME
+#  $Header$
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+lib_LTLIBRARIES = libOpenGLUtils.la
+
+salomeinclude_HEADERS =        \
+       OpenGLUtils.h \
+       OpenGLUtils_FrameBuffer.h
+
+dist_libOpenGLUtils_la_SOURCES = \
+       OpenGLUtils_FrameBuffer.cxx
+
+libOpenGLUtils_la_CPPFLAGS = $(OGL_INCLUDES)
+libOpenGLUtils_la_LDFLAGS  = $(KERNEL_LDFLAGS)
+
+libOpenGLUtils_la_LIBADD = $(OGL_LIBS) -lSALOMELocalTrace
\ No newline at end of file
diff --git a/src/OpenGLUtils/OpenGLUtils.h b/src/OpenGLUtils/OpenGLUtils.h
new file mode 100755 (executable)
index 0000000..c65d72b
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#if !defined ( OPENGLUTILS_H )
+#define OPENGLUTILS_H
+
+#ifdef WIN32
+#  if defined OPENGLUTILS_EXPORTS || defined OpenGLUtils_EXPORTS
+#    define OPENGLUTILS_EXPORT __declspec(dllexport)
+#  else
+#    define OPENGLUTILS_EXPORT __declspec(dllimport)
+#  endif
+#else
+#  define OPENGLUTILS_EXPORT
+#endif
+
+#if defined WIN32
+#pragma warning ( disable: 4251 )
+#endif
+
+#endif // OPENGLUTILS_H
diff --git a/src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx b/src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx
new file mode 100755 (executable)
index 0000000..f6514cd
--- /dev/null
@@ -0,0 +1,202 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : OpenGLUtils_FrameBuffer.cxx
+//  Module : SALOME
+//
+#include "OpenGLUtils_FrameBuffer.h"
+
+#include <utilities.h>
+
+#include <cstring>
+
+#ifndef WNT
+# ifndef GLX_GLXEXT_LEGACY
+#  define GLX_GLXEXT_LEGACY
+# endif
+# include <GL/glx.h>
+# include <dlfcn.h>
+#else
+# include <wingdi.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+
+#ifndef GL_FRAMEBUFFER_EXT
+#define GL_FRAMEBUFFER_EXT                0x8D40
+#endif
+
+#ifndef GL_RENDERBUFFER_EXT
+#define GL_RENDERBUFFER_EXT               0x8D41
+#endif
+
+#ifndef GL_COLOR_ATTACHMENT0_EXT
+#define GL_COLOR_ATTACHMENT0_EXT          0x8CE0
+#endif
+
+#ifndef GL_DEPTH_ATTACHMENT_EXT
+#define GL_DEPTH_ATTACHMENT_EXT           0x8D00
+#endif
+
+#ifndef GL_FRAMEBUFFER_COMPLETE_EXT
+#define GL_FRAMEBUFFER_COMPLETE_EXT       0x8CD5
+#endif
+
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+
+static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL;
+static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL;
+static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL;
+static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL;
+static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL;
+static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL;
+static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL;
+static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL;
+static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL;
+static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL;
+
+#ifndef WNT
+#define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
+#else
+#define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
+#endif
+
+bool InitializeEXT()
+{
+  vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" );
+  vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" );
+  vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" );
+  vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" );
+  vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" );
+  vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" );
+  vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" );
+  vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" );
+  vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" );
+  vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" );
+
+  bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT &&
+            vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT &&
+            vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT &&
+            vglDeleteRenderbuffersEXT;
+
+  return ok;
+}
+
+static bool IsEXTInitialized = InitializeEXT();
+
+OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer()
+  : textureId( 0 ),
+    fboId( 0 ),
+    rboId( 0 )
+{
+}
+
+OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer()
+{
+  release();
+}
+
+bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize )
+{
+  char* ext = (char*)glGetString( GL_EXTENSIONS );
+  if( !IsEXTInitialized ||
+      strstr( ext, "GL_EXT_framebuffer_object" ) == NULL )
+  {
+    MESSAGE( "Initializing OpenGL FrameBuffer extension failed" );
+    return false;
+  }
+
+  // create a texture object
+  glEnable( GL_TEXTURE_2D );
+  glGenTextures( 1, &textureId );
+  glBindTexture( GL_TEXTURE_2D, textureId );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
+  glBindTexture( GL_TEXTURE_2D, 0 );
+
+  // create a renderbuffer object to store depth info
+  vglGenRenderbuffersEXT( 1, &rboId );
+  vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId );
+  vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize );
+  vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
+
+  // create a framebuffer object
+  vglGenFramebuffersEXT( 1, &fboId );
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
+
+  // attach the texture to FBO color attachment point
+  vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 );
+
+  // attach the renderbuffer to depth attachment point
+  vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId );
+
+  // check FBO status
+  GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
+
+  // Unbind FBO
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+
+  return status == GL_FRAMEBUFFER_COMPLETE_EXT;
+}
+
+void OpenGLUtils_FrameBuffer::release()
+{
+  if( !IsEXTInitialized )
+    return;
+
+  glDeleteTextures( 1, &textureId );
+  textureId = 0;
+
+  vglDeleteFramebuffersEXT( 1, &fboId );
+  fboId = 0;
+
+  vglDeleteRenderbuffersEXT( 1, &rboId );
+  rboId = 0;
+}
+
+void OpenGLUtils_FrameBuffer::bind()
+{
+  if( !IsEXTInitialized )
+    return;
+
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
+}
+
+void OpenGLUtils_FrameBuffer::unbind()
+{
+  if( !IsEXTInitialized )
+    return;
+
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
diff --git a/src/OpenGLUtils/OpenGLUtils_FrameBuffer.h b/src/OpenGLUtils/OpenGLUtils_FrameBuffer.h
new file mode 100755 (executable)
index 0000000..daaf5dd
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : OpenGLUtils_FrameBuffer.h
+//  Module : SALOME
+//
+#ifndef OPENGLUTILS_FRAMEBUFFER_H
+#define OPENGLUTILS_FRAMEBUFFER_H
+
+#include "OpenGLUtils.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <GL/gl.h>
+
+class OPENGLUTILS_EXPORT OpenGLUtils_FrameBuffer
+{
+public:
+  OpenGLUtils_FrameBuffer();
+  ~OpenGLUtils_FrameBuffer();
+
+  bool init( const GLsizei&, const GLsizei& );
+  void release();
+
+  void bind();
+  void unbind();
+
+private:
+  GLuint textureId;
+  GLuint fboId;
+  GLuint rboId;
+};
+
+#endif
diff --git a/src/Qtx/resources/Qtx_msg_fr.ts b/src/Qtx/resources/Qtx_msg_fr.ts
new file mode 100644 (file)
index 0000000..c98d41b
--- /dev/null
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+    <name>QtxTreeView</name>
+    <message>
+        <source>Enable sorting</source>
+        <translation>Autoriser le tri</translation>
+    </message>
+</context>
+<context>
+    <name>QtxWorkspaceAction</name>
+    <message>
+        <source>Arranges the windows as overlapping tiles</source>
+        <translation>Ranger les fenêtres en les superposant</translation>
+    </message>
+    <message>
+        <source>Cascade</source>
+        <translation>Cascade</translation>
+    </message>
+    <message>
+        <source>Arranges the windows as nonoverlapping tiles</source>
+        <translation>Ranger les fenêtres sans les superposer</translation>
+    </message>
+    <message>
+        <source>Tile</source>
+        <translation>Mosaïque</translation>
+    </message>
+    <message>
+        <source>Arranges the windows as nonoverlapping horizontal tiles</source>
+        <translation>Ranger les fenêtres en mosaïque horizontale</translation>
+    </message>
+    <message>
+        <source>Tile horizontally</source>
+        <translation>Mosaïque horizontale</translation>
+    </message>
+    <message>
+        <source>Arranges the windows as nonoverlapping vertical tiles</source>
+        <translation>Ranger les fenêtres en mosaïque verticale</translation>
+    </message>
+    <message>
+        <source>Tile vertically</source>
+        <translation>Mosaïque verticale</translation>
+    </message>
+</context>
+<context>
+    <name>QtxMainWindow</name>
+    <message>
+        <source>Menu bar</source>
+        <translation>Barre de menu</translation>
+    </message>
+    <message>
+        <source>Status bar</source>
+        <translation>Barre de statut</translation>
+    </message>
+</context>
+<context>
+    <name>QtxPathDialog</name>
+    <message>
+        <source>Open file</source>
+        <translation>Ouvrir le fichier</translation>
+    </message>
+    <message>
+        <source>Save file</source>
+        <translation>Sauvegarder le fichier</translation>
+    </message>
+    <message>
+        <source>File name</source>
+        <translation>Nom du fichier</translation>
+    </message>
+    <message>
+        <source>File name not specified</source>
+        <translation>Le nom du fichier n&apos;est pas indiqué</translation>
+    </message>
+    <message>
+        <source>File \&quot;%1\&quot; does not exist</source>
+        <translation>Le fichier \&quot;%1\&quot; n&apos;existe pas</translation>
+    </message>
+    <message>
+        <source>File \&quot;%1\&quot; already exist. Do you want to overwrite it?</source>
+        <translation>Le fichier \&quot;%1\&quot; existe déjà. Voulez-vous l&apos;écraser ?</translation>
+    </message>
+    <message>
+        <source>Directory \&quot;%1\&quot; does not exist</source>
+        <translation>Le répertoire \&quot;%1\&quot; n&apos;existe pas</translation>
+    </message>
+    <message>
+        <source>Directory \&quot;%1\&quot; can&apos;t be created because file with the same name exist</source>
+        <translation>Il est impossible de créer le répertoire \&quot;%1\&quot; parce qu&apos;un fichier avec ce nom existe déjà</translation>
+    </message>
+    <message>
+        <source>Directory \&quot;%1\&quot; not empty. Do you want to remove all files in this directory?</source>
+        <translation>Le répertoire \&quot;%1\&quot; n&apos;est pas vide. Voulez-vous supprimer tous les fichiers dans ce répertoire?</translation>
+    </message>
+    <message>
+        <source>File dialog</source>
+        <translation>Fenêtre de dialogue de fichiers</translation>
+    </message>
+    <message>
+        <source>All files (*.*)</source>
+        <translation>Tous les fichiers (*.*)</translation>
+    </message>
+</context>
+<context>
+    <name>QtxFontEdit</name>
+    <message>
+        <source>B</source>
+        <translatorcomment>Bold</translatorcomment>
+        <translation>G</translation>
+    </message>
+    <message>
+        <source>I</source>
+        <translatorcomment>Italic</translatorcomment>
+        <translation>I</translation>
+    </message>
+    <message>
+        <source>U</source>
+        <translatorcomment>Underline</translatorcomment>
+        <translation>S</translation>
+    </message>
+    <message>
+        <source>S</source>
+        <translatorcomment>Strikethrough</translatorcomment>
+        <translation>R</translation>
+    </message>
+</context>
+<context>
+    <name>QtxPathListEdit</name>
+    <message>
+        <source>Warning</source>
+        <translation>Avertissement</translation>
+    </message>
+    <message>
+        <source>Path \&quot;%1\&quot; doesn&apos;t exist. Add it to list anyway?</source>
+        <translation>Le chemin \&quot;%1\&quot; n&apos;existe pas. Faut-il l&apos;ajouter dans la liste?</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation>Erreur</translation>
+    </message>
+    <message>
+        <source>Location \&quot;%1\&quot; doesn&apos;t point to file</source>
+        <translation>L&apos;emplacement \&quot;%1\&quot; ne pointe sur aucun fichier</translation>
+    </message>
+    <message>
+        <source>Location \&quot;%1\&quot; doesn&apos;t point to directory</source>
+        <translation>L&apos;emplacement \&quot;%1\&quot; ne pointe sur aucun répertoire</translation>
+    </message>
+    <message>
+        <source>Path \&quot;%1\&quot; already exist in the list</source>
+        <translation>Le chemin \&quot;%1\&quot; existe déjà dans la liste</translation>
+    </message>
+</context>
+<context>
+    <name>QtxMRUAction</name>
+    <message>
+        <source>Most Recently Used</source>
+        <translation>Récemment utilisés</translation>
+    </message>
+    <message>
+        <source>Clear</source>
+        <translation>Effacer</translation>
+    </message>
+    <message>
+        <source>&lt;Empty&gt;</source>
+        <translation>&lt;Vide&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>QtxDialog</name>
+    <message>
+        <source>&amp;OK</source>
+        <translation>&amp;OK</translation>
+    </message>
+    <message>
+        <source>&amp;Cancel</source>
+        <translation>&amp;Annuler</translation>
+    </message>
+    <message>
+        <source>C&amp;lose</source>
+        <translation>&amp;Fermer</translation>
+    </message>
+    <message>
+        <source>&amp;Help</source>
+        <translation>&amp;Aide</translation>
+    </message>
+    <message>
+        <source>&amp;Apply</source>
+        <translation>A&amp;ppliquer</translation>
+    </message>
+    <message>
+        <source>&amp;Yes</source>
+        <translation>&amp;Oui</translation>
+    </message>
+    <message>
+        <source>&amp;No</source>
+        <translation>&amp;Non</translation>
+    </message>
+</context>
+<context>
+    <name>QtxSearchTool</name>
+    <message>
+        <source>Case sensitive</source>
+        <translation>Sensible à la casse</translation>
+    </message>
+    <message>
+        <source>Regular expression</source>
+        <translation>Expression régulière</translation>
+    </message>
+    <message>
+        <source>Wrap search</source>
+        <translation>Continuer la recherche</translation>
+    </message>
+</context>
+<context>
+    <name>QtxSplash</name>
+    <message>
+        <source>Error</source>
+        <translation>Erreur</translation>
+    </message>
+    <message>
+        <source>&amp;OK</source>
+        <translation>&amp;OK</translation>
+    </message>
+</context>
+<context>
+    <name>QtxWorkstack</name>
+    <message>
+        <source>Split vertically</source>
+        <translation>Diviser verticalement</translation>
+    </message>
+    <message>
+        <source>Split horizontally</source>
+        <translation>Diviser horisontalement</translation>
+    </message>
+    <message>
+        <source>Close</source>
+        <translation>Fermer</translation>
+    </message>
+    <message>
+        <source>Rename</source>
+        <translation>Renommer</translation>
+    </message>
+    <message>
+        <source>Enter new name:</source>
+        <translation>Indiquer un nouveau nom:</translation>
+    </message>
+</context>
+<context>
+    <name>QtxWorkstackAction</name>
+    <message>
+        <source>Split the active window on two vertical parts</source>
+        <translation>Diviser la fenêtre actuelle en deux parties verticales</translation>
+    </message>
+    <message>
+        <source>Split vertically</source>
+        <translation>Diviser verticalement</translation>
+    </message>
+    <message>
+        <source>Split the active window on two horizontal parts</source>
+        <translation>Diviser la fenêtre actuelle en deux parties horizontales</translation>
+    </message>
+    <message>
+        <source>Split horizontally</source>
+        <translation>Diviser horizontalement</translation>
+    </message>
+</context>
+<context>
+    <name>QtxColorButton</name>
+    <message>
+        <source>Auto</source>
+        <translation>Auto</translation>
+    </message>
+    <message>
+        <source>Other colors...</source>
+        <translation>Autres couleurs...</translation>
+    </message>
+</context>
+<context>
+    <name>QtxColorScale</name>
+    <message>
+        <source>Color scale</source>
+        <translation>Echelle de couleurs</translation>
+    </message>
+</context>
+<context>
+    <name>QtxBackgroundTool</name>
+    <message>
+        <source>Browse...</source>
+        <translation>Parcourir...</translation>
+    </message>
+    <message>
+        <source>Not implemented yet</source>
+        <translation>Pas encore disponible</translation>
+    </message>
+    <message>
+        <source>Center</source>
+        <translation>Centre</translation>
+    </message>
+    <message>
+        <source>Tile</source>
+        <translation>Mosaïque</translation>
+    </message>
+    <message>
+        <source>Stretch</source>
+        <translation>Etiré</translation>
+    </message>
+    <message>
+        <source>Images Files (*.bmp *.png *.jpg *.jpeg *.gif *.tiff)</source>
+        <translation>Fichiers images (*.bmp *.png *.jpg *.jpeg *.gif *.tiff)</translation>
+    </message>
+    <message>
+        <source>Image</source>
+        <translation>Image</translation>
+    </message>
+    <message>
+        <source>Single Color</source>
+        <translation>Couleur unique</translation>
+    </message>
+    <message>
+        <source>Custom</source>
+        <translation>Personnalisé</translation>
+    </message>
+    <message>
+        <source>Select Picture</source>
+        <translation>Choisir l&apos;image</translation>
+    </message>
+</context>
+<context>
+    <name>QtxBackgroundDialog</name>
+    <message>
+        <source>Change background</source>
+        <translation>Modifier l&apos;arrière plan</translation>
+    </message>
+</context>
+</TS>
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/Makefile.am b/src/SALOME_PYQT/SALOME_PYQT_GUILight/Makefile.am
new file mode 100644 (file)
index 0000000..525818c
--- /dev/null
@@ -0,0 +1,103 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#  File   : Makefile.am
+#  Author : Roman NIKOLAEV Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# Library target
+lib_LTLIBRARIES = libSalomePyQtGUILight.la
+
+
+# extra source files (generated by sip)
+SIP_SRC   = sipAPISalomePyQtGUILight.h       \
+            sipSalomePyQtGUILightcmodule.cc
+
+# Sip definition file
+SIP_FILES = SALOME_PYQT_GUILight.sip
+
+# extra dist files
+EXTRA_DIST += $(SIP_FILES)
+
+
+# extra clean files
+CLEANFILES = $(SIP_SRC)
+
+# moc files (generated my moc)
+MOC_FILES = \
+       SALOME_PYQT_ModuleLight_moc.cxx \
+       SALOME_PYQT_DataModelLight_moc.cxx 
+
+
+# exported header files
+salomeinclude_HEADERS =        \
+       SALOME_PYQT_GUILight.h \
+       SALOME_PYQT_ModuleLight.h \
+       SALOME_PYQT_DataObjectLight.h \
+       SALOME_PYQT_DataModelLight.h \
+       SALOME_PYQT_PyInterp.h
+
+# library sources
+dist_libSalomePyQtGUILight_la_SOURCES = \
+       SALOME_PYQT_ModuleLight.cxx \
+       SALOME_PYQT_DataObjectLight.cxx \
+       SALOME_PYQT_DataModelLight.cxx  \
+       SALOME_PYQT_PyInterp.cxx
+
+nodist_libSalomePyQtGUILight_la_SOURCES = $(MOC_FILES) $(SIP_SRC)
+
+
+libSalomePyQtGUILight_la_CPPFLAGS =  $(QT_INCLUDES) $(SIP_INCLUDES) $(PYTHON_INCLUDES) \
+       $(CAS_CPPFLAGS) $(VTK_INCLUDES) $(OGL_INCLUDES) $(BOOST_CPPFLAGS)               \
+       -DHAVE_CONFIG_H @KERNEL_CXXFLAGS@ -DCALL_OLD_METHODS                            \
+       -I. -I$(srcdir)/../../PyInterp -I$(srcdir)/../../PyConsole              \
+       -I$(srcdir)/../../SUIT -I$(srcdir)/../../Qtx -I$(srcdir)/../../LightApp         \
+       -I$(srcdir)/../../Plot2d -I$(srcdir)/../../OCCViewer                            \
+       -I$(srcdir)/../../CAM -I$(srcdir)/../../STD                                     \
+       -I$(srcdir)/../../SUITApp                                                       \
+       -I$(srcdir)/../../CAM -I$(srcdir)/../../STD
+
+if GUI_ENABLE_CORBA
+libSalomePyQtGUILight_la_CPPFLAGS += -I$(srcdir)/../../SalomeApp \
+                                    @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
+endif
+                       
+
+if !GUI_ENABLE_CORBA
+  libSalomePyQtGUILight_la_CPPFLAGS += -DGUI_DISABLE_CORBA
+endif
+
+# linkage flags
+libSalomePyQtGUILight_la_LIBADD = $(PYTHON_LIBS) $(SIP_LIBS) $(PYQT_LIBS) $(VTK_LIBS)  \
+                                  $(OGL_LIBS) ../../PyInterp/libPyInterp.la ../../LightApp/libLightApp.la
+
+if GUI_ENABLE_CORBA
+  libSalomePyQtGUILight_la_LIBADD +=../../SalomeApp/libSalomeApp.la $(KERNEL_LDFLAGS) -lSalomeContainer
+endif
+                       
+
+
+# Custom build step: generate C++ wrapping according to $(SIP_FILES)
+$(SIP_SRC): $(SIP_FILES)
+       $(SIP) $(PYQT_SIPFLAGS) $<
+
+# extra dependency (SALOME_PYQT_Module.cxx depends on header files generated by sip)
+$(dist_libSalomePyQtGUILight_la_SOURCES): $(SIP_SRC)
+
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx
new file mode 100644 (file)
index 0000000..70222af
--- /dev/null
@@ -0,0 +1,203 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+//  Date   : 22/06/2007
+//
+#include "PyInterp_Interp.h" // // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+
+#include "SALOME_PYQT_DataModelLight.h" 
+#include "SALOME_PYQT_DataObjectLight.h"
+#include "SALOME_PYQT_ModuleLight.h"
+#include <utilities.h>
+
+#include <LightApp_Study.h>
+#include <CAM_Module.h>
+#include <CAM_Application.h>
+#include <CAM_Study.h>
+
+
+//=================================================================================
+// function : SALOME_PYQT_DataModelLight()
+// purpose  : constructor
+//=================================================================================
+SALOME_PYQT_DataModelLight::SALOME_PYQT_DataModelLight(CAM_Module * theModule)
+  : LightApp_DataModel( theModule ),
+    myFileName( "" ),
+    myStudyURL( "" ),
+    myModified( false )
+{
+  
+}
+
+//=================================================================================
+// function : ~SALOME_PYQT_DataModelLight()
+// purpose  : destructor
+//=================================================================================
+SALOME_PYQT_DataModelLight::~SALOME_PYQT_DataModelLight()
+{
+}
+
+//=================================================================================
+// function : open()
+// purpose  : Open data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::open( const QString& theURL, CAM_Study* study, QStringList theListOfFiles)
+{
+  MESSAGE("SALOME_PYQT_DataModelLight::open()");
+  LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( study );
+  SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+  if ( !aDoc || !aModule)
+    return false;
+  
+  LightApp_DataModel::open( theURL, aDoc, theListOfFiles );
+
+  setModified( false );
+  
+  return aModule->open(theListOfFiles);
+  
+}
+
+//=================================================================================
+// function : save()
+// purpose  : Save data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::save( QStringList& theListOfFiles)
+{
+  MESSAGE("SALOME_PYQT_DataModelLight::save()");
+  bool isMultiFile = false; // temporary solution
+  
+  LightApp_DataModel::save(theListOfFiles);
+  LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
+  SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+
+  if(!aModule || !study)
+    return false;
+  
+
+  std::string aTmpDir = study->GetTmpDir(myStudyURL.toLatin1().constData(), isMultiFile );
+
+  theListOfFiles.append(QString(aTmpDir.c_str()));
+  int listSize = theListOfFiles.size();
+  aModule->save(theListOfFiles);
+
+  setModified( false );
+
+  //Return true if in the List of files was added item(s)
+  //else return false 
+  return theListOfFiles.size() > listSize;
+}
+
+//=================================================================================
+// function : saveAs()
+// purpose  : SaveAs data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::saveAs ( const QString& theURL, CAM_Study* theStudy, QStringList& theListOfFiles)
+{
+  myStudyURL = theURL;
+  return save(theListOfFiles);
+}
+
+
+
+bool SALOME_PYQT_DataModelLight::create( CAM_Study* study )
+{
+  return true;
+}
+
+//=================================================================================
+// function : dumpPython()
+// purpose  : Re-defined from LigthApp_DataModel in order to participate 
+//            in dump study process
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::dumpPython( const QString& theURL, 
+                                            CAM_Study* theStudy,
+                                            bool isMultiFile,
+                                            QStringList& theListOfFiles )
+{
+  MESSAGE("SALOME_PYQT_DataModelLight::dumpPython()");
+  
+  LightApp_DataModel::dumpPython( theURL, theStudy, isMultiFile, theListOfFiles );
+
+  LightApp_Study* study = dynamic_cast<LightApp_Study*>( theStudy );
+  SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+
+  if(!aModule || !study)
+    return false;
+  
+  std::string aTmpDir = study->GetTmpDir( theURL.toLatin1().constData(), isMultiFile );
+
+  theListOfFiles.append( QString( aTmpDir.c_str() ) );
+  int oldSize = theListOfFiles.size();
+
+  aModule->dumpPython( theListOfFiles );
+
+  //Return true if some items have been added, else return false 
+  return theListOfFiles.size() > oldSize;
+}
+
+//=================================================================================
+// function : isModified()
+// purpose  : returns this model's modification status that can be controlled 
+//            with help of setModified() calls by the underlying Python module
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::isModified() const
+{
+  return myModified;
+}
+
+//=================================================================================
+// function : setModified()
+// purpose  : sets the model's modification status, should be used by 
+//            the underlying Python module when its data changes.
+//=================================================================================
+void SALOME_PYQT_DataModelLight::setModified( bool flag )
+{
+  myModified = flag;
+}
+
+//=================================================================================
+// function : close()
+// purpose  : Close data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::close()
+{
+  LightApp_DataModel::close();
+  return true;
+}
+
+
+void SALOME_PYQT_DataModelLight::update ( LightApp_DataObject* theObj, LightApp_Study* theStudy )
+{
+  // Nothing to do here: we always keep the data tree in the up-to-date state
+  // The only goal of this method is to hide default behavior from LightApp_DataModel
+  return;
+}
+
+CAM_DataObject* SALOME_PYQT_DataModelLight::getRoot()
+{
+  LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
+  CAM_ModuleObject *aModelRoot = dynamic_cast<CAM_ModuleObject*>(root());
+  if(study && aModelRoot == NULL) {
+    aModelRoot = createModuleObject( study->root() );
+    aModelRoot->setDataModel( this );
+    setRoot(aModelRoot);
+  }
+  return aModelRoot;
+}
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h
new file mode 100644 (file)
index 0000000..35ca6d1
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+//  Date   : 22/06/2007
+//
+#ifndef SALOME_PYQT_DATAMODELLIGHT_H
+#define SALOME_PYQT_DATAMODELLIGHT_H
+
+#include "SALOME_PYQT_GUILight.h"
+#include <LightApp_DataModel.h>
+
+#include <CAM_Module.h>
+#include "SALOME_PYQT_DataObjectLight.h"
+
+class SALOME_PYQT_RootObjectLight;
+
+
+
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_DataModelLight : public LightApp_DataModel
+{
+  Q_OBJECT
+
+public:
+  SALOME_PYQT_DataModelLight( CAM_Module* theModule );
+  virtual ~SALOME_PYQT_DataModelLight();
+  
+  virtual bool         open   ( const QString&, CAM_Study*, QStringList );
+  virtual bool         save   ( QStringList& );
+  virtual bool         saveAs ( const QString&, CAM_Study*, QStringList& );
+  virtual bool         close  ();
+  virtual bool         create ( CAM_Study* );
+  virtual bool         dumpPython( const QString&,
+                                  CAM_Study*,
+                                  bool,
+                                  QStringList& );
+  
+  virtual bool         isModified () const;
+  void                 setModified( bool );
+  
+  virtual void         update ( LightApp_DataObject* = 0, LightApp_Study* = 0 );
+
+  CAM_DataObject*      getRoot();
+
+ private:
+  QString              myFileName;
+  QString              myStudyURL;
+  bool                 myModified;
+};
+
+#endif // SALOME_PYQT_DATAMODELLIGHT_H
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx
new file mode 100644 (file)
index 0000000..11ba2f8
--- /dev/null
@@ -0,0 +1,177 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+//  Date   : 22/06/2007
+//
+#include "SALOME_PYQT_DataObjectLight.h"
+#include <LightApp_Application.h>
+#include <SUIT_Session.h>
+#include <utilities.h>
+#include <SUIT_ResourceMgr.h>
+
+
+#include <CAM_DataModel.h>
+#include <CAM_Module.h>
+
+
+/*!
+ *  Class:       SALOME_PYQT_DataObjectLight
+ *  Description: LIGHT PYTHON module's data object
+ */
+
+static int _ID = 0;
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight()
+// purpose  : constructor
+//=================================================================================
+SALOME_PYQT_DataObjectLight::SALOME_PYQT_DataObjectLight ( SUIT_DataObject* parent )
+  : CAM_DataObject(parent),
+    LightApp_DataObject( parent )
+
+{
+  _ID++;
+  myEntry = QString("PYLIGHT_OBJ_%1").arg(_ID);
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight()
+// purpose  : destructor
+//=================================================================================
+SALOME_PYQT_DataObjectLight::~SALOME_PYQT_DataObjectLight()
+{
+  
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::entry()
+// purpose  : return entry of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::entry() const
+{
+  return myEntry;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::refEntry()
+// purpose  : return entry of the data object referenced by this one (if any)
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::refEntry() const
+{
+  return myRefEntry;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::setRefEntry()
+// purpose  : sets entry of the data object referenced by this one
+//=================================================================================
+void SALOME_PYQT_DataObjectLight::setRefEntry( const QString& refEntry )
+{
+  myRefEntry = refEntry;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::name()
+// purpose  : return name of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::name() const
+{
+  return myName;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::icon()
+// purpose  : return icon of object
+//=================================================================================
+QPixmap SALOME_PYQT_DataObjectLight::icon(const int index) const
+{
+  if(index == NameId)
+    return myIcon;
+  else
+    return LightApp_DataObject::icon( index );
+}
+
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::toolTip()
+// purpose  : return toolTip of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::toolTip(const int index) const
+{
+  return myToolTip;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::toolTip()
+// purpose  : return toolTip of object
+//=================================================================================
+QColor SALOME_PYQT_DataObjectLight::color( const ColorRole role, const int id ) const
+{
+  QColor c;
+
+  switch ( role )
+  {
+  case Text:
+  case Foreground:
+    if ( !isReference() )
+      c = myColor;
+    break;
+
+  default:
+    break;
+  }
+
+  // Issue 21379: LightApp_DataObject::color() defines colors for valid references
+  if ( !c.isValid() )
+    c = LightApp_DataObject::color( role, id );
+
+  return c;
+}
+
+bool SALOME_PYQT_DataObjectLight::setName(const QString& name)
+{
+  myName = name;
+  return true;
+}
+
+void SALOME_PYQT_DataObjectLight::setIcon(const QString& iconname)
+{
+  if(!iconname.isEmpty()) {
+    LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
+    if(anApp) {
+      QString modulename = anApp->activeModule()->name();
+      if(!modulename.isEmpty())
+        {
+          myIcon = SUIT_Session::session()->resourceMgr()->loadPixmap(modulename,
+                                                                      QObject::tr(iconname.toLatin1()));
+        }
+    }
+  }
+}
+
+void SALOME_PYQT_DataObjectLight::setToolTip(const QString& tooltip)
+{
+  myToolTip = tooltip;
+}
+
+void SALOME_PYQT_DataObjectLight::setColor(const QColor& color)
+{
+  myColor = color;
+}
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h
new file mode 100644 (file)
index 0000000..b76e2d8
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+//  Date   : 22/06/2007
+//
+#ifndef SALOME_PYQT_DATAOBJECTLIGHT_H
+#define SALOME_PYQT_DATAOBJECTLIGHT_H
+
+
+#include "SALOME_PYQT_GUILight.h"
+#include <LightApp_DataObject.h>
+#include <LightApp_Study.h>
+
+#include <qstring.h>
+
+/*!
+ * SALOME_PYQT_DataObjectLight - PYTHON LIGHT module's data object class
+ */
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_DataObjectLight : public virtual LightApp_DataObject
+{
+
+ public:
+  SALOME_PYQT_DataObjectLight( SUIT_DataObject* = 0 );
+
+  virtual ~SALOME_PYQT_DataObjectLight();
+  
+  virtual QString    entry() const;
+
+  virtual QString    refEntry() const;
+  void               setRefEntry( const QString& refEntry );
+  
+  virtual QString    name()    const;
+  virtual QPixmap    icon(const int = NameId)    const;
+  virtual QString    toolTip(const int = NameId) const;
+
+  bool               setName(const QString& name);
+  void               setIcon(const QString& icon);
+  void               setToolTip(const QString& tooltip);
+
+  virtual QColor     color( const ColorRole, const int = NameId ) const;
+  void               setColor(const QColor& color);
+
+ private:
+  QString myEntry;
+  QString myRefEntry;
+  QString myName;
+  QString myToolTip;
+  QPixmap myIcon;
+  QColor  myColor;
+}; 
+
+#endif // SALOME_PYQT_DATAOBJECTLIGHT_H
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_GUILight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_GUILight.h
new file mode 100644 (file)
index 0000000..19d5f2d
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File   : SALOME_PYQT_GUI.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+#if !defined ( SALOME_PYQT_GUILIGHT_H )
+#define SALOME_PYQT_GUIILIGHT_H
+
+// ========================================================
+// set dllexport type for Win platform 
+#ifdef WNT
+
+#if defined SALOME_PYQT_LIGHT_EXPORTS || defined SalomePyQtGUILight_EXPORTS
+#define SALOME_PYQT_LIGHT_EXPORT __declspec(dllexport)
+#else
+#define SALOME_PYQT_LIGHT_EXPORT __declspec(dllimport)
+#endif
+
+#else   // WNT
+
+#define SALOME_PYQT_LIGHT_EXPORT
+
+#endif  // WNT
+
+// ========================================================
+// avoid warning messages
+#ifdef WNT
+#pragma warning (disable : 4786)
+#pragma warning (disable : 4251)
+#endif
+
+#endif // SALOME_PYQT_GUIILIGHT_H
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_GUILight.sip b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_GUILight.sip
new file mode 100644 (file)
index 0000000..51264cb
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SALOME_PYQT_GUI.sip
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+%Module SalomePyQtGUILight
+
+%Import QtGuimod.sip
+%Import QtXmlmod.sip
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx
new file mode 100644 (file)
index 0000000..b9a6aa3
--- /dev/null
@@ -0,0 +1,3128 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File   : SALOME_PYQT_Module.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+#include "SALOME_PYQT_PyInterp.h"
+#include <SUITApp_init_python.hxx>
+#include <PyInterp_Interp.h>
+#include <PyConsole_Interp.h>
+#include <PyConsole_Console.h>
+#include <PyInterp_Dispatcher.h>
+
+#include "SALOME_PYQT_ModuleLight.h"
+#include "SALOME_PYQT_DataModelLight.h"
+
+#ifndef GUI_DISABLE_CORBA
+#include <Container_init_python.hxx>
+#endif
+
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_DataObjectIterator.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_ViewModel.h>
+#include <SUIT_ViewWindow.h>
+#include <SUIT_ViewManager.h>
+#include <STD_MDIDesktop.h>
+#include <STD_TabDesktop.h>
+#include <LightApp_Preferences.h>
+#include <LightApp_Application.h>
+#include <LightApp_Study.h>
+
+#include <QtxWorkstack.h>
+#include <QtxWorkspace.h>
+#include <QtxActionGroup.h>
+#include <QtxActionMenuMgr.h>
+#include <QtxActionToolMgr.h>
+
+#include <QFile>
+#include <QDomDocument>
+#include <QDomNode>
+#include <QDomElement>
+#include <QMenuBar>
+#include <QMenu>
+#include <QAction>
+
+#include "sipAPISalomePyQtGUILight.h"
+
+#include <sip.h>
+#if SIP_VERSION < 0x040700
+#include "sipQtGuiQWidget.h"
+#include "sipQtGuiQMenu.h"
+#endif
+
+#include <utilities.h>
+
+/*!
+  \brief Default name of the module, replaced at the moment
+  of module creation.
+  \internal
+*/
+const char* DEFAULT_NAME  = "SALOME_PYQT_ModuleLight";
+
+/*!
+  \brief Default menu group number.
+  \internal
+*/
+const int DEFAULT_GROUP = 40;
+
+/*!
+  \var IsCallOldMethods
+  \brief Allow calling obsolete callback methods.
+  \internal
+  
+  If the macro CALL_OLD_METHODS is not defined, the invoking
+  of obsolete Python module's methods like setSetting(), definePopup(), 
+  etc. is blocked.
+
+  CALL_OLD_METHODS macro can be defined for example by adding 
+  -DCALL_OLD_METHODS compilation option to the Makefile.
+*/
+#ifdef CALL_OLD_METHODS
+const bool IsCallOldMethods = true;
+#else
+const bool IsCallOldMethods = false;
+#endif
+
+/* Py_ssize_t for old Pythons */
+/* This code is as recommended by: */
+/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+# define PY_SSIZE_T_MAX INT_MAX
+# define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+//
+// NB: Python requests.
+// General rule for Python requests created by SALOME_PYQT_Module:
+// all requests should be executed SYNCHRONOUSLY within the main GUI thread.
+// However, it is obligatory that ANY Python call is wrapped with a request object,
+// so that ALL Python API calls are serialized with PyInterp_Dispatcher.
+//
+
+/*!
+  \class SALOME_PYQT_Module::XmlHandler
+  \brief XML resource files parser.
+  \internal
+
+  This class is used to provide backward compatibility with
+  existing Python modules in which obsolete menu definition system
+  (via XML files) is used.
+*/
+
+class SALOME_PYQT_ModuleLight::XmlHandler
+{
+public:
+  XmlHandler( SALOME_PYQT_ModuleLight* module, const QString& fileName );
+  void createActions();
+  void createPopup  ( QMenu*         menu,
+                      const QString& context,
+                      const QString& parent,
+                      const QString& object );
+  void activateMenus( bool );
+
+protected:
+  void createToolBar   ( QDomNode&   parentNode );
+  void createMenu      ( QDomNode&   parentNode,
+                         const int   parentMenuId = -1,
+                         QMenu*      parentPopup = 0 );
+
+  void insertPopupItems( QDomNode&   parentNode,
+                         QMenu*      menu );
+
+private:
+  SALOME_PYQT_ModuleLight* myModule;
+  QDomDocument             myDoc;
+  QList<int>               myMenuItems;
+};
+
+//
+// NB: Library initialization
+// Since the SalomePyQtGUILight library is not imported in Python it's initialization function
+// should be called manually (and only once) in order to initialize global sip data
+// and to get C API from sip : sipBuildResult for example
+//
+
+#define INIT_FUNCTION initSalomePyQtGUILight
+#if defined(SIP_STATIC_MODULE)
+extern "C" void INIT_FUNCTION();
+#else
+PyMODINIT_FUNC INIT_FUNCTION();
+#endif
+
+/*!
+  \fn CAM_Module* createModule()
+  \brief Module factory function.
+  \internal
+  
+  Creates an instance of SALOME_PYQT_Module object by request
+  of an application when the module is loaded and initialized.
+
+  \return new module object
+*/
+
+extern "C" {
+  SALOME_PYQT_LIGHT_EXPORT CAM_Module* createModule() {
+
+    static bool alreadyInitialized = false;
+    if ( !alreadyInitialized ) {
+      // call only once (see comment above) !
+      static PyThreadState *gtstate = 0;
+#ifndef GUI_DISABLE_CORBA
+      if(SUIT_PYTHON::initialized)
+        gtstate = SUIT_PYTHON::_gtstate;
+      else
+        gtstate = KERNEL_PYTHON::_gtstate;
+#else
+      gtstate = SUIT_PYTHON::_gtstate;
+#endif
+      PyEval_RestoreThread( gtstate );
+      INIT_FUNCTION();
+      PyEval_ReleaseThread( gtstate );
+      alreadyInitialized = !alreadyInitialized;
+    }
+    return new SALOME_PYQT_ModuleLight();
+  }
+}
+
+/*!
+  \class FuncMsg
+  \brief Function call in/out tracer.
+  \internal
+*/
+
+class FuncMsg
+{
+public:
+  FuncMsg( const QString& funcName )
+  {
+    myName = funcName;
+    MESSAGE( myName.toLatin1().constData() << " [ begin ]" );
+  }
+  ~FuncMsg()
+  {
+    MESSAGE( myName.toLatin1().constData() << " [ end ]" );
+  }
+  void message( const QString& msg )
+  {
+    MESSAGE( myName.toLatin1().constData() << " : " << msg.toLatin1().constData() );
+  }
+private:
+  QString myName;
+};
+
+/*!
+  \class SALOME_PYQT_ModuleLight
+  \brief This class implements module API for all the Python-based 
+  SALOME modules.
+*/
+
+//
+// Static variables definition
+//
+SALOME_PYQT_ModuleLight::InterpMap SALOME_PYQT_ModuleLight::myInterpMap;
+SALOME_PYQT_ModuleLight* SALOME_PYQT_ModuleLight::myInitModule = 0;
+
+/*!
+  \brief Get the module being initialized.
+  
+  This is a little trick :) needed to provide an access from Python
+  (SalomePyQt) to the module being currently activated. The problem
+  that during the process of module initialization (initialize() 
+  function) it is not yet available via application->activeModule()
+  call.
+  
+  This method returns valid pointer only if called in scope of
+  initialize() function.
+
+  \return the module being currently initialized
+*/
+SALOME_PYQT_ModuleLight* SALOME_PYQT_ModuleLight::getInitModule()
+{
+  return myInitModule;
+}
+
+/*!
+  \brief Constructor
+*/
+SALOME_PYQT_ModuleLight::SALOME_PYQT_ModuleLight()
+: LightApp_Module( DEFAULT_NAME ),
+  myInterp( 0 ),
+  myModule( 0 ), 
+  myXmlHandler ( 0 ),
+  myLastActivateStatus( true )
+{
+}
+
+/*!
+  \brief Destructor
+*/
+SALOME_PYQT_ModuleLight::~SALOME_PYQT_ModuleLight()
+{
+  if ( myXmlHandler )
+    delete myXmlHandler;
+  if ( myInterp && myModule ) {
+    PyLockWrapper aLock = myInterp->GetLockWrapper();
+    Py_XDECREF(myModule);
+  }
+}
+
+/*!
+  \brief Initialization of the module.
+  
+  This method can be used for creation of the menus, toolbars and 
+  other such staff.
+  
+  There are two ways to do this:
+  - for obsolete modules this method first tries to read
+  <module>_<language>.xml resource file which contains a menu,
+  toolbars and popup menus description;
+  - new modules can create menus by direct calling of the
+  corresponding methods of SalomePyQt Python API in the Python
+  module's initialize() method which is called from here.
+
+  NOTE: SALOME supports two modes of modules loading:
+  - immediate (all the modules are created and initialized 
+  immediately when the application object is created;
+  - postponed modules loading (used currently); in this mode
+  the module is loaded only be request.
+  If postponed modules loading is not used, the active
+  study might be not yet defined at this stage, so initialize()
+  method should not perform any study-based initialization.
+
+  \param app parent application object
+*/
+void SALOME_PYQT_ModuleLight::initialize( CAM_Application* app )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initialize()" );
+
+  // call base implementation
+  LightApp_Module::initialize( app );
+
+  // try to get XML resource file name
+  SUIT_ResourceMgr* aResMgr = getApp()->resourceMgr();
+  if ( !myXmlHandler && aResMgr ) {
+    // get current language
+    QString aLang = aResMgr->stringValue( "language", "language", QString() );
+    if ( aLang.isEmpty() ) 
+      aLang = "en";
+    // define resource file name
+    QString aFileName = name() + "_" + aLang + ".xml";
+    aFileName = aResMgr->path( "resources", name(), aFileName );
+    // create XML handler instance
+    if ( !aFileName.isEmpty() && QFile::exists( aFileName ) )
+      myXmlHandler = new SALOME_PYQT_ModuleLight::XmlHandler( this, aFileName );
+    // create menus & toolbars from XML file if required
+    if ( myXmlHandler )
+      myXmlHandler->createActions();
+  }
+
+  // perform internal initialization and call module's initialize() funtion
+  // InitializeReq: request class for internal init() operation
+  class InitializeReq : public PyInterp_Request
+  {
+  public:
+    InitializeReq( CAM_Application*    _app,
+                   SALOME_PYQT_ModuleLight* _obj )
+      : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+        myApp( _app ),
+        myObj( _obj ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->init( myApp );
+    }
+
+  private:
+    CAM_Application*    myApp;
+    SALOME_PYQT_ModuleLight* myObj;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new InitializeReq( app, this ) );
+}
+
+/*!
+  \brief Activation of the module.
+
+  This function is usually used in order to show the module's 
+  specific menus and toolbars, update actions state and perform
+  other such actions required when the module is activated.
+  
+  Note, that returning \c false in this function prevents the 
+  module activation.
+
+  \param theStudy parent study
+  \return \c true if activation is successful and \c false otherwise
+*/
+bool SALOME_PYQT_ModuleLight::activateModule( SUIT_Study* theStudy )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::activateModule()" );
+
+  // call base implementation
+  bool res = LightApp_Module::activateModule( theStudy );
+
+  if ( !res )
+    return res;
+
+  // internal activation
+  return activateModuleInternal( theStudy );
+}
+
+/*!
+  \brief Perform internal activation of the module.
+
+  The only goal of this function is to extract common functionality
+  for LightApp_Module and SalomeApp_module classes requried by the
+  specific architecture aspects of "light" / "full" SALOME modes.
+
+  \sa activateModule()
+*/
+bool SALOME_PYQT_ModuleLight::activateModuleInternal( SUIT_Study* theStudy )
+{
+  // reset the activation status to the default value
+  myLastActivateStatus = true;
+
+  // perform internal activation
+  // ActivateReq: request class for internal activate() operation
+  class ActivateReq : public PyInterp_Request
+  {
+  public:
+    ActivateReq( SUIT_Study*         _study,
+                 SALOME_PYQT_ModuleLight* _obj )
+      : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+        myStudy ( _study ),
+        myObj   ( _obj   ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->activate( myStudy );
+    }
+
+  private:
+    SUIT_Study*         myStudy;
+    SALOME_PYQT_ModuleLight* myObj;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new ActivateReq( theStudy, this ) );
+
+  // check activation status (set by activate())
+  if ( !lastActivationStatus() )
+    return false;
+
+  // activate menus, toolbars, etc
+  if ( myXmlHandler ) myXmlHandler->activateMenus( true );
+  setMenuShown( true );
+  setToolShown( true );
+
+  // connect preferences changing signal
+  connect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
+           this,     SLOT(   preferenceChanged( const QString&, const QString&, const QString& ) ) );
+
+  // perform custom activation actions
+  // CustomizeReq: request class for internal customize() operation
+  class CustomizeReq : public PyInterp_Request
+  {
+  public:
+    CustomizeReq( SUIT_Study*         _study,
+                  SALOME_PYQT_ModuleLight* _obj )
+      : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+        myStudy ( _study ),
+        myObj   ( _obj   ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->customize( myStudy );
+    }
+
+  private:
+    SUIT_Study*         myStudy;
+    SALOME_PYQT_ModuleLight* myObj;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new CustomizeReq( theStudy, this ) );
+
+  return true;
+}
+
+/*!
+  \brief Deactivation of the module.
+
+  This function is usually used in order to hide the module's 
+  specific menus and toolbars and perform other such actions
+  required when the module is deactivated.
+
+  \param theStudy parent study
+  \return \c true if deactivation is successful and \c false otherwise
+*/
+bool SALOME_PYQT_ModuleLight::deactivateModule( SUIT_Study* theStudy )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::deactivateModule()" );
+
+  // disconnect preferences changing signal
+  disconnect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
+              this,     SLOT(   preferenceChanged( const QString&, const QString&, const QString& ) ) );
+
+  // perform internal deactivation
+  // DeactivateReq: request class for internal deactivate() operation
+  class DeactivateReq : public PyInterp_LockRequest
+  {
+  public:
+    DeactivateReq( PyInterp_Interp*    _py_interp,
+                   SUIT_Study*         _study,
+                   SALOME_PYQT_ModuleLight* _obj )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myStudy ( _study ),
+        myObj   ( _obj   ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->deactivate( myStudy );
+    }
+
+  private:
+    SUIT_Study*         myStudy;
+    SALOME_PYQT_ModuleLight* myObj;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new DeactivateReq( myInterp, theStudy, this ) );
+
+  // deactivate menus, toolbars, etc
+  if ( myXmlHandler ) myXmlHandler->activateMenus( false );
+  setMenuShown( false );
+  setToolShown( false );
+
+  // call base implementation
+  return LightApp_Module::deactivateModule( theStudy );
+}
+
+/*!
+ \brief Get last activation status.
+ \return status of last module activation operation
+ \sa activateModule()
+*/
+bool SALOME_PYQT_ModuleLight::lastActivationStatus() const
+{
+  return myLastActivateStatus;
+}
+
+/*!
+  \breif Process application preferences changing.
+
+  Called when any application setting is changed.
+
+  \param module preference module
+  \param section preference resource file section
+  \param setting preference resource name
+*/
+void SALOME_PYQT_ModuleLight::preferenceChanged( const QString& module, 
+                                            const QString& section, 
+                                            const QString& setting )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::preferenceChanged()" );
+
+  // perform synchronous request to Python event dispatcher
+  class Event : public PyInterp_LockRequest
+  {
+  public:
+    Event( PyInterp_Interp*    _py_interp,
+           SALOME_PYQT_ModuleLight* _obj,
+           const QString&      _section,
+           const QString&      _setting )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj    ( _obj ),
+        mySection( _section ),
+        mySetting( _setting ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->prefChanged( mySection, mySetting );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    QString mySection, mySetting;
+  };
+
+  if ( module != moduleName() ) {
+    // module's own preferences are processed by preferencesChanged() method
+    // ...
+    // post the request only if dispatcher is not busy!
+    // execute request synchronously
+    if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+      PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
+  }
+}
+
+/*!
+  \brief Process study activation.
+  
+  Called when study desktop is activated. Used for notifying the Python
+  module about changing of the active study.
+*/
+void SALOME_PYQT_ModuleLight::studyActivated()
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::studyActivated()" );
+
+  // StudyChangedReq: request class for internal studyChanged() operation
+  class StudyChangedReq : public PyInterp_Request
+  {
+  public:
+    StudyChangedReq( SUIT_Study*         _study,
+                     SALOME_PYQT_ModuleLight* _obj )
+      : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+        myStudy ( _study ),
+        myObj   ( _obj   ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->studyChanged( myStudy );
+    }
+
+  private:
+    SUIT_Study*         myStudy;
+    SALOME_PYQT_ModuleLight* myObj;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new StudyChangedReq( application()->activeStudy(), this ) );
+}
+
+/*!
+  \brief Process GUI action (from main menu, toolbar or 
+  context popup menu action).
+*/
+void SALOME_PYQT_ModuleLight::onGUIEvent()
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::onGUIEvent()" );
+
+  // get sender action
+  QAction* action = qobject_cast<QAction*>( sender() );
+  if ( !action )
+    return;
+
+  // get action ID
+  int id = actionId( action );
+  fmsg.message( QString( "action id = %1" ).arg( id ) );
+
+  // perform synchronous request to Python event dispatcher
+  class GUIEvent : public PyInterp_LockRequest
+  {
+  public:
+    GUIEvent( PyInterp_Interp*    _py_interp,
+              SALOME_PYQT_ModuleLight* _obj,
+              int                 _id )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myId    ( _id  ),
+        myObj   ( _obj ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->guiEvent( myId );
+    }
+
+  private:
+    int                 myId;
+    SALOME_PYQT_ModuleLight* myObj;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new GUIEvent( myInterp, this, id ) );
+}
+
+/*!
+  \brief Process context popup menu request.
+  
+  Called when user activates popup menu in some window
+  (view, object browser, etc).
+
+  \param theContext popup menu context (e.g. "ObjectBrowser")
+  \param thePopupMenu popup menu
+  \param title popup menu title (not used)
+*/
+void SALOME_PYQT_ModuleLight::contextMenuPopup( const QString& theContext, 
+                                           QMenu*         thePopupMenu, 
+                                           QString&       /*title*/ )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::contextMenuPopup()" );
+  fmsg.message( QString( "context: %1" ).arg( theContext ) );
+
+  // perform synchronous request to Python event dispatcher
+  class PopupMenuEvent : public PyInterp_LockRequest
+  {
+  public:
+    PopupMenuEvent( PyInterp_Interp*    _py_interp,
+                    SALOME_PYQT_ModuleLight* _obj,
+                    const QString&      _context,
+                    QMenu*        _popup )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myContext( _context ),
+        myPopup  ( _popup  ),
+        myObj    ( _obj )   {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->contextMenu( myContext, myPopup );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    QString             myContext;
+    QMenu*         myPopup;
+  };
+
+  // post request only if dispatcher is not busy!
+  // execute request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new PopupMenuEvent( myInterp, this, theContext, thePopupMenu ) );
+}
+
+/*!
+  \brief Export preferences for the Python module.
+  
+  Called only once when the first instance of the module is created.
+*/
+void SALOME_PYQT_ModuleLight::createPreferences()
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::createPreferences()" );
+
+  // perform synchronous request to Python event dispatcher
+  class Event : public PyInterp_LockRequest
+  {
+  public:
+    Event( PyInterp_Interp*    _py_interp,
+           SALOME_PYQT_ModuleLight* _obj )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj    ( _obj )   {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->initPreferences();
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+  };
+
+  // post request only if dispatcher is not busy!
+  // execute request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this ) );
+}
+
+/*!
+  \brief Define the dockable windows associated with the module.
+  
+  To fill the list of windows the correspondind Python module's windows()
+  method is called from SALOME_PYQT_ModuleLight::init() method.
+
+  By default, ObjectBrowser, PythonConsole and LogWindow windows are 
+  associated to the module.
+
+  Allowed dockable windows:
+  - LightApp_Application::WT_ObjectBrowser : object browser
+  - LightApp_Application::WT_PyConsole : python console
+  - LightApp_Application::WT_LogWindow : log messages output window
+
+  Dock area is defined by Qt::DockWidgetArea enumeration:
+  - Qt::TopDockWidgetArea : top dock area
+  - Qt::BottomDockWidgetArea : bottom dock area
+  - Qt::LeftDockWidgetArea : left dock area
+  - Qt::RightDockWidgetArea : right dock area
+
+  \param mappa map of dockable windows: { <window_type> : <dock_area> }
+*/
+void SALOME_PYQT_ModuleLight::windows( QMap<int, int>& mappa ) const
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::windows()" );
+
+  mappa = myWindowsMap;
+}
+
+/*!
+  \brief Define the compatible view windows associated with the module.
+
+  The associated view windows are opened automatically when the module
+  is activated.
+
+  To fill the list of views the correspondind Python module's views()
+  method is called from SALOME_PYQT_ModuleLight::init() method.
+  By default, the list is empty.
+
+  \param listik list of view windows types
+*/
+void SALOME_PYQT_ModuleLight::viewManagers( QStringList& lst ) const
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::viewManagers()" );
+
+  lst = myViewMgrList;
+}
+
+/*!
+  \brief Process module's preferences changing.
+
+  Called when the module's preferences are changed.
+  
+  \param section setting section
+  \param setting setting name
+*/
+void SALOME_PYQT_ModuleLight::preferencesChanged( const QString& section, const QString& setting )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::preferencesChanged()" );
+
+  // perform synchronous request to Python event dispatcher
+  class Event : public PyInterp_LockRequest
+  {
+  public:
+    Event( PyInterp_Interp*    _py_interp,
+           SALOME_PYQT_ModuleLight* _obj,
+           const QString&      _section,
+           const QString&      _setting )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj    ( _obj ),
+        mySection( _section ),
+        mySetting( _setting ) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->prefChanged( mySection, mySetting );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    QString mySection, mySetting;
+  };
+
+  // post request only if dispatcher is not busy!
+  // execut request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
+}
+
+/*!
+  \brief Internal module initialization:
+
+  Performs the following actions:
+  - initialize or get the Python interpreter (one per study)
+  - import the Python module
+  - pass the workspace widget to the Python module
+  - call Python module's initialize() method
+  - call Python module's windows() method
+  - call Python module's views() method
+
+  \param app parent application object
+*/
+void SALOME_PYQT_ModuleLight::init( CAM_Application* app )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::init()" );
+
+  // reset interpreter to NULL
+  myInterp = NULL;
+
+  // get study Id
+  LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( app );
+  if ( !anApp )
+    return;
+  LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( app->activeStudy() );
+  if ( !aStudy )
+    return;
+  int aStudyId = aStudy ? aStudy->id() : 0;
+
+  // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+  initInterp( aStudyId );
+  if ( !myInterp )
+    return; // Error
+
+  // import Python GUI module
+  importModule();
+  if ( !myModule )
+    return; // Error
+
+  // this module is being activated now!
+  myInitModule = this;
+
+  // then call Python module's initialize() method
+  // ... first get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  // ... (the Python module is already imported)
+  // ... finally call Python module's initialize() method
+  if ( PyObject_HasAttrString( myModule, (char*)"initialize" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"initialize", (char*)"" ) );
+    if ( !res ) {
+      PyErr_Print();
+    }
+  }
+
+  // get required dockable windows list from the Python module 
+  // by calling windows() method
+  // ... first put default values
+  myWindowsMap.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+  myWindowsMap.insert( LightApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
+  myWindowsMap.insert( LightApp_Application::WT_LogWindow,     Qt::BottomDockWidgetArea );
+
+  if ( PyObject_HasAttrString( myModule , (char*)"windows" ) ) {
+    PyObjWrapper res1( PyObject_CallMethod( myModule, (char*)"windows", (char*)"" ) );
+    if ( !res1 ) {
+      PyErr_Print();
+    }
+    else {
+      myWindowsMap.clear();
+      if ( PyDict_Check( res1 ) ) {
+        PyObject* key;
+        PyObject* value;
+        Py_ssize_t pos = 0;
+        while ( PyDict_Next( res1, &pos, &key, &value ) ) {
+          // parse the return value
+          // it should be a map: {integer:integer}
+          int aKey, aValue;
+          if( key && PyInt_Check( key ) && value && PyInt_Check( value ) ) {
+            aKey   = PyInt_AsLong( key );
+            aValue = PyInt_AsLong( value );
+            myWindowsMap[ aKey ] = aValue;
+          }
+        }
+      }
+    }
+  }
+
+  // get compatible view windows types from the Python module 
+  // by calling views() method
+  if ( PyObject_HasAttrString( myModule , (char*)"views" ) ) {
+    PyObjWrapper res2( PyObject_CallMethod( myModule, (char*)"views", (char*)"" ) );
+    if ( !res2 ) {
+      PyErr_Print();
+    }
+    else {
+      // parse the return value
+      // result can be one string...
+      if ( PyString_Check( res2 ) ) {
+        myViewMgrList.append( PyString_AsString( res2 ) );
+      }
+      // ... or list of strings
+      else if ( PyList_Check( res2 ) ) {
+        int size = PyList_Size( res2 );
+        for ( int i = 0; i < size; i++ ) {
+          PyObject* value = PyList_GetItem( res2, i );
+          if( value && PyString_Check( value ) ) {
+            myViewMgrList.append( PyString_AsString( value ) );
+          }
+        }
+      }
+    }
+  }
+  // module is already activated!
+  myInitModule = 0;
+}
+
+/*!
+  \brief Internal activation:
+
+  Performs the following actions:
+  - initialize or get the Python interpreter (one per study)
+  - import the Python GUI module
+  - call Python module's activate() method
+
+  \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::activate( SUIT_Study* theStudy )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::activate()" );
+
+  // get study Id
+  LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+  int aStudyId = aStudy ? aStudy->id() : 0;
+
+  // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+  initInterp( aStudyId );
+  if ( !myInterp ) {
+    myLastActivateStatus = false;
+    return; // Error
+  }
+
+  // import Python GUI module
+  importModule();
+  if ( !myModule ) {
+    myLastActivateStatus = false;
+    return; // Error
+  }
+
+  // get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+  // call Python module's activate() method (for the new modules)
+  if ( PyObject_HasAttrString( myModule , (char*)"activate" ) ) {
+    PyObject* res1 = PyObject_CallMethod( myModule, (char*)"activate", (char*)"" );
+    if ( !res1 || !PyBool_Check( res1 ) ) {
+      PyErr_Print();
+      // always true for old modules (no return value)
+      myLastActivateStatus = true;
+    }
+    else {
+      // detect return status
+      myLastActivateStatus = PyObject_IsTrue( res1 );
+    }
+  } 
+  
+  // Connect the SUIT_Desktop signal windowActivated() to this->onActiveViewChanged()
+  SUIT_Desktop* aDesk = theStudy->application()->desktop();
+  if ( aDesk )
+  {
+    connect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+             this,  SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );
+    // If a active window exists send activeViewChanged
+    // If a getActiveView() in SalomePyQt available we no longer need this 
+    SUIT_ViewWindow* aView = aDesk->activeWindow();
+    if ( aView ) 
+      activeViewChanged( aView );
+    
+    // get all view currently opened in the study and connect their signals  to 
+    // the corresponding slots of the class.
+    QList<SUIT_ViewWindow*> wndList = aDesk->windows();
+    SUIT_ViewWindow* wnd;
+    foreach ( wnd, wndList )
+      connectView( wnd );
+  }
+}
+
+/*!
+  \brief Additional customization after module is activated:
+
+  Performs the following actions:
+  - get the Python interpreter (one per study)
+  - import the Python GUI module
+  - call Python module's setSettings() method (obsolete function, 
+  used for compatibility with old code)
+
+  \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::customize( SUIT_Study* theStudy )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::customize()" );
+
+  // get study Id
+  LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+  int aStudyId = aStudy ? aStudy->id() : 0;
+
+  // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+  initInterp( aStudyId );
+  if ( !myInterp )
+    return; // Error
+
+  // import Python GUI module
+  importModule();
+  if ( !myModule )
+    return; // Error
+
+  if ( IsCallOldMethods ) {
+    // call Python module's setWorkspace() method
+    setWorkSpace();
+  }
+
+  // get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+  if ( IsCallOldMethods ) {
+    // call Python module's setSettings() method (obsolete)
+    if ( PyObject_HasAttrString( myModule , (char*)"setSettings" ) ) {
+      PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setSettings", (char*)"" ) );
+      if( !res ) {
+        PyErr_Print();
+      }
+    }
+  }
+}
+
+/*!
+  \brief Internal deactivation:
+
+  Performs the following actions:
+  - call Python module's deactivate() method
+
+  \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::deactivate( SUIT_Study* theStudy )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::deactivate()" );
+
+  // check if the subinterpreter is initialized and Python module is imported
+  if ( !myInterp || !myModule ) {
+    // Error! Python subinterpreter should be initialized and module should be imported first!
+    return;
+  }
+  // then call Python module's deactivate() method
+  if ( PyObject_HasAttrString( myModule , (char*)"deactivate" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"deactivate", (char*)"" ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+  
+  // Disconnect the SUIT_Desktop signal windowActivated()
+  SUIT_Desktop* aDesk = theStudy->application()->desktop();
+  if ( aDesk )
+  {
+    disconnect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+                this,  SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );      
+  }
+}
+
+/*!
+  \brief Perform internal actions when active study is changed.
+
+  Called when active the study is actived (user brings its 
+  desktop to top):
+  - initialize or get the Python interpreter (one per study)
+  - import the Python GUI module
+  - call Python module's activeStudyChanged() method
+
+  \param theStudy study being activated
+*/
+void SALOME_PYQT_ModuleLight::studyChanged( SUIT_Study* theStudy )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::studyChanged()" );
+
+  // get study Id
+  LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+  int aStudyId = aStudy ? aStudy->id() : 0;
+
+  // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+  initInterp( aStudyId );
+  if ( !myInterp )
+    return; // Error
+
+  // import Python GUI module
+  importModule();
+  if ( !myModule )
+    return; // Error
+
+  if ( IsCallOldMethods ) {
+    // call Python module's setWorkspace() method
+    setWorkSpace();
+  }
+
+  // get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+  // call Python module's activeStudyChanged() method
+  if ( PyObject_HasAttrString( myModule, (char*)"activeStudyChanged" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeStudyChanged", (char*)"i", aStudyId ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+  \brief Process (internally) context popup menu request.
+
+  Performs the following actions:
+  - calls Python module's definePopup(...) method (obsolete function, 
+  used for compatibility with old code) to define the popup menu context
+  - parses XML resourses file (if exists) and fills the popup menu with the items)
+  - calls Python module's customPopup(...) method (obsolete function, 
+  used for compatibility with old code) to allow module to customize the popup menu
+  - for new modules calls createPopupMenu() function to allow the 
+  modules to build the popup menu by using insertItem(...) Qt functions.
+
+  \param theContext popup menu context
+  \param thePopupMenu popup menu
+*/
+void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* thePopupMenu )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::contextMenu()" );
+
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule )
+    return;
+
+  QString aContext( "" ), aObject( "" ), aParent( theContext );
+
+  if ( IsCallOldMethods && PyObject_HasAttrString( myModule, (char*)"definePopup" ) ) {
+    // call definePopup() Python module's function
+    // this is obsolete function, used only for compatibility reasons
+    PyObjWrapper res( PyObject_CallMethod( myModule,
+                                           (char*)"definePopup",
+                                           (char*)"sss",
+                                           theContext.toLatin1().constData(),
+                                           aObject.toLatin1().constData(),
+                                           aParent.toLatin1().constData() ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+    else {
+      // parse return value
+      char *co, *ob, *pa;
+      if( PyArg_ParseTuple( res, "sss", &co, &ob, &pa ) ) {
+        aContext = co;
+        aObject  = ob;
+        aParent  = pa;
+      }
+    }
+  } // if ( IsCallOldMethods ... )
+
+  // first try to create menu via XML parser:
+  // we create popup menus without help of QtxPopupMgr
+  if ( myXmlHandler )
+    myXmlHandler->createPopup( thePopupMenu, aContext, aParent, aObject );
+
+#if SIP_VERSION < 0x040800
+  PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QMenu) );
+#else
+  PyObjWrapper sipPopup( sipBuildResult( 0, "D", thePopupMenu, sipType_QMenu, NULL) );
+#endif
+
+  // then call Python module's createPopupMenu() method (for new modules)
+  if ( PyObject_HasAttrString( myModule, (char*)"createPopupMenu" ) ) {
+    PyObjWrapper res1( PyObject_CallMethod( myModule,
+                                            (char*)"createPopupMenu",
+                                            (char*)"Os",
+                                            sipPopup.get(),
+                                            theContext.toLatin1().constData() ) );
+    if( !res1 ) {
+      PyErr_Print();
+    }
+  }
+
+  if ( IsCallOldMethods && PyObject_HasAttrString( myModule, (char*)"customPopup" ) ) {
+    // call customPopup() Python module's function
+    // this is obsolete function, used only for compatibility reasons
+    PyObjWrapper res2( PyObject_CallMethod( myModule,
+                                            (char*)"customPopup",
+                                            (char*)"Osss",
+                                            sipPopup.get(),
+                                            aContext.toLatin1().constData(),
+                                            aObject.toLatin1().constData(),
+                                            aParent.toLatin1().constData() ) );
+    if( !res2 ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+  \brief Internal GUI event handling.
+
+  Performs the following actions:
+  - calls Python module's OnGUIEvent() method
+
+  \param theId GUI action ID
+*/
+void SALOME_PYQT_ModuleLight::guiEvent( const int theId )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::guiEvent()" );
+
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule )
+    return;
+
+  if ( PyObject_HasAttrString( myModule, (char*)"OnGUIEvent" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"OnGUIEvent", (char*)"i", theId ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+  \brief Initialize (internally) preferences for the module.
+
+  Performs the following actions:
+  - calls Python module's createPreferences() method
+*/
+void SALOME_PYQT_ModuleLight::initPreferences()
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initPreferences()" );
+
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule )
+    return;
+
+  // temporary set myInitModule because createPreferences() method
+  // might be called during the module intialization process
+  myInitModule = this;
+
+  if ( PyObject_HasAttrString( myModule, (char*)"createPreferences" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"createPreferences", (char*)"" ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+
+  myInitModule = 0;
+}
+
+/*!
+  \brief Initialize python subinterpreter (one per study).
+  \param theStudyId study ID
+*/
+void SALOME_PYQT_ModuleLight::initInterp( int theStudyId )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initInterp()" );
+
+  // check study Id
+  if ( !theStudyId ) {
+    // Error! Study Id must not be 0!
+    myInterp = NULL;
+    return;
+  }
+  // try to find the subinterpreter
+  if( myInterpMap.contains( theStudyId ) ) {
+    // found!
+    myInterp = myInterpMap[ theStudyId ];
+    return;
+  }
+
+  myInterp = new SALOME_PYQT_PyInterp();
+  if(!myInterp)
+    return;
+  
+  myInterp->initialize();
+  myInterpMap[ theStudyId ] = myInterp;
+  
+#ifndef GUI_DISABLE_CORBA
+  if(!SUIT_PYTHON::initialized) {
+    // import 'salome' module and call 'salome_init' method;
+    // do it only once on interpreter creation
+    // ... first get python lock
+    PyLockWrapper aLock = myInterp->GetLockWrapper();
+    // ... then import a module
+    PyObjWrapper aMod = PyImport_ImportModule( "salome" );
+    if( !aMod ) {
+      // Error!
+      PyErr_Print();
+      return;
+    }
+    // ... then call a method
+    int embedded = 1;
+    PyObjWrapper aRes( PyObject_CallMethod( aMod, (char*)"salome_init", (char*)"ii", theStudyId, embedded ) );
+    if( !aRes ) {
+      // Error!
+      PyErr_Print();
+      return;
+    }
+  }
+#endif 
+}
+
+/*!
+  \brief Import Python GUI module and remember the reference to the module.
+
+  Attention! initInterp() should be called first!!!
+*/
+void SALOME_PYQT_ModuleLight::importModule()
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::importModule()" );
+
+  // check if the subinterpreter is initialized
+  if ( !myInterp ) {
+    // Error! Python subinterpreter should be initialized first!
+    myModule = 0;
+    return;
+  }
+  // import Python GUI module and puts it in <myModule> attribute
+  // ... first get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  // ... then import a module
+  QString aMod = name() + "GUI";
+  try {
+    myModule = PyImport_ImportModule( aMod.toLatin1().data() );
+  }
+  catch (...) {
+  }
+  if( !myModule ) {
+    // Error!
+    PyErr_Print();
+    return;
+  }
+}
+
+/*!
+  \brief Set study workspace to the Python module.
+
+  Calls setWorkSpace() method of the Pythohn module with 
+  PyQt QWidget object to use with interpreter.
+
+  Attention! initInterp() and importModule() should be called first!!!
+*/
+void SALOME_PYQT_ModuleLight::setWorkSpace()
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::setWorkSpace()" );
+
+  // check if the subinterpreter is initialized and Python module is imported
+  if ( !myInterp || !myModule ) {
+    // Error! Python subinterpreter should be initialized and module should be imported first!
+    return;
+  }
+
+  // call setWorkspace() method
+  // ... first get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+  // ... then try to import SalomePyQt module. If it's not possible don't go on.
+  PyObjWrapper aQtModule( PyImport_ImportModule( "SalomePyQt" ) );
+  if( !aQtModule ) {
+    // Error!
+    PyErr_Print();
+    return;
+  }
+
+  if ( IsCallOldMethods ) {
+    // ... then get workspace object
+    QWidget* aWorkspace = 0;
+    if ( getApp()->desktop()->inherits( "STD_MDIDesktop" ) ) {
+      STD_MDIDesktop* aDesktop = dynamic_cast<STD_MDIDesktop*>( getApp()->desktop() );
+      if ( aDesktop )
+        aWorkspace = aDesktop->workspace();
+    }
+    else if ( getApp()->desktop()->inherits( "STD_TabDesktop" ) ) {
+      STD_TabDesktop* aDesktop = dynamic_cast<STD_TabDesktop*>( getApp()->desktop() );
+      if ( aDesktop )
+        aWorkspace = aDesktop->workstack();
+    }
+#if SIP_VERSION < 0x040800
+    PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget) );
+#else
+    PyObjWrapper pyws( sipBuildResult( 0, "D", aWorkspace, sipType_QWidget , NULL) );
+#endif
+    // ... and finally call Python module's setWorkspace() method (obsolete)
+    if ( PyObject_HasAttrString( myModule, (char*)"setWorkSpace" ) ) {
+      PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setWorkSpace", (char*)"O", pyws.get() ) );
+      if( !res ) {
+        PyErr_Print();
+      }
+    }
+  }
+}
+
+/*!
+  \brief Preference changing callback function (internal).
+
+  Performs the following actions:
+  - call Python module's preferenceChanged() method
+
+  \param section setting section name
+  \param setting setting name
+*/
+void SALOME_PYQT_ModuleLight::prefChanged( const QString& section, const QString& setting )
+{
+  FuncMsg fmsg( "SALOME_PYQT_ModuleLight::prefChanged()" );
+
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule )
+    return;
+
+  if ( PyObject_HasAttrString( myModule, (char*)"preferenceChanged" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule,
+                                           (char*)"preferenceChanged", 
+                                           (char*)"ss", 
+                                           section.toLatin1().constData(), 
+                                           setting.toLatin1().constData() ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+  \brief Get default menu group identifier
+  \return menu group ID (40 by default)
+*/
+int SALOME_PYQT_ModuleLight::defaultMenuGroup()
+{
+  return DEFAULT_GROUP; 
+}
+
+//
+// The next methods call the parent implementation.
+// This is done to open protected methods from CAM_Module class.
+//
+
+/*!
+  \brief Create toolbar with specified \a name.
+  \param name toolbar name
+  \return toolbar ID or -1 if toolbar creation is failed
+*/
+int SALOME_PYQT_ModuleLight::createTool( const QString& name )
+{
+  return LightApp_Module::createTool( name );
+}
+
+/*! 
+  \brief Insert action with specified \a id to the toolbar.
+  \param id action ID
+  \param tBar toolbar ID
+  \param idx required index in the toolbar
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( const int id, const int tBar, const int idx )
+{
+  return LightApp_Module::createTool( id, tBar, idx );
+}
+
+/*!
+  \brief Insert action with specified \a id to the toolbar.
+  \param id action ID
+  \param tBar toolbar name
+  \param idx required index in the toolbar
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( const int id, const QString& tBar, const int idx )
+{
+  return LightApp_Module::createTool( id, tBar, idx );
+}
+
+/*!
+  \brief Insert action to the toolbar.
+  \param a action
+  \param tBar toolbar ID
+  \param id required action ID
+  \param idx required index in the toolbar
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( QAction* a, const int tBar, const int id, const int idx )
+{
+  return LightApp_Module::createTool( a, tBar, id, idx );
+}
+
+/*!
+  \brief Insert action to the toolbar.
+  \param a action
+  \param tBar toolbar name
+  \param id required action ID
+  \param idx required index in the toolbar
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( QAction* a, const QString& tBar, const int id, const int idx )
+{
+  return LightApp_Module::createTool( a, tBar, id, idx );
+}
+
+/*!
+  \brief Create main menu.
+  \param subMenu menu name
+  \param menu parent menu ID
+  \param id required menu ID
+  \param group menu group ID
+  \param idx required index in the menu
+  \return menu ID or -1 if menu could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const QString& subMenu, const int menu, const int id, const int group, const int idx )
+{
+  return LightApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+
+/*!
+  \brief Create main menu.
+  \param subMenu menu name
+  \param menu parent menu name (list of menu names separated by "|")
+  \param id required menu ID
+  \param group menu group ID
+  \param idx required index in the menu
+  \return menu ID or -1 if menu could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const QString& subMenu, const QString& menu, const int id, const int group, const int idx )
+{
+  return LightApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+
+/*!
+  \brief Insert action to the main menu.
+  \param id action ID
+  \param menu parent menu ID
+  \param group menu group ID
+  \param idx required index in the menu
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const int id, const int menu, const int group, const int idx )
+{
+  return LightApp_Module::createMenu( id, menu, group, idx );
+}
+
+/*!
+  \brief Insert action to the main menu.
+  \param id action ID
+  \param menu parent menu name (list of menu names separated by "|")
+  \param group menu group ID
+  \param idx required index in the menu
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const int id, const QString& menu, const int group, const int idx )
+{
+  return LightApp_Module::createMenu( id, menu, group, idx );
+}
+
+/*!
+  \brief Insert action to the main menu.
+  \param a action
+  \param menu parent menu ID
+  \param group menu group ID
+  \param idx required index in the menu
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
+{
+  return LightApp_Module::createMenu( a, menu, id, group, idx );
+}
+
+/*!
+  \brief Insert action to the main menu.
+  \param a action
+  \param menu parent menu name (list of menu names separated by "|")
+  \param group menu group ID
+  \param idx required index in the menu
+  \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
+{
+  return LightApp_Module::createMenu( a, menu, id, group, idx );
+}
+
+/*!
+  \brief Create separator action which can be used in the menu or toolbar.
+  \return new separator action
+*/
+QAction* SALOME_PYQT_ModuleLight::separator()
+{
+  return LightApp_Module::separator();
+}
+
+/*!
+  \brief Get action by specified \a id.
+  \return action or 0 if it is not found
+*/
+QAction* SALOME_PYQT_ModuleLight::action( const int id ) const
+{
+  QAction* a = LightApp_Module::action( id );
+  if ( !a ) {
+    // try menu
+    QMenu* m = menuMgr()->findMenu( id );
+    if ( m ) a = m->menuAction();
+  }
+  return a;
+}
+
+/*!
+  \brief Get action identifier.
+  \return action ID or -1 if action is not registered
+*/
+int SALOME_PYQT_ModuleLight::actionId( const QAction* a ) const
+{
+  return LightApp_Module::actionId( a );
+}
+
+/*!
+  \brief Create new action.
+  
+  If the action with specified identifier already registered
+  it is not created, but its attributes are only modified.
+
+  \param id action ID
+  \param text tooltip text
+  \param icon icon
+  \param menu menu text
+  \param tip status tip
+  \param key keyboard shortcut
+  \param toggle \c true for checkable action
+  \return created action
+*/
+QAction* SALOME_PYQT_ModuleLight::createAction( const int id, const QString& text, const QString& icon,
+                                           const QString& menu, const QString& tip, const int key,
+                                           const bool toggle, QObject* parent )
+{
+  QIcon anIcon = loadIcon( icon );
+  QAction* a = action( id );
+  if ( a ) {
+    if ( a->toolTip().isEmpty()   && !text.isEmpty() )  a->setToolTip( text );
+    if ( a->text().isEmpty()      && !menu.isEmpty() )  a->setText( menu );
+    if ( a->icon().isNull()       && !anIcon.isNull() ) a->setIcon( anIcon );
+    if ( a->statusTip().isEmpty() && !tip.isEmpty() )   a->setStatusTip( tip );
+    if ( a->shortcut().isEmpty()  && key )              a->setShortcut( key );
+    if ( a->isCheckable() != toggle )                   a->setCheckable( toggle );
+    disconnect( a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
+    connect(    a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
+  }
+  else {
+    a = LightApp_Module::createAction( id, 
+                                        text, 
+                                        anIcon, 
+                                        menu, 
+                                        tip, 
+                                        key, 
+                                        parent ? parent : this, 
+                                        toggle, 
+                                        this, 
+                                        SLOT( onGUIEvent() ) );
+  }
+  return a;
+}
+
+/*!
+  \brief Create new action group.
+  
+  If the action with specified identifier already registered
+  it is not created, but its attributes are only modified.
+
+  \param id action ID
+  \param text tooltip text
+  \param icon icon
+  \param menu menu text
+  \param tip status tip
+  \param key keyboard shortcut
+  \param toggle \c true for checkable action
+  \return created action
+*/
+QtxActionGroup* SALOME_PYQT_ModuleLight::createActionGroup(const int id, const bool exclusive)
+{
+  QtxActionGroup* a = qobject_cast<QtxActionGroup*>( action( id ) );
+  if ( !a ) {
+    a = new QtxActionGroup( this );
+    LightApp_Module::registerAction( id, a );
+  }
+  a->setExclusive( exclusive );
+  return a;
+}
+
+/*! 
+  \brief Load icon from resource file.
+  \param fileName icon file name
+  \return icon (null icon if loading failed)
+*/
+QIcon SALOME_PYQT_ModuleLight::loadIcon( const QString& fileName )
+{
+  QIcon anIcon;
+  if ( !fileName.isEmpty() ) {
+    QPixmap pixmap = getApp()->resourceMgr()->loadPixmap( name(), tr( fileName.toLatin1() ) );
+    if ( !pixmap.isNull() )
+      anIcon = QIcon( pixmap );
+  }
+  return anIcon;
+}
+
+/*!
+  \brief Add global application preference (for example, 
+  application specific section).
+  \param label preference name
+  \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addGlobalPreference( const QString& label )
+{
+  LightApp_Preferences* pref = preferences();
+  if ( !pref )
+    return -1;
+
+  return pref->addPreference( label, -1 );
+}
+
+/*!
+  \brief Add preference.
+  \param label preference name
+  \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addPreference( const QString& label )
+{
+  return LightApp_Module::addPreference( label );
+}
+                                       
+/*!
+  \brief Add preference.
+  \param label preference name
+  \param pId parent preference ID
+  \param type preference type
+  \param section resource file section name
+  \param param resource file setting name
+  \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addPreference( const QString& label, 
+                                       const int pId, const int type,
+                                       const QString& section,
+                                       const QString& param )
+{
+  return LightApp_Module::addPreference( label, pId, type, section, param );
+}
+
+/*!
+  \brief Get the preference property.
+  \param id preference ID
+  \param prop property name
+  \return property value (invalid QVariant() if property is not found)
+*/
+QVariant SALOME_PYQT_ModuleLight::preferenceProperty( const int id, 
+                                                 const QString& prop ) const
+{
+  QVariant v = LightApp_Module::preferenceProperty( id, prop );
+  return v;
+}
+
+/*!
+  \brief Set the preference property.
+  \param id preference ID
+  \param prop property name
+  \param var property value
+*/
+void SALOME_PYQT_ModuleLight::setPreferenceProperty( const int id, 
+                                                const QString& prop, 
+                                                const QVariant& var )
+{
+  LightApp_Module::setPreferenceProperty( id, prop, var );
+}
+
+
+/*!
+  \brief Signal handler windowActivated(SUIT_ViewWindow*) of SUIT_Desktop
+  \param pview view being activated
+*/
+void SALOME_PYQT_ModuleLight::onActiveViewChanged( SUIT_ViewWindow* pview )
+{
+  class ActiveViewChange : public PyInterp_LockRequest
+  {
+  public:
+    ActiveViewChange( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+      : PyInterp_LockRequest( _py_interp, 0, true ),
+        myObj(_obj),myView(_pview) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->activeViewChanged( myView );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    const SUIT_ViewWindow * myView;
+  };
+  
+  PyInterp_Dispatcher::Get()->Exec( new ActiveViewChange( myInterp, this, pview ) ); 
+}
+
+/*!
+  \brief Processes the view changing, calls Python module's activeViewChanged() method 
+  \param pview view being activated
+*/
+void SALOME_PYQT_ModuleLight::activeViewChanged( const SUIT_ViewWindow* pview )
+{
+  if ( !myInterp || !myModule ) 
+    return;
+  
+  // Do not use SUIT_ViewWindow::closing() signal here. View manager reacts on 
+  // this signal and deletes view. So our slot does not works if it is connected 
+  // on this signal. SUIT_ViewManager::deleteView(SUIT_ViewWindow*) is used here
+  
+  connectView( pview );
+
+  if ( PyObject_HasAttrString( myModule, (char*)"activeViewChanged" ) ) 
+  {
+    if ( !pview ) 
+      return;   
+
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeViewChanged", (char*)"i" , pview->getId() ) );
+    if( !res )
+      PyErr_Print();
+  }
+}
+
+/*!
+  \brief Signal handler cloneView() of OCCViewer_ViewWindow
+  \param pview view being cloned
+*/
+void SALOME_PYQT_ModuleLight::onViewCloned( SUIT_ViewWindow* pview )
+{
+  class ViewClone : public PyInterp_LockRequest
+  {
+  public:
+    ViewClone( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+      : PyInterp_LockRequest( _py_interp, 0, true ),
+        myObj(_obj), myView(_pview) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->viewCloned( myView );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;    
+    const SUIT_ViewWindow* myView;
+  };
+  
+  PyInterp_Dispatcher::Get()->Exec( new ViewClone( myInterp, this, pview ) );
+}
+
+/*!
+  \brief Processes the view cloning, calls Python module's activeViewCloned() method
+  \param pview view being cloned
+*/
+void SALOME_PYQT_ModuleLight::viewCloned( const SUIT_ViewWindow* pview )
+{
+  if ( !myInterp || !myModule || !pview ) 
+    return;  
+
+  if ( PyObject_HasAttrString( myModule, (char*)"viewCloned" ) ) 
+  {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewCloned", (char*)"i", pview->getId() ) );
+    if( !res )
+      PyErr_Print();
+  }
+}
+
+/*!
+  \brief Signal handler tryClose(SUIT_ViewWindow*) of a view
+  \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::onViewTryClose( SUIT_ViewWindow* pview )
+{
+  class ViewTryClose : public PyInterp_LockRequest
+  {
+  public:
+    ViewTryClose( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+      : PyInterp_LockRequest( _py_interp, 0, true ),
+        myObj(_obj),myView(_pview) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->viewTryClose( myView );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    const SUIT_ViewWindow * myView;    
+  };
+
+  PyInterp_Dispatcher::Get()->Exec( new ViewTryClose( myInterp, this, pview ) );
+}
+
+/*!
+  \brief Processes the view closing attempt, calls Python module's viewTryClose() method
+  \param pview view user tries to close
+*/
+void SALOME_PYQT_ModuleLight::viewTryClose( const SUIT_ViewWindow* pview )
+{
+  if ( !myInterp || !myModule ) 
+    return;  
+
+  if ( PyObject_HasAttrString( myModule, (char*)"viewTryClose" ) ) 
+  {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewTryClose", (char*)"i", pview->getId() ) );
+    if ( !res )
+    {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+  \brief Signal handler closing(SUIT_ViewWindow*) of a view
+  \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::onViewClosed( SUIT_ViewWindow* pview )
+{
+  class ViewClose : public PyInterp_LockRequest
+  {
+  public:
+    ViewClose( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+      : PyInterp_LockRequest( _py_interp, 0, true ),
+        myObj(_obj),myView(_pview) {}
+
+  protected:
+    virtual void execute()
+    {
+      myObj->viewClosed( myView );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    const SUIT_ViewWindow * myView;    
+  };
+
+  PyInterp_Dispatcher::Get()->Exec( new ViewClose( myInterp, this, pview ) );
+}
+
+/*!
+  \brief Processes the view closing, calls Python module's viewClosed() method
+  \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::viewClosed( const SUIT_ViewWindow* pview )
+{
+  if ( !myInterp || !myModule ) 
+    return;  
+
+  if ( PyObject_HasAttrString( myModule, (char*)"viewClosed" ) ) 
+  {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewClosed", (char*)"i", pview->getId() ) );
+    if ( !res )
+    {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+  \brief Connects or disconnects signals about activating and cloning view on the module slots
+  \param pview view which is connected/disconnected
+*/
+void SALOME_PYQT_ModuleLight::connectView( const SUIT_ViewWindow* pview )
+{
+  SUIT_ViewManager* viewMgr = pview->getViewManager();
+  SUIT_ViewModel* viewModel = viewMgr ? viewMgr->getViewModel() : 0;
+      
+  if ( viewMgr )
+  {
+    disconnect( viewMgr, SIGNAL( tryCloseView( SUIT_ViewWindow* ) ),
+               this, SLOT( onViewTryClose( SUIT_ViewWindow* ) ) );
+    disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+               this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+  
+    connect( viewMgr, SIGNAL( tryCloseView( SUIT_ViewWindow* ) ),
+            this, SLOT( onViewTryClose( SUIT_ViewWindow* ) ) );
+    connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+             this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+  }
+  
+  // Connect cloneView() signal of an OCC View
+  if ( pview->inherits( "OCCViewer_ViewWindow" ) )
+  {
+    disconnect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ), 
+                this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+    connect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ), 
+             this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+  }
+  // Connect cloneView() signal of Plot2d View manager
+  else if ( viewModel && viewModel->inherits( "Plot2d_Viewer" ) )
+  {
+    disconnect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ), 
+                this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+    connect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ), 
+             this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+  }
+}
+
+/*!
+  \brief Get tag name for the DOM element.
+  \param element DOM element
+  \return empty string if the element does not have tag name
+  \internal
+*/
+static QString tagName( const QDomElement& element )
+{
+  return element.tagName().trimmed();
+}
+
+/*!
+  \brief Get DOM element's attribute by its name.
+  \param element DOM element
+  \param attName attribute name
+  \return empty string if the element does not have such attribute
+  \internal
+*/
+static QString attribute( const QDomElement& element, const QString& attName )
+{
+  return element.attribute( attName ).trimmed();
+}
+
+/*!
+  \brief Inspect specified string for the boolean value.
+  
+  This function returns \c true if string represents boolean value: 
+  - "true", "yes" or "1" for \c true
+  - "false", "no" or "0" for \c false
+  Second parameter allows to specify what boolean value is expected:
+  - 1: \c true
+  - 0: \c false
+  - other value is not taken into account (return represented value)
+
+  \param value inspected string
+  \param check expected boolean value
+  \return boolean value represented by the string (\a check is not 1 or 0)
+          or \c true if value correspond to the specified \a check
+*/
+static bool checkBool( const QString& value, const int check = -1 )
+{
+  QString v = value.toLower();
+  if ( ( v == "true"  || v == "yes" || v == "1" ) && ( check != 0 ) )
+    return true;
+  if ( ( v == "false" || v == "no"  || v == "0" ) && ( check == 0 ) )
+    return true;
+  return false;
+}
+
+/*!
+  \brief Inspect specified string for the integer value.
+  
+  This function returns returns -1 if item is empty or represents
+  an invalid number.
+  \param value inspected string
+  \param def default value
+  \param shift shift value (it is added to the integer value to produce shifted result)
+*/
+static int checkInt( const QString& value, const int def = -1, const int shift = -1 )
+{
+  bool bOk;
+  int val = value.toInt( &bOk );
+  if ( !bOk ) val = def;
+  if ( shift > 0 && bOk && val < 0 )
+    val += shift;
+  return val;
+}
+
+/*!
+  \brief Constructor
+  \internal
+  \param module parent module pointer
+  \param fileName XML file path
+*/
+SALOME_PYQT_ModuleLight::XmlHandler::XmlHandler( SALOME_PYQT_ModuleLight* module, 
+                                            const QString&      fileName )
+: myModule( module )
+{
+  if ( fileName.isEmpty() ) 
+    return;
+  QFile aFile( fileName );
+  if ( !aFile.open( QIODevice::ReadOnly ) )
+    return;
+  myDoc.setContent( &aFile );
+  aFile.close();
+}
+
+/*!
+  \brief Parse XML file and create actions.
+  \internal
+  
+  Called by SALOME_PYQT_ModuleLight::activate() in order to create actions
+  (menus, toolbars).
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createActions()
+{
+  // get document element
+  QDomElement aDocElem = myDoc.documentElement();
+
+  // create main menu actions
+  QDomNodeList aMenuList = aDocElem.elementsByTagName( "menu-item" );
+  for ( int i = 0; i < aMenuList.count(); i++ ) {
+    QDomNode n = aMenuList.item( i );
+    createMenu( n );
+  }
+
+  // create toolbars actions
+  QDomNodeList aToolsList = aDocElem.elementsByTagName( "toolbar" );
+  for ( int i = 0; i < aToolsList.count(); i++ ) {
+    QDomNode n = aToolsList.item( i );
+    createToolBar( n );
+  }
+}
+
+/*!
+  \brief Create popup menu.
+  \internal
+  \param menu popup menu
+  \param context popup menu context
+  \param context popup menu parent object name
+  \param context popup menu object name
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createPopup( QMenu*         menu,
+                                                  const QString& context,
+                                                  const QString& parent,
+                                                  const QString& object )
+{
+  // get document element
+  QDomElement aDocElem = myDoc.documentElement();
+
+  // get popup menus actions
+  QDomNodeList aPopupList = aDocElem.elementsByTagName( "popupmenu" );
+  for ( int i = 0; i < aPopupList.count(); i++ ) {
+    QDomNode n = aPopupList.item( i );
+    if ( !n.isNull() && n.isElement() ) {
+      QDomElement e = n.toElement();
+      // QString lab = attribute( e, "label-id" ); // not used // 
+      QString ctx = attribute( e, "context-id" );
+      QString prt = attribute( e, "parent-id"  );
+      QString obj = attribute( e, "object-id"  );
+      if ( ctx == context && prt == parent && obj == object )  {
+        insertPopupItems( n, menu );
+        break;
+      }
+    }
+  }
+}
+
+/*!
+  \brief Activate menus
+  \internal
+  \param enable if \c true menus are activated, otherwise menus are deactivated
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::activateMenus( bool enable )
+{
+  if ( !myModule )
+    return;
+
+  QtxActionMenuMgr* mgr = myModule->menuMgr();
+  int id;
+  foreach( id, myMenuItems ) mgr->setEmptyEnabled( id, enable );
+}
+
+/*!
+  \brief Create main menu item and insert actions to it.
+  \internal
+  \param parentNode XML node with menu description
+  \param parentMenuId parent menu ID (-1 for top-level menu)
+  \param parentPopup parent popup menu (0 for top-level menu)
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createMenu( QDomNode& parentNode, 
+                                                 const int parentMenuId, 
+                                                 QMenu*    parentPopup )
+{
+  if ( !myModule || parentNode.isNull() )
+    return;
+  
+  QDomElement parentElement = parentNode.toElement();
+  if ( !parentElement.isNull() ) {
+    QString plabel = attribute( parentElement, "label-id" );
+    int     pid    = checkInt( attribute( parentElement, "item-id" ) );
+    int     ppos   = checkInt( attribute( parentElement, "pos-id" ) );
+    int     group  = checkInt( attribute( parentElement, "group-id" ), 
+                               myModule->defaultMenuGroup() );
+    if ( !plabel.isEmpty() ) {
+      QMenu* popup = 0;
+      int menuId = -1;
+      // create menu
+      menuId = myModule->createMenu( plabel,         // label
+                                     parentMenuId,   // parent menu ID, -1 for top-level menu
+                                     pid,            // ID
+                                     group,          // group ID
+                                     ppos );         // position
+      myMenuItems.append( menuId );
+      QDomNode node = parentNode.firstChild();
+      while ( !node.isNull() ) {
+        if ( node.isElement() ) {
+          QDomElement elem = node.toElement();
+          QString aTagName = tagName( elem );
+          if ( aTagName == "popup-item" ) {
+            int     id      = checkInt( attribute( elem, "item-id" ) );
+            int     pos     = checkInt( attribute( elem, "pos-id" ) );
+            int     group   = checkInt( attribute( elem, "group-id" ), 
+                                        myModule->defaultMenuGroup() );
+            QString label   = attribute( elem, "label-id" );
+            QString icon    = attribute( elem, "icon-id" );
+            QString tooltip = attribute( elem, "tooltip-id" );
+            QString accel   = attribute( elem, "accel-id" );
+            bool    toggle  = checkBool( attribute( elem, "toggle-id" ) );
+
+            // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+            // also check if the action with given ID is already created
+            if ( id != -1 ) {
+              // create menu action
+              QAction* action = myModule->createAction( id,                     // ID
+                                                        tooltip,                // tooltip
+                                                        icon,                   // icon
+                                                        label,                  // menu text
+                                                        tooltip,                // status-bar text
+                                                        QKeySequence( accel ),  // keyboard accelerator
+                                                        toggle );               // toogled action
+              myModule->createMenu( action,   // action
+                                    menuId,   // parent menu ID
+                                    id,       // ID (same as for createAction())
+                                    group,    // group ID
+                                    pos );    // position
+            }
+          }
+          else if ( aTagName == "submenu" ) {
+            // create sub-menu
+            createMenu( node, menuId, popup );
+          }
+          else if ( aTagName == "separator" ) {
+            // create menu separator
+            int id    = checkInt( attribute( elem, "item-id" ) ); // separator can have ID
+            int pos   = checkInt( attribute( elem, "pos-id" ) );
+            int group = checkInt( attribute( elem, "group-id" ), 
+                                  myModule->defaultMenuGroup() );
+            QAction* action = myModule->separator();
+            myModule->createMenu( action,  // separator action
+                                  menuId,  // parent menu ID
+                                  id,      // ID
+                                  group,   // group ID
+                                  pos );   // position
+          }
+        }
+        node = node.nextSibling();
+      }
+    }
+  }
+}
+
+/*!
+  \brief Create a toolbar and insert actions to it.
+  \param parentNode XML node with toolbar description
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createToolBar( QDomNode& parentNode )
+{
+  if ( !myModule || parentNode.isNull() )
+    return;
+
+  QDomElement parentElement = parentNode.toElement();
+  if ( !parentElement.isNull() ) {
+    QString aLabel = attribute( parentElement, "label-id" );
+    if ( !aLabel.isEmpty() ) {
+      // create toolbar
+      int tbId = myModule->createTool( aLabel );
+      QDomNode node = parentNode.firstChild();
+      while ( !node.isNull() ) {
+        if ( node.isElement() ) {
+          QDomElement elem = node.toElement();
+          QString aTagName = tagName( elem );
+          if ( aTagName == "toolbutton-item" ) {
+            int     id      = checkInt( attribute( elem, "item-id" ) );
+            int     pos     = checkInt( attribute( elem, "pos-id" ) );
+            QString label   = attribute( elem, "label-id" );
+            QString icon    = attribute( elem, "icon-id" );
+            QString tooltip = attribute( elem, "tooltip-id" );
+            QString accel   = attribute( elem, "accel-id" );
+            bool    toggle  = checkBool( attribute( elem, "toggle-id" ) );
+
+            // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+            // also check if the action with given ID is already created
+            if ( id != -1 ) {
+              // create toolbar action
+              QAction* action = myModule->createAction( id,                    // ID
+                                                        tooltip,               // tooltip
+                                                        icon,                  // icon
+                                                        label,                 // menu text
+                                                        tooltip,               // status-bar text
+                                                        QKeySequence( accel ), // keyboard accelerator
+                                                        toggle );              // toogled action
+              myModule->createTool( action, tbId, -1, pos );
+            }
+          }
+          else if ( aTagName == "separatorTB" || aTagName == "separator" ) {
+            // create toolbar separator
+            int pos = checkInt( attribute( elem, "pos-id" ) );
+            QAction* action = myModule->separator();
+            myModule->createTool( action, tbId, -1, pos );
+          }
+        }
+        node = node.nextSibling();
+      }
+    }
+  }
+}
+
+/*!
+  \brief Fill popup menu with the items.
+  \param parentNode XML node with popup menu description
+  \param menu popup menu
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::insertPopupItems( QDomNode& parentNode, QMenu* menu )
+{
+  if ( !myModule && parentNode.isNull() )
+    return;
+
+  // we create popup menus without help of QtxPopupMgr
+  QDomNode node = parentNode.firstChild();
+  while ( !node.isNull() ) { 
+    if ( node.isElement() ) {
+      QDomElement elem = node.toElement();
+      QString aTagName = tagName( elem );
+      QList<QAction*> actions = menu->actions();
+      if ( aTagName == "popup-item" ) {
+        // insert a command item
+        int     id      = checkInt( attribute( elem, "item-id" ) );
+        int     pos     = checkInt( attribute( elem, "pos-id" ) );
+        QString label   = attribute( elem, "label-id" );
+        QString icon    = attribute( elem, "icon-id" );
+        QString tooltip = attribute( elem, "tooltip-id" );
+        QString accel   = attribute( elem, "accel-id" );
+        bool    toggle  = checkBool( attribute( elem, "toggle-id" ) );
+
+        // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+        // also check if the action with given ID is already created
+        if ( id != -1 ) {
+          QAction* action = myModule->createAction( id,                     // ID
+                                                    tooltip,                // tooltip
+                                                    icon,                   // icon
+                                                    label,                  // menu text
+                                                    tooltip,                // status-bar text
+                                                    QKeySequence( accel ),  // keyboard accelerator
+                                                    toggle );               // toogled action
+          QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+          menu->insertAction( before, action );
+        }
+      }
+      else if ( aTagName == "submenu" ) {
+        // create sub-menu
+        ////int     id    = checkInt( attribute( elem, "item-id" ) ); // not used //
+        int     pos   = checkInt( attribute( elem, "pos-id" ) );
+        QString label = attribute( elem, "label-id" );
+        QString icon  = attribute( elem, "icon-id" );
+
+        QIcon anIcon;
+        if ( !icon.isEmpty() ) {
+          QPixmap pixmap  = myModule->getApp()->resourceMgr()->loadPixmap( myModule->name(), icon );
+          if ( !pixmap.isNull() )
+            anIcon = QIcon( pixmap );
+        }
+
+        QMenu* newPopup = menu->addMenu( anIcon, label );
+        QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+        menu->insertMenu( before, newPopup );
+        insertPopupItems( node, newPopup );
+      }
+      else if ( aTagName == "separator" ) {
+        // create menu separator
+        int pos = checkInt( attribute( elem, "pos-id" ) );
+        QAction* action = myModule->separator();
+        QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+        menu->insertAction( before, action );
+      }
+    }
+    node = node.nextSibling();
+  }
+}
+
+/*
+ * Save study request.
+ * Called when user save study.
+ */
+void SALOME_PYQT_ModuleLight::save(QStringList& theListOfFiles)
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::save()")
+  // perform synchronous request to Python event dispatcher
+  class SaveEvent: public PyInterp_LockRequest
+  {
+  public:     
+    SaveEvent(PyInterp_Interp*           _py_interp,
+              SALOME_PYQT_ModuleLight*       _obj,
+              QStringList&                   _files_list)
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj( _obj ) ,
+        myFilesList(_files_list) {}
+  protected:
+    virtual void execute()
+    {
+      myObj->saveEvent(myFilesList);
+    }
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    QStringList&        myFilesList;
+  };
+  
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new SaveEvent( myInterp, this, theListOfFiles ) );
+}
+
+void SALOME_PYQT_ModuleLight::saveEvent(QStringList& theListOfFiles)
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::saveEvent()");
+  QStringList::Iterator it = theListOfFiles.begin();
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule || (it == theListOfFiles.end()))
+    return;
+
+  if ( PyObject_HasAttrString(myModule, (char*)"saveFiles") ) {
+    // temporary set myInitModule because saveEvent() method
+    // might be called by the framework when this module is inactive,
+    // but still it should be possible to access this module's data
+    // from Python
+    myInitModule = this;
+
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"saveFiles",
+                                           (char*)"s", (*it).toLatin1().constData()));
+
+    myInitModule = 0;
+
+    if( !res ) {
+      PyErr_Print();
+    }
+    else{
+      // parse the return value
+      // result can be one string...
+      if ( PyString_Check( res ) ) {
+        QString astr = PyString_AsString( res );
+        //SCRUTE(astr);
+        theListOfFiles.append(astr);
+      }
+      //also result can be a list...
+      else if ( PyList_Check( res ) ) {
+        int size = PyList_Size( res );
+        for ( int i = 0; i < size; i++ ) {
+          PyObject* value = PyList_GetItem( res, i );
+          if( value && PyString_Check( value ) ) {
+            theListOfFiles.append( PyString_AsString( value ) );
+          }
+        }
+      }
+    }
+  }
+}
+
+/*
+ * Python dump request.
+ * Called when user activates dump study operation.
+ */
+void SALOME_PYQT_ModuleLight::dumpPython(QStringList& theListOfFiles)
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::dumpPython()")
+  // perform synchronous request to Python event dispatcher
+  class DumpEvent: public PyInterp_LockRequest
+  {
+  public:     
+    DumpEvent(PyInterp_Interp*          _py_interp,
+              SALOME_PYQT_ModuleLight*  _obj,
+              QStringList&              _files_list)
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj( _obj ) ,
+        myFilesList(_files_list) {}
+  protected:
+    virtual void execute()
+    {
+      myObj->dumpEvent(myFilesList);
+    }
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    QStringList&             myFilesList;
+  };
+  
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new DumpEvent( myInterp, this, theListOfFiles ) );
+}
+
+void SALOME_PYQT_ModuleLight::dumpEvent(QStringList& theListOfFiles)
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::dumpEvent()");
+  QStringList::Iterator it = theListOfFiles.begin();
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule || (it == theListOfFiles.end()))
+    return;
+
+  if ( PyObject_HasAttrString(myModule, (char*)"dumpStudy") ) {
+    // temporary set myInitModule because dumpEvent() method
+    // might be called by the framework when this module is inactive,
+    // but still it should be possible to access this module's data
+    // from Python
+    myInitModule = this;
+
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"dumpStudy",
+                                           (char*)"s", (*it).toLatin1().constData()));
+
+    myInitModule = 0;
+
+    if( !res ) {
+      PyErr_Print();
+    }
+    else{
+      // parse the return value
+      // result can be one string...
+      if ( PyString_Check( res ) ) {
+        QString astr = PyString_AsString( res );
+        //SCRUTE(astr);
+        theListOfFiles.append(astr);
+      }
+      //also result can be a list...
+      else if ( PyList_Check( res ) ) {
+        int size = PyList_Size( res );
+        for ( int i = 0; i < size; i++ ) {
+          PyObject* value = PyList_GetItem( res, i );
+          if( value && PyString_Check( value ) ) {
+            theListOfFiles.append( PyString_AsString( value ) );
+          }
+        }
+      }
+    }
+  }
+}
+
+/*
+ * Open study request.
+ * Called when user open study.
+ */
+bool SALOME_PYQT_ModuleLight::open(QStringList theListOfFiles)
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::open()");
+  // perform synchronous request to Python event dispatcher
+  bool opened = false;
+  class OpenEvent: public PyInterp_LockRequest
+  {
+  public:
+    OpenEvent(PyInterp_Interp*              _py_interp,
+              SALOME_PYQT_ModuleLight*      _obj,
+              QStringList                   _files_list,
+              bool&                         _opened)
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj( _obj ) ,
+        myFilesList(_files_list),
+        myOpened(_opened) {}
+  protected:
+    virtual void execute()
+    {
+      myObj->openEvent(myFilesList,myOpened);
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    QStringList        myFilesList;
+    bool& myOpened;
+  };
+  
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new OpenEvent( myInterp, this, theListOfFiles, opened) );
+  return opened;
+}
+
+
+void SALOME_PYQT_ModuleLight::openEvent(QStringList theListOfFiles, bool &opened)
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::openEvent()");
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule || theListOfFiles.isEmpty())
+    return;
+  QStringList* theList = new QStringList(theListOfFiles);
+
+#if SIP_VERSION < 0x040800
+  PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList) );
+#else
+  PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) );
+#endif
+  if ( PyObject_HasAttrString(myModule , (char*)"openFiles") ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"openFiles",
+                                           (char*)"O", sipList.get()));
+    if( !res || !PyBool_Check( res )) {
+      PyErr_Print();
+      opened = false;
+    }
+    else{
+      opened = PyObject_IsTrue( res );
+      
+    }
+  }
+}
+
+/*
+ * Create new empty Data Object and return its entry
+ */
+QString SALOME_PYQT_ModuleLight::createObject(const QString& parent)
+{
+  SALOME_PYQT_DataObjectLight* obj=0;
+  if(!parent.isEmpty())
+  {
+    SALOME_PYQT_DataObjectLight* parentObj = findObject(parent);
+    if(parentObj)
+    {
+      obj = new SALOME_PYQT_DataObjectLight(parentObj);
+    }
+  }
+  else
+  {
+      SALOME_PYQT_DataModelLight* dm =
+        dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+      if(dm)
+      {
+        obj = new SALOME_PYQT_DataObjectLight(dm->getRoot());
+      }
+  }  
+  if (obj)
+    return obj->entry();
+  else
+    return QString::null;
+}
+
+/*
+ * Create new Data Object with name, icon and tooltip
+ * and return its entry
+ */
+QString SALOME_PYQT_ModuleLight::createObject(const QString& aname,
+                                              const QString& iconname,
+                                              const QString& tooltip,
+                                              const QString& parent)
+{
+  QString entry = createObject(parent);
+  SALOME_PYQT_DataObjectLight* obj = findObject(entry);
+
+  if(obj)
+  {
+    obj->setName(aname);
+    obj->setToolTip(tooltip);
+    obj->setIcon(iconname);
+    return obj->entry();
+  }
+  else
+    return QString::null;
+}
+
+/*
+ * Find object by entry
+ */
+SALOME_PYQT_DataObjectLight* SALOME_PYQT_ModuleLight::findObject(const QString& entry)
+{
+  SALOME_PYQT_DataObjectLight* obj = 0;
+  SALOME_PYQT_DataModelLight* dm =
+    dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+  if(!entry.isEmpty() && dm ){
+    for ( SUIT_DataObjectIterator it( dm->getRoot(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) { 
+      SALOME_PYQT_DataObjectLight* curentobj =
+        dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.current() );
+      
+      if(curentobj && curentobj->entry() == entry) {
+        obj = curentobj;
+        return obj;
+      }
+    }
+  }
+  return obj;
+}
+
+/*
+ * Set Name for object
+ */
+void SALOME_PYQT_ModuleLight::setName(const QString& obj, const QString& name)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    dataObj->setName(name);
+  }
+}
+
+/*
+ * Set Icon for object
+ */
+void SALOME_PYQT_ModuleLight::setIcon(const QString& obj, const QString& iconname)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    dataObj->setIcon(iconname);
+  }
+}
+
+/*
+ * Return Name of object
+ */
+QString SALOME_PYQT_ModuleLight::getName(const QString& obj)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    return dataObj->name();
+  }
+  return QString::null;
+}
+
+/*
+ * Return Tool Tip of object
+ */
+QString SALOME_PYQT_ModuleLight::getToolTip(const QString& obj)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    return dataObj->toolTip();
+  }
+  return QString::null;
+}
+
+
+/*
+ * Set Tool Tip for object
+ */
+void SALOME_PYQT_ModuleLight::setToolTip(const QString& obj, const QString& tooltip)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    dataObj->setToolTip(tooltip);
+  }
+}
+
+/*
+ * Return color of object
+ */
+QColor SALOME_PYQT_ModuleLight::getColor(const QString& obj)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject( obj );
+  if( dataObj ) {
+    return dataObj->color( SUIT_DataObject::Foreground );
+  }
+  return QColor();
+}
+
+/*
+ * Set color for object
+ */
+void SALOME_PYQT_ModuleLight::setColor(const QString& obj, const QColor& color)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject( obj );
+  if( dataObj ) {
+    dataObj->setColor( color );
+  }
+}
+
+/*
+ * Return entry of the referenced object (if any)
+ */
+QString SALOME_PYQT_ModuleLight::getReference(const QString& obj)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    return dataObj->refEntry();
+  }
+  return QString::null;
+}
+
+
+/*
+ * Set entry of the referenced object
+ */
+void SALOME_PYQT_ModuleLight::setReference(const QString& obj, const QString& refEntry)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    dataObj->setRefEntry(refEntry);
+  }
+}
+
+/*
+ * Remove object by entry
+ */
+void SALOME_PYQT_ModuleLight::removeObject(const QString& obj)
+{
+  SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+  if(dataObj) {
+    dataObj->parent()->removeChild(dataObj);
+  }
+}
+
+
+/*
+ * Remove chields from object 
+ */
+void SALOME_PYQT_ModuleLight::removeChild(const QString& obj)
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::removeChild()");
+  DataObjectList lst;
+  if(!obj.isEmpty())
+    {
+    SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+    if(dataObj)
+    {
+      dataObj->children(lst);
+      QListIterator<SUIT_DataObject*> it( lst );
+      while( it.hasNext() )
+      {
+        SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+        dataObj->removeChild(sobj);
+      }
+    }
+  }
+  else
+  {
+    SALOME_PYQT_DataModelLight* dm =
+      dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+    if(dm)
+    {
+      dm->getRoot()->children(lst);
+      QListIterator<SUIT_DataObject*> it( lst );
+      while(it.hasNext() )
+      {
+        SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+        dm->getRoot()->removeChild(sobj);
+      }
+    }
+  }
+}
+
+QStringList SALOME_PYQT_ModuleLight::getChildren(const QString& obj, const bool rec)
+{
+  DataObjectList lst;
+  QStringList entryList;
+  if(!obj.isEmpty())
+  {
+    SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+    if(dataObj)
+    {
+      dataObj->children(lst,rec);
+      QListIterator<SUIT_DataObject*> it( lst );
+      while(it.hasNext())
+      {
+        SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+        entryList.append(sobj->entry());
+      }
+    }
+  }
+  else
+  {
+    SALOME_PYQT_DataModelLight* dm =
+      dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+    if(dm)
+    {
+      dm->getRoot()->children(lst);
+      QListIterator<SUIT_DataObject*> it( lst );
+      while( it.hasNext() )
+      {
+        SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+        entryList.append(sobj->entry());
+      }
+    }
+  }
+  return entryList;
+}
+
+/*!
+ * Create new instance of data model and return it.
+ */
+CAM_DataModel* SALOME_PYQT_ModuleLight::createDataModel()
+{
+  MESSAGE( "SALOME_PYQT_ModuleLight::createDataModel()" );
+  return new SALOME_PYQT_DataModelLight(this);
+}
+
+/*!
+ * Returns the Python module object currently loaded.
+ */
+PyObject* SALOME_PYQT_ModuleLight::getPythonModule()
+{
+  return myModule;
+}
+
+bool SALOME_PYQT_ModuleLight::isDraggable( const SUIT_DataObject* what ) const
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::isDraggable()");
+  // perform synchronous request to Python event dispatcher
+  bool draggable = false;
+  class IsDraggableEvent: public PyInterp_LockRequest
+  {
+  public:
+    IsDraggableEvent(PyInterp_Interp*          _py_interp,
+                    SALOME_PYQT_ModuleLight*  _obj,
+                    LightApp_DataObject*      _data_object,
+                    bool&                     _is_draggable )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj( _obj ) ,
+        myDataObject( _data_object ),
+        myIsDraggable( _is_draggable ) {}
+  protected:
+    virtual void execute()
+    {
+      myIsDraggable = myObj->isDraggableEvent( myDataObject );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    LightApp_DataObject*     myDataObject;
+    bool&                    myIsDraggable;
+  };
+
+  const LightApp_DataObject* data_object = dynamic_cast<const LightApp_DataObject*>( what );
+                                                             
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new IsDraggableEvent( myInterp,
+                                                           const_cast<SALOME_PYQT_ModuleLight*>( this ),
+                                                           const_cast<LightApp_DataObject*>( data_object ),
+                                                           draggable ) );
+  return draggable;
+}
+
+bool SALOME_PYQT_ModuleLight::isDraggableEvent( LightApp_DataObject* what )
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::isDraggableEvent()");
+
+  bool draggable = false;
+
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule || !what )
+    return draggable;
+
+  if ( PyObject_HasAttrString(myModule , (char*)"isDraggable") ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"isDraggable",
+                                          (char*)"s", what->entry().toLatin1().constData() ) );
+    if( !res || !PyBool_Check( res )) {
+      PyErr_Print();
+      draggable = false;
+    }
+    else{
+      draggable = PyObject_IsTrue( res );
+    }
+  }
+
+  return draggable;
+}
+
+bool SALOME_PYQT_ModuleLight::isDropAccepted( const SUIT_DataObject* where ) const
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::isDropAccepted()");
+  // perform synchronous request to Python event dispatcher
+  bool dropAccepted = false;
+  class IsDropAcceptedEvent: public PyInterp_LockRequest
+  {
+  public:
+    IsDropAcceptedEvent(PyInterp_Interp*          _py_interp,
+                       SALOME_PYQT_ModuleLight*  _obj,
+                       LightApp_DataObject*      _data_object,
+                       bool&                     _is_drop_accepted )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj( _obj ) ,
+        myDataObject( _data_object ),
+        myIsDropAccepted( _is_drop_accepted ) {}
+  protected:
+    virtual void execute()
+    {
+      myIsDropAccepted = myObj->isDropAcceptedEvent( myDataObject );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    LightApp_DataObject*     myDataObject;
+    bool&                    myIsDropAccepted;
+  };
+  
+  const LightApp_DataObject* data_object = dynamic_cast<const LightApp_DataObject*>( where );
+                                                             
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new IsDropAcceptedEvent( myInterp,
+                                                              const_cast<SALOME_PYQT_ModuleLight*>( this ),
+                                                              const_cast<LightApp_DataObject*>( data_object ),
+                                                              dropAccepted ) );
+  return dropAccepted;
+}
+
+bool SALOME_PYQT_ModuleLight::isDropAcceptedEvent( LightApp_DataObject* where )
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::isDropAcceptedEvent()");
+
+  bool dropAccepted = false;
+
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule || !where )
+    return dropAccepted;
+
+  if ( PyObject_HasAttrString(myModule , (char*)"isDropAccepted") ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"isDropAccepted",
+                                          (char*)"s", where->entry().toLatin1().constData() ) );
+    if( !res || !PyBool_Check( res )) {
+      PyErr_Print();
+      dropAccepted = false;
+    }
+    else{
+      dropAccepted = PyObject_IsTrue( res );
+    }
+  }
+
+  return dropAccepted;
+}
+
+void SALOME_PYQT_ModuleLight::dropObjects( const DataObjectList& what, SUIT_DataObject* where,
+                                          const int row, Qt::DropAction action )
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::dropObjects()");
+  // perform synchronous request to Python event dispatcher
+  class DropObjectsEvent: public PyInterp_LockRequest
+  {
+  public:
+    DropObjectsEvent(PyInterp_Interp*          _py_interp,
+                    SALOME_PYQT_ModuleLight*  _obj,
+                    const DataObjectList&     _what,
+                    SUIT_DataObject*          _where,
+                    const int                 _row,
+                    Qt::DropAction            _action )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myObj( _obj ) ,
+        myWhat( _what ),
+       myWhere( _where ),
+       myRow ( _row ),
+       myAction ( _action ){}
+  protected:
+    virtual void execute()
+    {
+      myObj->dropObjectsEvent( myWhat, myWhere, myRow, myAction );
+    }
+
+  private:
+    SALOME_PYQT_ModuleLight* myObj;
+    DataObjectList           myWhat;
+    SUIT_DataObject*         myWhere;
+    int                      myRow;
+    Qt::DropAction           myAction;
+  };
+  
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new DropObjectsEvent( myInterp, this, what, where, row, action ) );
+}
+
+void SALOME_PYQT_ModuleLight::dropObjectsEvent( const DataObjectList& what, SUIT_DataObject* where,
+                                               const int row, Qt::DropAction action )
+{
+  MESSAGE("SALOME_PYQT_ModuleLight::dropObjectsEvent()");
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule || what.isEmpty() || !where )
+    return;
+
+  QStringList* theList = new QStringList();
+
+  LightApp_DataObject* whereObject = dynamic_cast<LightApp_DataObject*>( where );
+  if ( !whereObject ) return;
+  
+  for ( int i = 0; i < what.count(); i++ ) {
+    LightApp_DataObject* dataObject = dynamic_cast<LightApp_DataObject*>( what[i] );
+    if ( dataObject ) theList->append( dataObject->entry() );
+  }
+
+#if SIP_VERSION < 0x040800
+  PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList) );
+#else
+  PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL) );
+#endif
+  if ( PyObject_HasAttrString(myModule, (char*)"dropObjects") ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"dropObjects", (char*)"Osii",
+                                          sipList.get(),
+                                          whereObject->entry().toLatin1().constData(),
+                                          row, action ) );
+    
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h
new file mode 100644 (file)
index 0000000..c2c92ea
--- /dev/null
@@ -0,0 +1,222 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File   : SALOME_PYQT_Module.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+#ifndef SALOME_PYQT_MODULELIGHT_H
+#define SALOME_PYQT_MODULELIGHT_H
+
+#include "PyInterp_Interp.h" // // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+#include "SALOME_PYQT_GUILight.h"
+#include "LightApp_Module.h"
+#include "SALOME_PYQT_DataObjectLight.h"
+#include <CAM_Module.h>
+
+#include <map>
+#include <QStringList>
+#include <QList>
+#include <QMap>
+#include <QIcon>
+
+class SALOME_PYQT_RootObjectLight;
+class SALOME_PYQT_PyInterp;
+class SUIT_ViewWindow;
+class QAction;
+class QtxActionGroup;
+class QMenu;
+
+
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_ModuleLight: virtual public LightApp_Module
+{
+  Q_OBJECT;
+
+private:
+  class XmlHandler;
+
+  //! study to Python subinterpreter map
+  typedef QMap<int, PyInterp_Interp*> InterpMap;
+  static SALOME_PYQT_ModuleLight* myInitModule; //!< Python GUI being initialized (not zero only during the initialization)
+
+  XmlHandler*                myXmlHandler; //!< XML resource file parser
+  QMap<int, int>             myWindowsMap; //!< windows map
+  QStringList                myViewMgrList;//!< compatible view managers list
+  bool                       myLastActivateStatus; //!< latest module activation status
+
+protected:
+  PyObject*                  myModule;     //!< Python GUI module
+  PyInterp_Interp*           myInterp;     //!< current Python subinterpreter
+  static InterpMap           myInterpMap;  //!< study to Python subinterpreter map
+
+public:
+  SALOME_PYQT_ModuleLight();
+  ~SALOME_PYQT_ModuleLight();
+
+public:
+  static SALOME_PYQT_ModuleLight* getInitModule();
+
+  void                       initialize( CAM_Application* );
+  void                       windows( QMap<int, int>& ) const;
+  void                       viewManagers( QStringList& ) const;
+  void                       contextMenuPopup( const QString&, QMenu*, QString& );
+  void                       createPreferences();
+  void                       studyActivated();
+  void                       preferencesChanged( const QString&, const QString& );
+
+  static int                 defaultMenuGroup();
+
+  int                        createTool( const QString& );
+  int                        createTool( const int, const int, const int = -1 );
+  int                        createTool( const int, const QString&, const int = -1 );
+  int                        createTool( QAction*, const int, 
+                                         const int = -1, const int = -1 );
+  int                        createTool( QAction*, const QString&, 
+                                         const int = -1, const int = -1 );
+
+  int                        createMenu( const QString&, const int, 
+                                         const int = -1, const int = -1, const int = -1 );
+  int                        createMenu( const QString&, const QString&, 
+                                         const int = -1, const int = -1, const int = -1 );
+  int                        createMenu( const int, const int, 
+                                         const int = -1, const int = -1 );
+  int                        createMenu( const int, const QString&, 
+                                         const int = -1, const int = -1 );
+  int                        createMenu( QAction*, const int, 
+                                         const int = -1, const int = -1, const int = -1 );
+  int                        createMenu( QAction*, const QString&, 
+                                         const int = -1, const int = -1, const int = -1 );
+
+  QAction*                   separator();
+
+  QAction*                   action( const int ) const;
+  int                        actionId( const QAction* ) const;
+  QAction*                   createAction( const int, const QString&, const QString&, 
+                                           const QString&, const QString&, const int, 
+                                           const bool = false, QObject* = 0 );
+  QtxActionGroup*            createActionGroup( const int, const bool );
+
+
+  QIcon                      loadIcon( const QString& fileName );
+
+  int                        addGlobalPreference( const QString& );
+  int                        addPreference( const QString& );
+  int                        addPreference( const QString&, const int, const int = LightApp_Preferences::Auto,
+                                            const QString& = QString(),
+                                            const QString& = QString() );
+  QVariant                   preferenceProperty( const int, const QString& ) const;
+  void                       setPreferenceProperty( const int, const QString&, 
+                                                    const QVariant& );
+
+  void                       save(QStringList& theListOfFiles);
+  bool                       open(QStringList theListOfFiles);
+  void                       dumpPython(QStringList& theListOfFiles);
+
+  /*create new SALOME_PYQT_DataObjectLight and return its entry*/
+  QString                    createObject(const QString& parent);
+  QString                    createObject(const QString& name, 
+                                         const QString& iconname,
+                                         const QString& tooltip,
+                                         const QString& parent);
+  /*Sets Name, Icon and Tool Tip for object*/
+  void                      setName(const QString& obj,const QString& iconname);
+  void                      setIcon(const QString& obj,const QString& name);
+  void                      setToolTip(const QString& obj, const QString& tooltip);
+
+  /*Gets Name and Tool Tip for object*/
+  QString                   getName(const QString& obj);
+  QString                   getToolTip(const QString& obj);
+
+  void                      setColor(const QString& obj, const QColor& color);
+  QColor                    getColor(const QString& obj);
+
+  void                      setReference( const QString& obj, 
+                                         const QString& refEntry ); 
+  QString                   getReference( const QString& obj );
+
+                             /*remove object*/
+  void                      removeObject(const QString& obj);
+                            /*remove child*/
+  void                      removeChild(const QString& obj);
+                            /*return list of child objets*/
+  QStringList               getChildren(const QString& obj, const bool rec);
+
+  /*Access to the underlying Python module object */
+  PyObject*                 getPythonModule();
+
+  /*Drag and drop support*/
+  virtual bool              isDraggable( const SUIT_DataObject* ) const;
+  virtual bool              isDropAccepted( const SUIT_DataObject* ) const;
+  virtual void              dropObjects( const DataObjectList&, SUIT_DataObject*,
+                                        const int, Qt::DropAction );
+
+public slots:
+  virtual bool               activateModule( SUIT_Study* );
+  virtual bool               deactivateModule( SUIT_Study* );
+  void                       preferenceChanged( const QString&, 
+                                                const QString&, 
+                                                const QString& );
+  void                       onGUIEvent();
+
+  void                       onActiveViewChanged( SUIT_ViewWindow* );
+  void                       onViewTryClose( SUIT_ViewWindow* );
+  void                       onViewClosed( SUIT_ViewWindow* );
+  void                       onViewCloned( SUIT_ViewWindow* );
+
+protected:
+  /* create data model */
+  virtual CAM_DataModel*     createDataModel();
+  virtual bool               activateModuleInternal( SUIT_Study* );
+
+private:
+  void                       init( CAM_Application* );
+  void                       activate( SUIT_Study* );
+  void                       deactivate( SUIT_Study* );
+  bool                       lastActivationStatus() const;
+  void                       customize( SUIT_Study* );
+  void                       studyChanged( SUIT_Study* );
+  void                       contextMenu( const QString&, QMenu* );
+  void                       guiEvent( const int );
+  void                       initPreferences();
+  void                       prefChanged( const QString&, const QString& );
+
+  virtual void               initInterp  ( int );
+  void                       importModule();
+  void                       setWorkSpace();
+  
+  void                       activeViewChanged( const SUIT_ViewWindow* );
+  void                       viewTryClose( const SUIT_ViewWindow* );
+  void                       viewClosed( const SUIT_ViewWindow* );
+  void                       viewCloned( const SUIT_ViewWindow* );
+  void                       connectView( const SUIT_ViewWindow* );
+
+  void                       saveEvent(QStringList& theListOfFiles);
+  void                       dumpEvent(QStringList& theListOfFiles);
+  void                       openEvent(QStringList theListOfFiles, bool& opened);
+  
+  bool                       isDraggableEvent( LightApp_DataObject* );
+  bool                       isDropAcceptedEvent( LightApp_DataObject* );
+  void                       dropObjectsEvent( const DataObjectList&, SUIT_DataObject*,
+                                              const int, Qt::DropAction );
+
+  SALOME_PYQT_DataObjectLight* findObject(const QString& entry);
+
+  friend class XmlHandler;
+};
+
+#endif // SALOME_PYQT_MODULELIGHT_H
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyInterp.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyInterp.cxx
new file mode 100644 (file)
index 0000000..fc41424
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SALOME_PYQT_PyInterp.h" // this include must be first !!
+
+#include <SUITApp_init_python.hxx>
+#include <PyInterp_Interp.h>
+#include <utilities.h>
+
+#ifndef GUI_DISABLE_CORBA
+#include <Container_init_python.hxx>
+#endif
+
+
+
+
+/*!
+ * constructor : the main SALOME Python interpreter is used for PyQt GUI.
+ * calls initialize method defined in base class, which calls virtual methods
+ * initstate & initcontext redefined here
+ */
+SALOME_PYQT_PyInterp::SALOME_PYQT_PyInterp(): PyInterp_Interp()
+{
+}
+
+SALOME_PYQT_PyInterp::~SALOME_PYQT_PyInterp()
+{
+}
+
+void SALOME_PYQT_PyInterp::initPython()
+{
+ /*
+  * Do nothing
+  * The initialization has been done in main
+  */
+  MESSAGE("SALOME_PYQT_PyInterp::initPython");
+#ifndef GUI_DISABLE_CORBA
+  if(SUIT_PYTHON::initialized) {
+    ASSERT(SUIT_PYTHON::_gtstate); // initialisation in main
+    SCRUTE(SUIT_PYTHON::_gtstate);
+    _tstate = SUIT_PYTHON::_gtstate;
+  }
+  else {
+    ASSERT(KERNEL_PYTHON::_gtstate); // initialisation in main
+    SCRUTE(KERNEL_PYTHON::_gtstate);
+    _tstate = KERNEL_PYTHON::_gtstate;
+  }
+#else
+  SCRUTE(SUIT_PYTHON::_gtstate);
+  _tstate = SUIT_PYTHON::_gtstate;
+#endif
+}
+
+bool SALOME_PYQT_PyInterp::initState()
+{
+ /*
+  * The GIL is assumed to not be held on the call
+  * The GIL is acquired in initState and will be held on initState exit
+  * It is the caller responsability to release the lock on exit if needed
+  */
+  PyEval_AcquireThread(_tstate);
+  SCRUTE(_tstate);
+  PyEval_ReleaseThread(_tstate);
+  return true;
+}
+
+
+bool SALOME_PYQT_PyInterp::initContext()
+{
+  /*
+   * The GIL is assumed to be held
+   * It is the caller responsability to acquire the GIL before calling initContext
+   * It will still be held on initContext exit
+   */
+  _g = PyDict_New();          // create interpreter dictionnary context
+  PyObject *bimod = PyImport_ImportModule("__builtin__");
+  PyDict_SetItemString(_g, "__builtins__", bimod);
+  Py_DECREF(bimod); 
+  return true;
+}
+
+int SALOME_PYQT_PyInterp::run(const char *command)
+{
+  MESSAGE("compile");
+  PyObject *code = Py_CompileString((char *)command,"PyGUI",Py_file_input);
+  if(!code){
+    // Une erreur s est produite en general SyntaxError
+    PyErr_Print();
+    return -1;
+  }
+  //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+  //  PyObject *r = PyEval_EvalCode(code,_g,_g);
+  //#else
+  PyObject *r = PyEval_EvalCode((PyCodeObject *)code,_g,_g);
+  //#endif
+  Py_DECREF(code);
+  if(!r){
+    // Une erreur s est produite a l execution
+    PyErr_Print();
+    return -1 ;
+  }
+  Py_DECREF(r);
+  return 0;
+}
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyInterp.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyInterp.h
new file mode 100644 (file)
index 0000000..d894ab6
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : SALOME_PYQT_Module.h
+//  Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+//  Date   : 13/04/2009
+//
+#ifndef SALOME_PYQT_PYINTERP_H
+#define SALOME_PYQT_PYINTERP_H
+
+#include "SALOME_PYQT_GUILight.h"
+
+#include "PyInterp_Interp.h" // this include must be first !!!
+
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_PyInterp : public PyInterp_Interp
+{
+ public:
+  SALOME_PYQT_PyInterp();
+  ~SALOME_PYQT_PyInterp();
+  
+  int run(const char *command);
+  
+ protected:
+  virtual void initPython();
+  virtual bool initState();
+  virtual bool initContext();
+};
+
+#endif // SALOME_PYQT_PYINTERP_H
diff --git a/src/SalomeApp/pluginsdemo/Makefile.am b/src/SalomeApp/pluginsdemo/Makefile.am
new file mode 100644 (file)
index 0000000..f949438
--- /dev/null
@@ -0,0 +1,41 @@
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF) 
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+#
+# Note that the plugins files should be installed in the directory
+# <salomepluginsdir> (ROOT_DIR/share/salome/plugins) or one of this
+# sub-directories (the search of plugins by the plugin manager is
+# recurcive from this folder, in each SALOME module, i.e. each
+# variable *_ROOT_DIR).  
+#
+pluginsdir =$(salomepluginsdir)/demo
+plugins_PYTHON = \
+       salome_plugins.py \
+       smesh_plugins.py \
+       trihedron.py      \
+       tubedialog_ui.py  \
+       tubedialog.py     \
+       tubebuilder.py    \
+       xalome.py         \
+       minmax_dialog.py  \
+       minmax_plugin.py
diff --git a/src/SalomeApp/pluginsdemo/minmax.ui b/src/SalomeApp/pluginsdemo/minmax.ui
new file mode 100644 (file)
index 0000000..3c9eafd
--- /dev/null
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>178</width>
+    <height>156</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Get min and max value of control</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Mesh</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" colspan="2">
+    <widget class="QLineEdit" name="mesh">
+     <property name="readOnly">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Control</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1" colspan="2">
+    <widget class="QComboBox" name="control"/>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Min</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1" colspan="2">
+    <widget class="QLineEdit" name="minvalue">
+     <property name="readOnly">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="label_4">
+     <property name="text">
+      <string>Max</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1" colspan="2">
+    <widget class="QLineEdit" name="maxvalue">
+     <property name="readOnly">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0" colspan="3">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>mesh</tabstop>
+  <tabstop>control</tabstop>
+  <tabstop>minvalue</tabstop>
+  <tabstop>maxvalue</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Dialog</receiver>
+   <slot>OnCancel()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>253</x>
+     <y>371</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>262</x>
+     <y>101</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>helpRequested()</signal>
+   <receiver>Dialog</receiver>
+   <slot>helpMessage()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>131</x>
+     <y>373</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>131</x>
+     <y>64</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>control</sender>
+   <signal>activated(QString)</signal>
+   <receiver>Dialog</receiver>
+   <slot>compute_minmax()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>250</x>
+     <y>137</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>131</x>
+     <y>81</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <slots>
+  <slot>compute_minmax()</slot>
+  <slot>helpMessage()</slot>
+  <slot>OnCancel()</slot>
+  <slot>OnOk()</slot>
+ </slots>
+</ui>
diff --git a/src/SalomeApp/pluginsdemo/minmax_dialog.py b/src/SalomeApp/pluginsdemo/minmax_dialog.py
new file mode 100644 (file)
index 0000000..c7d310e
--- /dev/null
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'minmax.ui'
+#
+# Created: Thu Mar  1 15:23:57 2012
+#      by: PyQt4 UI code generator 4.8.1
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+try:
+    _fromUtf8 = QtCore.QString.fromUtf8
+except AttributeError:
+    _fromUtf8 = lambda s: s
+
+class Ui_Dialog(object):
+    def setupUi(self, Dialog):
+        Dialog.setObjectName(_fromUtf8("Dialog"))
+        Dialog.resize(178, 156)
+        Dialog.setSizeGripEnabled(True)
+        self.gridLayout = QtGui.QGridLayout(Dialog)
+        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
+        self.label_2 = QtGui.QLabel(Dialog)
+        self.label_2.setObjectName(_fromUtf8("label_2"))
+        self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
+        self.mesh = QtGui.QLineEdit(Dialog)
+        self.mesh.setReadOnly(True)
+        self.mesh.setObjectName(_fromUtf8("mesh"))
+        self.gridLayout.addWidget(self.mesh, 0, 1, 1, 2)
+        self.label_3 = QtGui.QLabel(Dialog)
+        self.label_3.setObjectName(_fromUtf8("label_3"))
+        self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
+        self.control = QtGui.QComboBox(Dialog)
+        self.control.setObjectName(_fromUtf8("control"))
+        self.gridLayout.addWidget(self.control, 1, 1, 1, 2)
+        self.label = QtGui.QLabel(Dialog)
+        self.label.setObjectName(_fromUtf8("label"))
+        self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
+        self.minvalue = QtGui.QLineEdit(Dialog)
+        self.minvalue.setReadOnly(True)
+        self.minvalue.setObjectName(_fromUtf8("minvalue"))
+        self.gridLayout.addWidget(self.minvalue, 2, 1, 1, 2)
+        self.label_4 = QtGui.QLabel(Dialog)
+        self.label_4.setObjectName(_fromUtf8("label_4"))
+        self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1)
+        self.maxvalue = QtGui.QLineEdit(Dialog)
+        self.maxvalue.setReadOnly(True)
+        self.maxvalue.setObjectName(_fromUtf8("maxvalue"))
+        self.gridLayout.addWidget(self.maxvalue, 3, 1, 1, 2)
+        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
+        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.Help)
+        self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
+        self.gridLayout.addWidget(self.buttonBox, 4, 0, 1, 3)
+
+        self.retranslateUi(Dialog)
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.OnCancel)
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("helpRequested()")), Dialog.helpMessage)
+        QtCore.QObject.connect(self.control, QtCore.SIGNAL(_fromUtf8("activated(QString)")), Dialog.compute_minmax)
+        QtCore.QMetaObject.connectSlotsByName(Dialog)
+        Dialog.setTabOrder(self.mesh, self.control)
+        Dialog.setTabOrder(self.control, self.minvalue)
+        Dialog.setTabOrder(self.minvalue, self.maxvalue)
+        Dialog.setTabOrder(self.maxvalue, self.buttonBox)
+
+    def retranslateUi(self, Dialog):
+        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Get min and max value of control", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_2.setText(QtGui.QApplication.translate("Dialog", "Mesh", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_3.setText(QtGui.QApplication.translate("Dialog", "Control", None, QtGui.QApplication.UnicodeUTF8))
+        self.label.setText(QtGui.QApplication.translate("Dialog", "Min", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_4.setText(QtGui.QApplication.translate("Dialog", "Max", None, QtGui.QApplication.UnicodeUTF8))
+
diff --git a/src/SalomeApp/pluginsdemo/minmax_plugin.py b/src/SalomeApp/pluginsdemo/minmax_plugin.py
new file mode 100644 (file)
index 0000000..c743e52
--- /dev/null
@@ -0,0 +1,184 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+def minmax(context):
+  # get context study, studyId, salomeGui
+  study = context.study
+  studyId = context.studyId
+  sg = context.sg
+
+  from PyQt4.QtGui import QDialog
+  from PyQt4.QtGui import QMessageBox
+  from PyQt4.QtCore import Qt
+  from PyQt4.QtCore import SIGNAL
+
+  from minmax_dialog import Ui_Dialog
+
+  import salome
+  import smesh
+
+  controls_dict = {
+    "Aspect Ratio 3D" :     smesh.FT_AspectRatio3D,
+    "Volume" :              smesh.FT_Volume3D,
+    "Element Diameter 3D" : smesh.FT_MaxElementLength3D,
+    "Length 2D" :           smesh.FT_Length2D,
+    "MultiConnection 2D" :  smesh.FT_MultiConnection2D,
+    "Area" :                smesh.FT_Area,
+    "Taper" :               smesh.FT_Taper,
+    "Aspect Ratio" :        smesh.FT_AspectRatio,
+    "Minimum Angle" :       smesh.FT_MinimumAngle,
+    "Warping" :             smesh.FT_Warping,
+    "Skew" :                smesh.FT_Skew,
+    "Element Diameter 2D" : smesh.FT_MaxElementLength2D,
+    "Length" :              smesh.FT_Length,
+    "MultiConnection" :     smesh.FT_MultiConnection,
+    }
+
+  controls_3d = [
+    "Aspect Ratio 3D",
+    "Volume",
+    "Element Diameter 3D",
+    ]
+  controls_2d = [
+    "Length 2D",
+    "MultiConnection 2D",
+    "Area",
+    "Taper",
+    "Aspect Ratio",
+    "Minimum Angle",
+    "Warping",
+    "Skew",
+    "Element Diameter 2D"
+    ]
+  controls_1d = [
+    "Length",
+    "MultiConnection",
+    ]
+
+  class MinmaxDialog(QDialog):
+    def __init__(self):
+      QDialog.__init__(self, None, Qt.Tool)
+      # Set up the user interface from Designer.
+      self.ui = Ui_Dialog()
+      self.ui.setupUi(self)
+      self.show()
+
+      self.clearLineEdit()
+
+      # Connect up the selectionChanged() event of the object browser.
+      self.connect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+
+      self.mm = None
+      self.ui.control.setFocus()
+      self.select()
+
+      pass
+
+    def OnCancel(self):
+      self.disconnect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+      self.reject()
+      pass
+
+    def clearLineEdit(self):
+      self.ui.mesh.setText("Select a Mesh")
+      self.ui.mesh.setStyleSheet("QLineEdit { color: grey }")
+      self.ui.minvalue.setText("")
+      self.ui.maxvalue.setText("")
+
+    def select(self):
+      self.disconnect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+      self.ui.control.clear()
+      self.ui.minvalue.setText("")
+      self.ui.maxvalue.setText("")
+      objId = salome.sg.getSelected(0)
+      if objId:
+        mm = study.FindObjectID(objId).GetObject()
+        mesh = None
+        try:
+          mesh = mm.GetMEDMesh()
+        except:
+          #print "No mesh selected"
+          self.clearLineEdit()
+          mesh = None
+          pass
+        if mesh:
+          self.ui.mesh.setStyleSheet("")
+          self.ui.mesh.setText(mesh.getName())
+          #print "Mesh selected: ", mesh.getName()
+          self.mm = mm
+          e = self.mm.NbEdges()
+          f = self.mm.NbFaces()
+          v = self.mm.NbVolumes()
+          #print "NbEdges: ",e
+          #print "NbFaces: ",f
+          #print "NbVolumes: ",v
+          controls = []
+          if e:
+            controls += controls_1d
+            pass
+          if f:
+            controls += controls_2d
+            pass
+          if v:
+            controls += controls_3d
+            pass
+          self.ui.control.addItems(controls)
+          self.compute_minmax()
+      self.connect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+      pass
+
+    def helpMessage(self):
+      QMessageBox.about(None, "About Min/Max value of control",
+      """
+      Displays the min/max value of a control
+      ---------------------------------
+
+This plugin displays the min and max value of a control
+on a mesh.
+Inputs:
+  - The mesh to analyse
+  - The control to compute
+      """)
+      pass
+
+    def compute_minmax(self):
+      if self.mm:
+        control = self.ui.control.currentText()
+        #print "Compute control: ",control
+        fun = smesh.GetFunctor(controls_dict[str(control)])
+        fun.SetMesh(self.mm.GetMesh())
+        hist = fun.GetHistogram(1)
+        maxVal = hist[0].max
+        minVal = hist[0].min
+        #print "Max value for %s: %f"%(control, maxVal)
+        #print "Min value for %s: %f"%(control, minVal)
+        self.ui.maxvalue.setText("%f"%(maxVal))
+        self.ui.minvalue.setText("%f"%(minVal))
+      else:
+        print "Pas de maillage"
+        pass
+      pass
+    pass
+
+  window = MinmaxDialog()
+  window.exec_()
+  pass
+
diff --git a/src/SalomeApp/pluginsdemo/salome_plugins.py b/src/SalomeApp/pluginsdemo/salome_plugins.py
new file mode 100755 (executable)
index 0000000..edb361b
--- /dev/null
@@ -0,0 +1,281 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import salome_pluginsmanager
+
+DEMO_IS_ACTIVATED = False
+
+if DEMO_IS_ACTIVATED:
+  # Check that GEOM and SMESH modules are present
+  try:
+    import geompy, smesh
+  except:
+    DEMO_IS_ACTIVATED = False
+
+if DEMO_IS_ACTIVATED:
+  # -------------------------------------------------------------------------
+  # Example 1: creation of basic objects.
+  # The plugin function is implemented here and declared in the pluginsmanager.
+  #
+  import salome
+
+  def trihedron(context):
+      import geompy
+
+      # Intialize the geompy factory with the active study
+      activeStudy = context.study
+      geompy.init_geom(activeStudy)
+
+      # Create the objects
+      Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
+      Vy = geompy.MakeVectorDXDYDZ(0, 10, 0)
+      Vz = geompy.MakeVectorDXDYDZ(0, 0, 10)
+      origin = geompy.MakeVertex(0, 0, 0)
+
+      # Register the objects in the active study
+      geompy.addToStudy( Vx, "Vx" )
+      geompy.addToStudy( Vy, "Vy" )
+      geompy.addToStudy( Vz, "Vz" )
+      geompy.addToStudy( origin, "origin" )
+
+
+  salome_pluginsmanager.AddFunction('DEMO/O,Vx,Vy,Vz',
+                                    'Creates the trihedron',
+                                    trihedron)
+
+
+  # -------------------------------------------------------------------------
+  # Example 1 bis: creation of basic objects and automatic display
+  def trihedron_withdisplay(context):
+      import geompy
+
+      # Intialize the geompy factory with the active study
+      activeStudy = context.study
+      geompy.init_geom(activeStudy)
+
+      # Create the objects
+      Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
+      Vy = geompy.MakeVectorDXDYDZ(0, 10, 0)
+      Vz = geompy.MakeVectorDXDYDZ(0, 0, 10)
+      origin = geompy.MakeVertex(0, 0, 0)
+
+      # Register the objects in the active study
+      entries=[]
+      entries.append(geompy.addToStudy( Vx, "Vx" ))
+      entries.append(geompy.addToStudy( Vy, "Vy" ))
+      entries.append(geompy.addToStudy( Vz, "Vz" ))
+      entries.append(geompy.addToStudy( origin, "origin" ))
+
+      # This part is to automatically display the objects in the active viewer.
+      gcomp = salome.ImportComponentGUI("GEOM")
+      for entry in entries:
+          gcomp.createAndDisplayFitAllGO(entry)
+
+
+  salome_pluginsmanager.AddFunction('DEMO/O,Vx,Vy,Vz (2)',
+                                    'Creates Basic GEOM objects',
+                                    trihedron_withdisplay)
+
+  # -------------------------------------------------------------------------
+  # Example 2: creation of a shape with parameters that can be read from a GUI.
+  # The plugin function (tube_shapewithgui) delegates some action to
+  # dedicated imported modules (tube.py and tubedialog.py).
+  #
+
+  import tubebuilder
+  import xalome
+
+  # A single dialog box is defined and recycled for every call. The
+  # fields are initialized with default values given by the tube factory
+  # tube.py.
+  import tubedialog
+  dialog = tubedialog.TubeDialog()
+  dialog.setData(tubebuilder.DEFAULT_RADIUS,
+                tubebuilder.DEFAULT_LENGTH,
+                tubebuilder.DEFAULT_WIDTH)
+
+  def tube_shapewithgui(context):
+      global tubebuilder, xalome, dialog
+      activeStudy = context.study
+
+      # Get the parameter values from a gui dialog box. If the dialog is
+      # closed using the Ok button, then the data are requested from the
+      # gui and used to create the shape of the tube.
+      dialog.exec_()
+      if dialog.wasOk():
+          radius, length, width = dialog.getData()
+          shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+          entry = xalome.addToStudy(activeStudy, shape, "Tube" )
+          xalome.displayShape(entry)
+
+
+  salome_pluginsmanager.AddFunction('DEMO/Tube shape from parameters',
+                                    'Creates a tube object from specified parameters',
+                                    tube_shapewithgui)
+
+
+  # -------------------------------------------------------------------------
+  # Example 2 bis: creation of a mesh with parameters that can be read from a GUI.
+  # The plugin function (tube_meshwithgui) delegates some action to
+  # dedicated imported modules (tubebuilder.py and tubedialog.py).
+  #
+  def tube_meshwithgui(context):
+      global tube, dialog
+      activeStudy = context.study
+
+      # Get the parameter values from a gui dialog box. If the dialog is
+      # closed using the Ok button, then the data are requested from the
+      # gui and used to create the shape of the tube.
+      dialog.exec_()
+      if dialog.wasOk():
+          radius, length, width = dialog.getData()
+          mesh = tubebuilder.createModel(activeStudy, radius, length, width)
+
+
+  salome_pluginsmanager.AddFunction('DEMO/Tube mesh from parameters',
+                                    'Creates a tube object from specified parameters',
+                                    tube_meshwithgui)
+
+
+  # -------------------------------------------------------------------------
+  # Example 2 ter: creation of a geom object with a preview function in
+  # the dialog box. This use case is more complex from the gui point of
+  # view because the dialog box is a not modal so that we can have
+  # interaction with the complete SALOME application. This modal
+  # situation requires to connect button click signal on global
+  # functions as a "callback" mechanism.
+  #
+  # TODO:
+  # - coloring the preview in pink
+  # - store the tmp study objects in a "preview" folder
+  #
+  dialogWithApply = tubedialog.TubeDialogOnTopWithApply()
+  dialogWithApply.setData(tubebuilder.DEFAULT_RADIUS,
+                          tubebuilder.DEFAULT_LENGTH,
+                          tubebuilder.DEFAULT_WIDTH)
+  activeStudy = None
+  previewShapeEntry = None
+
+  DEFAULT_FOLDER_NAME="TubeList"
+  DEFAULT_SHAPE_NAME="tube"
+  PREVIEW_SHAPE_NAME="preview"
+
+  def acceptCallback():
+      """Action to be done when click on Ok"""
+      global tubebuilder, xalome
+      global dialogWithApply, activeStudy
+      global previewShapeEntry, deletePreviewShape
+      global DEFAULT_FOLDER_NAME,DEFAULT_SHAPE_NAME 
+
+      dialogWithApply.accept()
+
+      if previewShapeEntry is not None:
+          deletePreviewShape()
+
+      radius, length, width = dialogWithApply.getData()
+      shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+      entry = xalome.addToStudy(activeStudy, shape, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME)
+      xalome.displayShape(entry)
+      
+  def rejectCallback():
+      """Action to be done when click on Cancel"""
+      global dialogWithApply, previewShapeEntry, deletePreviewShape
+
+      dialogWithApply.reject()
+
+      if previewShapeEntry is not None:
+          deletePreviewShape()
+
+  import SALOMEDS
+  PREVIEW_COLOR=SALOMEDS.Color(1,0.6,1) # pink
+
+  def applyCallback():
+      """Action to be done when click on Apply"""
+      global tubebuilder, xalome
+      global dialogWithApply, activeStudy
+      global previewShapeEntry, deletePreviewShape
+      global PREVIEW_COLOR, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME, PREVIEW_SHAPE_NAME
+
+      # We first have to destroy the currently displayed preview shape.
+      if previewShapeEntry is not None:
+          deletePreviewShape()
+
+      # Then we can create the new shape with the new parameter values
+      radius, length, width = dialogWithApply.getData()
+      shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+      # We apply a specific color on the shape for the preview state
+      shape.SetColor(PREVIEW_COLOR)
+      previewShapeEntry = xalome.addToStudy(activeStudy, shape, PREVIEW_SHAPE_NAME, DEFAULT_FOLDER_NAME )
+      xalome.displayShape(previewShapeEntry)
+
+  def deletePreviewShape():
+      """This delete the shape currently being displayed as a preview"""
+      global activeStudy, previewShapeEntry, xsalome
+      xalome.deleteShape(activeStudy,previewShapeEntry)
+      previewShapeEntry = None
+
+  # Connection of callback functions to the dialog butoon click signals
+  dialogWithApply.handleAcceptWith(acceptCallback)
+  dialogWithApply.handleRejectWith(rejectCallback)
+  dialogWithApply.handleApplyWith(applyCallback)
+
+  def tube_shapewithguiAndPreview(context):
+      """
+      This plugin open a dialog in an asynchronous mode. Then it
+      required callback functions to be associated to the button
+      signals.
+      """
+      global dialogWithApply, activeStudy
+      activeStudy = context.study
+      dialogWithApply.open()
+
+
+  salome_pluginsmanager.AddFunction('DEMO/Tube geometry from parameters with preview',
+                                    'Creates a tube object from specified parameters',
+                                    tube_shapewithguiAndPreview)
+
+
+
+# -------------------------------------------------------------------------
+# Example 3: run a shell session in a xterm to get a SALOME python console
+def runSalomeShellSession(context):
+    import os,subprocess
+    import salome_version
+    version = salome_version.getVersion(full=True)
+    kernel_appli_dir = os.environ['KERNEL_ROOT_DIR']
+    command = ""
+    if os.path.exists("/usr/bin/xterm"):
+      command = 'xterm -T "SALOME %s - Shell session" -e %s/runSession &'%(version,kernel_appli_dir)
+    elif os.path.exists("/usr/bin/gnome-terminal"):
+      command = 'gnome-terminal -t "SALOME %s - Shell session" -e %s/runSession &'%(version,kernel_appli_dir)
+    else:
+      print "Neither xterm nor gnome-terminal is installed."
+    
+    if command is not "":
+      try:
+        subprocess.check_call(command, shell = True)
+      except Exception, e:
+        print "Error: ",e
+
+
+salome_pluginsmanager.AddFunction('SALOME shell session',
+                                  'Execute a SALOME shell session in an external xterm',
+                                  runSalomeShellSession)
diff --git a/src/SalomeApp/pluginsdemo/smesh_plugins.py b/src/SalomeApp/pluginsdemo/smesh_plugins.py
new file mode 100644 (file)
index 0000000..77269a5
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#!/usr/bin/env python
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import salome_pluginsmanager
+
+DEMO_IS_ACTIVATED = True
+
+from minmax_plugin import *
+# register the function in the plugin manager
+if DEMO_IS_ACTIVATED:
+  salome_pluginsmanager.AddFunction('Get min or max value of control',
+      'Get min or max value of control',
+      minmax)
diff --git a/src/SalomeApp/pluginsdemo/trihedron.py b/src/SalomeApp/pluginsdemo/trihedron.py
new file mode 100644 (file)
index 0000000..8a82c9b
--- /dev/null
@@ -0,0 +1,41 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+# Example 1: creation of basic objects (O, Vx, Vy, Vz)
+#
+
+# Intialize the geompy factory with the active study
+import geompy
+import salome
+geompy.init_geom(salome.myStudy)
+
+# Create the objects
+Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
+Vy = geompy.MakeVectorDXDYDZ(0, 10, 0)
+Vz = geompy.MakeVectorDXDYDZ(0, 0, 10)
+origin = geompy.MakeVertex(0, 0, 0)
+
+# Register the objects in the active study
+geompy.addToStudy( Vx, "Vx" )
+geompy.addToStudy( Vy, "Vy" )
+geompy.addToStudy( Vz, "Vz" )
+geompy.addToStudy( origin, "origin" )
+
+
diff --git a/src/SalomeApp/pluginsdemo/tubebuilder.py b/src/SalomeApp/pluginsdemo/tubebuilder.py
new file mode 100644 (file)
index 0000000..5aedfe6
--- /dev/null
@@ -0,0 +1,143 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import salome
+
+DEFAULT_RADIUS = 100
+DEFAULT_LENGTH = 300
+DEFAULT_WIDTH  = 20
+
+from salome.geom import geomtools
+
+def createGeometry(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+    '''
+    This function creates the geometry on the specified study and with
+    given parameters.
+    '''
+    print "TUBE: creating the geometry ..."
+    studyId = study._get_StudyId()
+    geompy = geomtools.getGeompy(studyId)
+
+    radius_ext = radius
+    radius_int = radius_ext - width
+
+    CylinderExt = geompy.MakeCylinderRH(radius_ext, length)
+    CylinderInt = geompy.MakeCylinderRH(radius_int, length)
+    Tube = geompy.MakeCut(CylinderExt, CylinderInt)
+    return Tube
+    
+def createGeometryWithPartition(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+    '''
+    This function create the geometrical shape with a partition so
+    that the hexaedric algorithm could be used for meshing.
+    '''
+    shape = createGeometry(study,radius,length,width)
+
+    # We have to create a partition so that we can use an hexaedric
+    # meshing algorithm.
+    studyId = study._get_StudyId()
+    geompy = geomtools.getGeompy(studyId)
+
+    print "TUBE: creating a partition ..."
+    toolPlane = geompy.MakeFaceHW(2.1*length,2.1*radius,3)
+    partition = geompy.MakePartition([shape], [toolPlane], [], [], geompy.ShapeType["SOLID"], 0, [], 0)
+    entry = geompy.addToStudy( partition, "TubeWithPartition" )
+    return partition
+    
+def createMesh(study, shape):
+    '''This function creates the mesh of the specified shape on the specified study'''
+    print "TUBE: creating the mesh ..."
+    import smesh
+
+    smesh.SetCurrentStudy(study)
+    mesh = smesh.Mesh(shape)
+    Regular_1D = mesh.Segment()
+    Nb_Segments = Regular_1D.NumberOfSegments(10)
+    Nb_Segments.SetDistrType( 0 )
+    Quadrangle_2D = mesh.Quadrangle()
+    Hexa_3D = mesh.Hexahedron()
+
+    isDone = mesh.Compute()
+
+    if salome.sg.hasDesktop():
+        smesh.SetName(mesh.GetMesh(), 'TubeMesh')
+        smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+        smesh.SetName(Nb_Segments, 'Nb. Segments_1')
+        smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
+        smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D')
+        salome.sg.updateObjBrowser(0)
+
+    return mesh
+
+
+def createModel(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH,width=DEFAULT_WIDTH):
+    '''
+    This function create the geomtrical shape AND the associated mesh.
+    '''
+    # We first create a shape with a partition so that the hexaedric
+    # algorithm could be used.
+    shape = createGeometryWithPartition(study,radius,length,width)
+
+    # Then the mesh can be defined and computed
+    mesh = createMesh(study,shape)
+    
+def exportModel(mesh, filename):
+    '''
+    This exports the mesh to the specified filename in the med format
+    '''
+    print "TUBE: exporting mesh to file %s ..."%filename
+    import SMESH
+    mesh.ExportMED(filename, 0, SMESH.MED_V2_2, 1 )
+
+
+#
+# ===================================================================
+# Use cases and test functions
+# ===================================================================
+#
+def TEST_createGeometry():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    createGeometry(theStudy)
+
+def TEST_createMesh():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    shape = createGeometryWithPartition(theStudy)
+    mesh  = createMesh(theStudy, shape)
+
+def TEST_createModel():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    createModel(theStudy)
+
+def TEST_exportModel():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    shape = createGeometryWithPartition(theStudy)
+    mesh  = createMesh(theStudy, shape)
+    exportModel(mesh,"tubemesh.med")
+    
+if __name__ == "__main__":
+    #TEST_createGeometry()
+    #TEST_createMesh()
+    TEST_createModel()
+    #TEST_exportModel()
diff --git a/src/SalomeApp/pluginsdemo/tubedialog.py b/src/SalomeApp/pluginsdemo/tubedialog.py
new file mode 100644 (file)
index 0000000..09d3d8f
--- /dev/null
@@ -0,0 +1,117 @@
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import sys
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+from tubedialog_ui import TubeDialog_UI
+
+
+class TubeDialog(TubeDialog_UI):
+    def setupUi(self):
+        TubeDialog_UI.setupUi(self)
+        self.handleAcceptWith(self.accept)
+        self.handleRejectWith(self.reject)
+
+    def handleAcceptWith(self,callbackFunction):
+        """This defines the function to be connected to the signal 'accepted()' (click on Ok)"""
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), callbackFunction)
+
+    def handleRejectWith(self,callbackFunction):
+        """This defines the function to be connected to the signal 'rejected()' (click on Cancel)"""
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), callbackFunction)
+
+    def handleApplyWith(self,callbackFunction):
+        """This defines the function to be connected to the signal 'apply()' (click on Apply)"""
+        button = self.buttonBox.button(QtGui.QDialogButtonBox.Apply)        
+        QtCore.QObject.connect(button, QtCore.SIGNAL("clicked()"), callbackFunction);
+
+    def accept(self):
+        '''Callback function when dialog is accepted (click Ok)'''
+        self._wasOk = True
+        # We should test here the validity of values
+        QtGui.QDialog.accept(self)
+
+    def reject(self):
+        '''Callback function when dialog is rejected (click Cancel)'''
+        self._wasOk = False
+        QtGui.QDialog.reject(self)
+
+    def wasOk(self):
+        return self._wasOk
+
+    def setData(self, radius, length, width):
+        self.txtRadius.setText(str(radius))
+        self.txtLength.setText(str(length))
+        self.txtWidth.setText(str(width))
+
+    def getData(self):
+        try:
+            radius=eval(str(self.txtRadius.text()))
+            length=eval(str(self.txtLength.text()))
+            width=eval(str(self.txtWidth.text()))
+        except:
+            print "pb a la saisie"
+
+        return radius, length, width
+
+    
+class TubeDialogOnTopWithApply(TubeDialog):
+    def setupUi(self):
+        """
+        This setupUi adds a button 'Apply' to execute a processing
+        tasks (ex: preview), and set a flag that keeps the dialog on
+        top of all windows.
+        """
+        TubeDialog.setupUi(self)
+        # Add a button "Apply"
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|
+                                          QtGui.QDialogButtonBox.Apply|
+                                          QtGui.QDialogButtonBox.Ok)
+
+        # Keep the dialog on top of the windows
+        self.setWindowFlags(self.windowFlags() |
+                            QtCore.Qt.WindowStaysOnTopHint)
+
+
+#
+# ======================================================================
+# Unit test
+# ======================================================================
+#
+def TEST_getData_synchrone():
+    """This use case illustrates the MVC pattern on this simple dialog example""" 
+    tubedialog = TubeDialog()
+    tubedialog.setData(10,50,3)
+    tubedialog.exec_()
+    if tubedialog.wasOk():
+        radius, length, width = tubedialog.getData()
+        print radius, length, width
+
+
+def main( args ):
+    a = QtGui.QApplication(sys.argv)
+    TEST_getData_synchrone()
+    sys.exit(0)
+
+if __name__=="__main__":
+    main(sys.argv)
+
diff --git a/src/SalomeApp/pluginsdemo/tubedialog_ui.py b/src/SalomeApp/pluginsdemo/tubedialog_ui.py
new file mode 100644 (file)
index 0000000..de6ec8b
--- /dev/null
@@ -0,0 +1,107 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import sys
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+
+class TubeDialog_UI(QtGui.QDialog):
+    """
+    This class defines the design of a Qt dialog box dedicated to the
+    salome plugin examples. It presents a UI form that contains
+    parameters for the spatial dimensions of geometrical object.  
+    """
+    def __init__(self, parent=None):
+        QtGui.QDialog.__init__(self, parent)
+        self.setupUi()
+
+    def setupUi(self):
+        self.setObjectName("Dialog")
+        self.resize(400, 300)
+        self.hboxlayout = QtGui.QHBoxLayout(self)
+        self.hboxlayout.setMargin(9)
+        self.hboxlayout.setSpacing(6)
+        self.hboxlayout.setObjectName("hboxlayout")
+        self.vboxlayout = QtGui.QVBoxLayout()
+        self.vboxlayout.setMargin(0)
+        self.vboxlayout.setSpacing(6)
+        self.vboxlayout.setObjectName("vboxlayout")
+        self.hboxlayout1 = QtGui.QHBoxLayout()
+        self.hboxlayout1.setMargin(0)
+        self.hboxlayout1.setSpacing(6)
+        self.hboxlayout1.setObjectName("hboxlayout1")
+        self.vboxlayout1 = QtGui.QVBoxLayout()
+        self.vboxlayout1.setMargin(0)
+        self.vboxlayout1.setSpacing(6)
+        self.vboxlayout1.setObjectName("vboxlayout1")
+        self.lblRadius = QtGui.QLabel(self)
+        self.lblRadius.setObjectName("lblRadius")
+        self.vboxlayout1.addWidget(self.lblRadius)
+        self.lblLength = QtGui.QLabel(self)
+        self.lblLength.setObjectName("lblLength")
+        self.vboxlayout1.addWidget(self.lblLength)
+        self.lblWidth = QtGui.QLabel(self)
+        self.lblWidth.setObjectName("lblWidth")
+        self.vboxlayout1.addWidget(self.lblWidth)
+        self.hboxlayout1.addLayout(self.vboxlayout1)
+        self.vboxlayout2 = QtGui.QVBoxLayout()
+        self.vboxlayout2.setMargin(0)
+        self.vboxlayout2.setSpacing(6)
+        self.vboxlayout2.setObjectName("vboxlayout2")
+        self.txtRadius = QtGui.QLineEdit(self)
+        self.txtRadius.setObjectName("txtRadius")
+        self.vboxlayout2.addWidget(self.txtRadius)
+        self.txtLength = QtGui.QLineEdit(self)
+        self.txtLength.setObjectName("txtLength")
+        self.vboxlayout2.addWidget(self.txtLength)
+        self.txtWidth = QtGui.QLineEdit(self)
+        self.txtWidth.setObjectName("txtWidth")
+        self.vboxlayout2.addWidget(self.txtWidth)
+        self.hboxlayout1.addLayout(self.vboxlayout2)
+        self.vboxlayout.addLayout(self.hboxlayout1)
+        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.vboxlayout.addItem(spacerItem)
+        self.buttonBox = QtGui.QDialogButtonBox(self)
+        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
+        self.buttonBox.setObjectName("buttonBox")
+        self.vboxlayout.addWidget(self.buttonBox)
+        self.hboxlayout.addLayout(self.vboxlayout)
+
+        self.setWindowTitle("Tube construction")
+        self.lblRadius.setText("Rayon")
+        self.lblLength.setText("Longueur")
+        self.lblWidth.setText("Epaisseur")
+
+#
+# ======================================================================
+# Unit test
+# ======================================================================
+#
+def main( args ):
+    a = QtGui.QApplication(sys.argv)
+    tubedialog = TubeDialog_UI()
+    sys.exit(tubedialog.exec_())
+
+if __name__=="__main__":
+    main(sys.argv)
+
diff --git a/src/SalomeApp/pluginsdemo/xalome.py b/src/SalomeApp/pluginsdemo/xalome.py
new file mode 100644 (file)
index 0000000..724afa4
--- /dev/null
@@ -0,0 +1,229 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+#
+# XALOME means "eXtension for sALOME. This module contains specific
+# helper functions that extends salome for the needs of the salome
+# plugin examples, or hide some complex technical parts of SALOME to
+# ease the global understanding of the examples.
+#
+# (gboulant - 09/02/2012)
+#
+import salome
+from salome.kernel.studyedit import getStudyEditor
+from salome.kernel.services import IDToSObject, IDToObject
+from salome.geom import geomtools
+
+# ======================================================================
+# Helper functions to add/remove a geometrical shape in/from the study
+# ======================================================================
+
+def addToStudy(study,shape,shapeName,folderName=None):
+    """
+    Add a GEOM shape in the study. It returns the associated entry
+    that corresponds to the identifier of the entry in the study. This
+    entry can be used to retrieve an object in the study. A folderName
+    can be specified. In this case, a folder with this name is first
+    created in the Geometry part of the study, and the shape study
+    object is stored in this folder of the study. 
+    """
+    studyId = study._get_StudyId()
+    geompy = geomtools.getGeompy(studyId)
+
+    if folderName is None:
+        # Insert the shape in the study by the standard way
+        entry = geompy.addToStudy( shape, shapeName )
+    else:
+        # A folder name has been specified to embed this shape. Find
+        # or create a folder with this name in the Geometry study, and
+        # then store the shape in this folder.
+        studyEditor = getStudyEditor(studyId)
+        geomStudyFolder = studyEditor.findOrCreateComponent("GEOM")
+        shapeStudyFolder = studyEditor.findOrCreateItem(geomStudyFolder,folderName)
+
+        shapeIor = salome.orb.object_to_string(shape)
+        geomgui = salome.ImportComponentGUI("GEOM")
+        shapeIcon = geomgui.getShapeTypeIcon(shapeIor)
+
+        shapeStudyObject = studyEditor.createItem(shapeStudyFolder,
+                                                  name=shapeName,
+                                                  IOR=shapeIor,
+                                                  icon=shapeIcon)
+        entry = shapeStudyObject.GetID()
+
+    return entry
+
+def removeFromStudy(study,shapeStudyEntry):
+    """
+    This removes the specified entry from the study. Note that this
+    operation does not destroy the underlying GEOM object, neither
+    erase the drawing in the viewer.
+    The underlying GEOM object is returned (so that it can be destroyed)
+    """
+    studyId = study._get_StudyId()
+    shape = IDToObject(shapeStudyEntry)    
+    studyObject = IDToSObject(shapeStudyEntry)
+    studyEditor = getStudyEditor(studyId)
+    studyEditor.removeItem(studyObject,True)
+    return shape
+
+
+# ======================================================================
+# Helper functions to display/erase a shape in/from the viewer. The
+# shape must be previously put in the study and the study entry must
+# be known.
+# ======================================================================
+
+ModeShading = 1
+DisplayMode=ModeShading
+PreviewColor=[236,163,255]
+def displayShape(shapeStudyEntry, color=None):
+    """This displays the shape specified by its entry in the study"""
+    geomgui = salome.ImportComponentGUI("GEOM")            
+    geomgui.createAndDisplayFitAllGO(shapeStudyEntry)
+    geomgui.setDisplayMode(shapeStudyEntry, DisplayMode)
+    if color is not None:
+        geomgui.setColor(shapeStudyEntry, color[0], color[1], color[2])
+
+def eraseShape(shapeStudyEntry):
+    """
+    This erases from the viewers the shape specified by its study
+    entry.
+    """
+    geomgui = salome.ImportComponentGUI("GEOM")
+    eraseFromAllWindows=True
+    geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows)
+
+# Available in SALOME 6.5 only
+def displayShape_version65(shapeStudyEntry):
+    gst = geomtools.GeomStudyTools()
+    gst.displayShapeByEntry(shapeStudyEntry)
+
+def eraseShape_version65(shapeStudyEntry):
+    gst = geomtools.GeomStudyTools()
+    gst.eraseShapeByEntry(shapeStudyEntry)
+
+
+# ======================================================================
+# Helper functions for a complete suppression of a shape from the
+# SALOME session.
+# ======================================================================
+def deleteShape(study,shapeStudyEntry):
+    """
+    This completly deletes a geom shape.
+
+    WARNING: please be aware that to delete a geom object, you have
+    three operations to perform:
+
+    1. erase the shape from the viewers
+    2. remove the entry from the study
+    3. destroy the underlying geom object
+    """
+    eraseShape(shapeStudyEntry)
+    shape = removeFromStudy(study, shapeStudyEntry)
+    if shape is not None:
+      shape.Destroy()
+    
+
+#
+# ======================================================================
+# Unit tests
+# ======================================================================
+#
+# To experiment this unit test, just execute this script in
+# SALOME. The script is self-consistent.
+
+def TEST_createAndDeleteShape():
+    """
+    This test is a simple use case that illustrates how to create a
+    GEOM shape in a SALOME session (create the GEOM object, put in in
+    the study, and display the shape in a viewer) and delete a shape
+    from a SALOME session (erase the shape from the viewer, delete the
+    entry from the study, and finally destroy the underlying GEOM
+    object).
+    """
+    import salome
+    salome.salome_init()
+    study   = salome.myStudy
+    studyId = salome.myStudyId
+
+    from salome.geom import geomtools
+    geompy = geomtools.getGeompy(studyId)
+
+    # --------------------------------------------------
+    # Create a first shape (GEOM object)
+    radius = 5
+    length = 100
+    cylinder = geompy.MakeCylinderRH(radius, length)
+
+    # Register the shape in the study, at the root of the GEOM
+    # folder. A name must be specified. The register operation
+    # (addToStudy) returns an identifier of the entry in the study.
+    cylinderName = "cyl.r%s.l%s"%(radius,length)
+    cylinderStudyEntry = addToStudy(study, cylinder, cylinderName)
+
+    # Display the registered shape in a viewer
+    displayShape(cylinderStudyEntry)
+
+    # --------------------------------------------------
+    # A second shape
+    radius = 10
+    sphere = geompy.MakeSphereR(radius)
+    sphereName = "sph.r%s"%radius
+    sphereStudyEntry = addToStudy(study, sphere, sphereName)
+    displayShape(sphereStudyEntry)
+
+    # --------------------------------------------------
+    # This new shape is stored in the study, but in a specific
+    # sub-folder, and is displayed in the viewer with a specific
+    # color.
+    length = 20
+    box = geompy.MakeBoxDXDYDZ(length,length,length)
+    boxName = "box.l%s"%length
+    folderName = "boxset" 
+    boxStudyEntry = addToStudy(study, box, boxName, folderName)
+    displayShape(boxStudyEntry,PreviewColor)
+
+    # --------------------------------------------------
+    # In this example, we illustrate how to erase a shape (the sphere)
+    # from the viewer. After this operation, the sphere is no longer
+    # displayed but still exists in the study. You can then redisplay
+    # it using the context menu of the SALOME object browser.
+    eraseShape(sphereStudyEntry)
+
+    # --------------------------------------------------
+    # In this last example, we completly delete an object from the
+    # SALOME session (erase from viewer, remove from study and finnaly
+    # destroy the object). This is done by a simple call to
+    # deleteShape().
+    deleteShape(study,cylinderStudyEntry)
+
+    # --------------------------------------------------
+    # At the end of the executioon of this test, you should have in
+    # the SALOME session:
+    # - the box, in a dedicated folder of the study, and displayed in the viewer
+    # - the sphere, in the standard place of the study, and not displayed 
+
+    # If you comment the deleteShape line, you should see the cylinder
+    # in the study and displayed in the viewer. 
+
+if __name__=="__main__":
+    TEST_createAndDeleteShape()
diff --git a/src/TreeData/DataModel.cxx b/src/TreeData/DataModel.cxx
new file mode 100644 (file)
index 0000000..c08d07f
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DataModel.hxx"
+
+DataModel::DataModel() {
+
+}
+
+DataModel::~DataModel() {
+  _mapDataObjects.clear();
+}
+
+bool DataModel::addDataObject(DataObject * dataObject) {
+  _mapDataObjects[dataObject->getNameId()] = dataObject;
+  return true;
+}
+bool DataModel::removeDataObject(string nameId) {
+  _mapDataObjects.erase(nameId);
+  return true;
+}
+bool DataModel::removeDataObject(DataObject * dataObject) {
+  if ( dataObject == NULL ) return false;
+  return removeDataObject(dataObject->getNameId());
+}
+
+DataObject * DataModel::getDataObject(string id) {
+  return _mapDataObjects[id];
+}
+
+
+
+map<string, DataObject *>::iterator DataModel::begin() {
+  return _mapDataObjects.begin();
+}
+
+map<string, DataObject *>::iterator DataModel::end() {
+  return _mapDataObjects.end();
+}
diff --git a/src/TreeData/DataModel.hxx b/src/TreeData/DataModel.hxx
new file mode 100644 (file)
index 0000000..c30a1e3
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef DATAMODEL_H
+#define DATAMODEL_H
+
+#include "TreeData.hxx"
+
+#include <map>
+#include "DataObject.hxx"
+
+class TREEDATA_EXPORT DataModel {
+
+public:
+  DataModel();
+  ~DataModel();
+
+  /*!
+   * This function can be used to create a specific instance of
+   * DataObject. Note that this function is a pure virtual method and
+   * then no default behavior is done. In particular, the newly
+   * created object is not automatically added to the data model. This
+   * behavior should be implemented in a dedicated version of this
+   * class.
+   */
+  virtual DataObject * newDataObject() = 0;
+
+  /*! Function to add data object to the model */
+  bool addDataObject(DataObject * dataObject);
+  /*! Functions to remove data object from the model */
+  bool removeDataObject(string nameId);
+  bool removeDataObject(DataObject * dataObject);
+  /*! Function to retrieve a data object in the model */
+  DataObject * getDataObject(string nameId);
+
+  map<string, DataObject *>::iterator begin();
+  map<string, DataObject *>::iterator end();
+
+private:
+  map<string, DataObject *> _mapDataObjects;
+  
+
+};
+
+#endif // DATAMODEL_H
diff --git a/src/TreeData/DataObject.cxx b/src/TreeData/DataObject.cxx
new file mode 100644 (file)
index 0000000..d8be9ea
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DataObject.hxx"
+#include <Basics_Utils.hxx>
+
+// Static assignement
+int DataObject::_lastId=0;
+const string DataObject::_BASENAME = string("object_");
+const string DataObject::pathsep = string("/");
+
+DataObject::DataObject() {
+  _nameId = _BASENAME+ToString(_lastId);
+  _lastId++;
+  // The default label is set to the nameId, but it can be modified
+  // using setLabel whereas the nameId can't be modified.
+  _label  = _nameId;
+}
+
+DataObject::~DataObject() {
+  _properties.clear();
+}
+
+void DataObject::setLabel(string label) {
+  _label = label;
+}
+string DataObject::getLabel() {
+  return _label;
+}
+
+string DataObject::getPathName() {
+  string pathName;
+  pathName = this->getPath() + pathsep + this->getLabel();
+  return pathName;
+}
+
+
+string DataObject::getNameId() {
+  return _nameId;
+}
+
+void DataObject::setProperty(string key, string value) {
+  _properties[key] = value;
+}
+string DataObject::getProperty(string key) {
+  return _properties[key];
+}
+
+string DataObject::toString() {
+  string serialize="\n";
+  serialize+="nameId = "+getNameId()+"\n";
+  serialize+="label  = "+getLabel()+"\n";
+  serialize+="path   = "+getPath();
+  return serialize;
+}
diff --git a/src/TreeData/DataObject.hxx b/src/TreeData/DataObject.hxx
new file mode 100644 (file)
index 0000000..089b36f
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef DATAOBJECT_H
+#define DATAOBJECT_H
+
+#include "TreeData.hxx"
+
+#include <map>
+#include <string>
+using namespace std;
+
+class TREEDATA_EXPORT DataObject {
+
+public:
+  DataObject();
+  ~DataObject();
+
+  void setLabel(string label);
+  string getLabel();
+  void setProperty(string key, string value);
+  string getProperty(string key);
+
+  /*!
+   * This function specifies the localization of the object in the
+   * hierarchical organization that can be defined by the DataModel it
+   * belongs to.
+   */
+  virtual string getPath() = 0;
+  string getPathName();
+  string getNameId();
+
+  static const string pathsep;
+
+  /*! This function can be used for debug */
+  string toString();
+
+private:
+  /*! The name this object can be displayed with */
+  string _label;
+  /*! The identifier of this object. An identifier is invariant all the session long */
+  string _nameId;
+  /*! The dictionnary of properties that characterize this object */
+  map<string, string> _properties;
+
+  static int _lastId;
+  static const string _BASENAME;
+};
+
+#endif // DATAOBJECT_H
diff --git a/src/TreeData/DataProcessor.cxx b/src/TreeData/DataProcessor.cxx
new file mode 100644 (file)
index 0000000..ac52d5e
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include "DataProcessor.hxx"
+#include <Basics_Utils.hxx>
+#include "QtHelper.hxx"
+
+DataProcessor::DataProcessor(DataModel * dataModel) {
+  _dataModel = dataModel;
+}
+
+/*!
+ * This function retrieves in the data model all the DataObject
+ * associated to the item nameIds contained in the specified list. The
+ * input list is what the TreeView sends via the notification signal.
+ */
+DataObjectVector * DataProcessor::extract(QStringList itemNameIdList) {
+  if ( _dataModel == NULL ) {
+    STDLOG("No data model associated to this processor");
+    return NULL;
+  }
+
+  DataObjectVector * dataObjectList = new DataObjectVector();
+
+  // We can request the dataModel to obtain the dataObject associated
+  // to each of the item (iteNameId is a TreeView id, Qt stuff only).
+  QStringList::const_iterator it;
+  for (it = itemNameIdList.constBegin(); it != itemNameIdList.constEnd(); ++it) {
+    QString itemNameId = *it;
+    DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+    
+    if ( dataObject != NULL ) {
+      dataObjectList->push_back(dataObject);
+    } else {
+      LOG("No data object associated to the item "<<itemNameId);
+    } 
+  }
+  return dataObjectList;
+}
+
+
+void DataProcessor::process(QStringList itemNameIdList) {
+  if ( _dataModel == NULL ) {
+    STDLOG("No data model");
+    return;
+  }
+
+  this->preprocess(itemNameIdList);
+
+  // We can request the dataModel to obtain the dataObject associated
+  // to each of the item (iteNameId is a TreeView id, Qt stuff only).
+  QStringList::const_iterator it;
+  for (it = itemNameIdList.constBegin(); it != itemNameIdList.constEnd(); ++it) {
+    QString itemNameId = *it;
+    DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+    
+    if ( dataObject != NULL ) {
+      this->processDataObject(dataObject);
+    } else {
+      STDLOG("No data object associated to the item "<<QS2S(itemNameId));
+    } 
+  }
+
+  this->postprocess(itemNameIdList);
+}
+
+
diff --git a/src/TreeData/DataProcessor.hxx b/src/TreeData/DataProcessor.hxx
new file mode 100644 (file)
index 0000000..4798598
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _DATAPROCESSOR_H_
+#define _DATAPROCESSOR_H_
+
+#include "TreeData.hxx"
+
+#include "DataModel.hxx"
+#include "DataObject.hxx"
+#include <QStringList>
+#include <QString>
+
+#include <vector>
+typedef std::vector<DataObject *> DataObjectVector;
+
+//
+// =================================================================
+// This class can be used to automize processing on data objects.
+// The inputs of public functions are list of selected items in the
+// tree view. The function automize the extraction of associated
+// DataObject and can automize the processing of these object if the
+// virtual function processDataObject is implemented.
+// =================================================================
+//
+
+class TREEDATA_EXPORT DataProcessor {
+
+public:
+  DataProcessor(DataModel * dataModel);
+
+  DataObjectVector * extract(QStringList itemNameIdList);
+  void               process(QStringList itemNameIdList);
+
+  
+protected:
+  virtual void preprocess(QStringList itemNameIdList) {
+      // Implement something to be executed at the begining of the process function
+  };
+  virtual void postprocess(QStringList itemNameIdList) {
+      // Implement something to be executed at the end of the process function
+  };
+  // Implement what must be done with each DataObject during the process function
+  virtual void processDataObject(DataObject * dataObject) = 0;
+
+private:
+  DataModel * _dataModel;
+};
+
+#endif
diff --git a/src/TreeData/DockWidgets.cxx b/src/TreeData/DockWidgets.cxx
new file mode 100644 (file)
index 0000000..fcb4e18
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DockWidgets.hxx"
+
+// Qt includes
+#include <QMainWindow>
+
+// SALOME includes
+#include <SUIT_Desktop.h>
+#include <SUIT_DataBrowser.h>
+#include <QtxTreeView.h>
+
+/*!
+ * This create a gui container to hold widgets dedicated to the XCAD
+ * data model. By default, the dock widgets are not visible. Use the
+ * show() method to control the visibility (usefull when activating
+ * and desactivating the module to show/hide the dock widgets).
+ *
+ * This class does not make any hypothesis on what will be embedded in
+ * the dock widgets (only that it is QTreeView). The QTreeView is
+ * defined elsewhere and is generaly rendering a tree model containing
+ * tree items.
+ */
+DockWidgets::DockWidgets(SalomeApp_Application* salomeApp,
+                        bool tabify,
+                        const char * title) {
+  _salomeApp = salomeApp;
+
+  QMainWindow *parent = _salomeApp->desktop();
+  _dwDataPanel = new QDockWidget(parent);
+  _dwDataPanel->setVisible(false);
+  _dwDataPanel->setWindowTitle(title);
+  parent->addDockWidget(Qt::LeftDockWidgetArea, _dwDataPanel);
+  //
+  // At this step, the _dwDataPanel is located side by side with the object
+  // browser (or one over the other).
+  //
+  // It is possible to tabify the different dock widgets in one single
+  // tabbed widget. See the above example:
+  this->tabify(tabify);
+}
+
+void DockWidgets::tabify(bool tabify) {
+  if ( tabify ) {    
+    // We first get the object browser tree view, and then the
+    // associated DockWidget. Note that the tree view is a SALOME
+    // specific extention of the originate QTreeView and called
+    // QtxTreeView.
+    SUIT_DataBrowser* objectBrowser = _salomeApp->objectBrowser();
+    QtxTreeView* treeView = objectBrowser->treeView();
+    QWidget* pw = treeView->parentWidget();
+    QDockWidget* dwObjectBrowser = 0;
+    while ( pw && !dwObjectBrowser ) {
+      dwObjectBrowser = ::qobject_cast<QDockWidget*>( pw );
+      pw = pw->parentWidget();
+    };
+    QMainWindow *parent = _salomeApp->desktop();
+    parent->tabifyDockWidget(_dwDataPanel, dwObjectBrowser);
+    parent->setTabOrder(_dwDataPanel, dwObjectBrowser);
+    parent->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
+  }
+  else {
+    // TO BE IMPLEMENTED
+  }
+}
+
+/*!
+ * This function controls the visibility of the dock widgets.
+ */
+void DockWidgets::show(bool isVisible) {
+  _dwDataPanel->setVisible(isVisible);
+}
+
+/*!
+ * This function initializes the central part of the dock widget with
+ * a tree view that can hold a hierarchical data model.
+ */
+void DockWidgets::setDataView(QTreeView * dataView) {
+  _tvDataView = dataView;
+  _tvDataView->setParent(_dwDataPanel);
+  _tvDataView->setMinimumHeight(200);
+  _dwDataPanel->setWidget(_tvDataView);
+}
+
+void DockWidgets::setPropertiesView(QTreeView * propertiesView) {
+  // Not implemented yet
+}
diff --git a/src/TreeData/DockWidgets.hxx b/src/TreeData/DockWidgets.hxx
new file mode 100644 (file)
index 0000000..2c5847d
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _DOCKWIDGETS_H_
+#define _DOCKWIDGETS_H_
+
+#include "TreeData.hxx"
+
+// Qt includes
+#include <QDockWidget>
+#include <QTreeView>
+
+// SALOME includes
+#include <SalomeApp_Application.h>
+
+class TREEDATA_EXPORT DockWidgets {
+ public:
+  DockWidgets(SalomeApp_Application* salomeApp,
+        bool tabify=false,
+        const char * title="Data Model");
+
+  void tabify(bool tabify);
+  void show(bool isVisible);
+  void setDataView(QTreeView * dataView);
+  void setPropertiesView(QTreeView * propertyView);
+
+ private:
+  SalomeApp_Application* _salomeApp;
+  QDockWidget * _dwDataPanel;
+  QTreeView * _tvDataView;
+};
+
+#endif // _DOCKWIDGETS_H_
diff --git a/src/TreeData/Makefile.am b/src/TreeData/Makefile.am
new file mode 100644 (file)
index 0000000..99998ac
--- /dev/null
@@ -0,0 +1,107 @@
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF) 
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+SUBDIRS = . Test
+
+# moc-files generation
+%_moc.cxx: %.hxx
+       $(MOC) $< -o $@
+
+mostlyclean-local:
+       rm -f @builddir@/*_moc.cxx
+       rm -f @builddir@/*.qm
+
+# Libraries targets
+lib_LTLIBRARIES = libSalomeTreeData.la
+
+#
+# Generic source files
+#
+salomeinclude_HEADERS = \
+       TreeData.hxx \
+       DockWidgets.hxx \
+       TreeModel.hxx \
+       TreeItem.hxx \
+       TreeView.hxx \
+       TreeObserver.hxx \
+       DataModel.hxx \
+       DataObject.hxx \
+       DataProcessor.hxx \
+       TreeGuiManager.hxx
+
+dist_libSalomeTreeData_la_SOURCES = \
+       DockWidgets.cxx \
+       TreeModel.cxx \
+       TreeItem.cxx \
+       TreeView.cxx \
+       TreeObserver.cxx \
+       DataModel.cxx \
+       DataObject.cxx \
+       DataProcessor.cxx \
+       TreeGuiManager.cxx
+
+# MOC pre-processing
+MOC_FILES_HXX = \
+       TreeModel_moc.cxx \
+       TreeView_moc.cxx \
+       TreeObserver_moc.cxx
+
+nodist_libSalomeTreeData_la_SOURCES = $(MOC_FILES_HXX)
+
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+CAS_CXXFLAGS=@CAS_CPPFLAGS@ @CAS_CXXFLAGS@
+
+BOOST_CPPFLAGS=@BOOST_CPPFLAGS@
+BOOST_LIBS=@BOOST_LIBS@
+
+libSalomeTreeData_la_CPPFLAGS = \
+       $(QT_CXXFLAGS) \
+       $(CAS_CXXFLAGS) \
+       $(BOOST_CPPFLAGS) \
+       $(CORBA_CXXFLAGS) \
+       $(KERNEL_CXXFLAGS) \
+       -I$(srcdir)/../SalomeApp \
+       -I$(srcdir)/../LightApp  \
+       -I$(srcdir)/../CAM  \
+       -I$(srcdir)/../STD \
+       -I$(srcdir)/../ObjBrowser \
+       -I$(srcdir)/../SUIT \
+       -I$(srcdir)/../Qtx \
+       -I$(srcdir)/../GuiHelpers
+
+
+
+
+libSalomeTreeData_la_LDFLAGS  = \
+       $(CORBA_LIBS) $(QT_LIBS)\
+       $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeKernelHelpers \
+       $(top_builddir)/src/SalomeApp/libSalomeApp.la \
+       $(top_builddir)/src/LightApp/libLightApp.la \
+       $(top_builddir)/src/SUIT/libsuit.la \
+       $(top_builddir)/src/Qtx/libqtx.la \
+       $(top_builddir)/src/CAM/libCAM.la \
+       $(top_builddir)/src/STD/libstd.la \
+       $(top_builddir)/src/ObjBrowser/libObjBrowser.la
diff --git a/src/TreeData/Test/Makefile.am b/src/TreeData/Test/Makefile.am
new file mode 100644 (file)
index 0000000..8d6141e
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF) 
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# moc-files generation
+%_moc.cxx: %.hxx
+       $(MOC) $< -o $@
+
+mostlyclean-local:
+       rm -f @builddir@/*_moc.cxx
+       rm -f @builddir@/*.qm
+       rm -f @builddir@/*_moc.cxx @builddir@/ui_*.h
+
+# qt forms files generation (uic)
+ui_%.h: %.ui
+       $(UIC) -o $@ $<
+
+
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+
+TEST_CPPFLAGS = \
+       $(QT_CXXFLAGS) \
+       $(CORBA_CXXFLAGS) \
+       $(KERNEL_CXXFLAGS) \
+       -I$(top_srcdir)/src/GuiHelpers \
+       -I$(top_srcdir)/src/TreeData \
+       -I.
+
+TEST_LDFLAGS  = \
+       $(CORBA_LIBS) $(QT_LIBS) \
+       $(top_builddir)/src/TreeData/libSalomeTreeData.la \
+       $(top_builddir)/src/GuiHelpers/libSalomeGuiHelpers.la \
+       $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeKernelHelpers
+
+# Program targets
+bin_PROGRAMS = TreeData_guitester TreeData_tester
+
+MOC_FILES_HXX = \
+       mainwindow_moc.cxx
+
+UIC_FILES = \
+       ui_mainwindow.h
+
+BUILT_SOURCES = $(UIC_FILES)
+
+nodist_TreeData_guitester_SOURCES = $(MOC_FILES_HXX) $(UIC_FILES)
+
+TreeData_guitester_SOURCES = \
+       testhelper.hxx \
+       testhelper.cxx \
+       guitester.cxx \
+       mainwindow.hxx \
+       mainwindow.cxx \
+       MyDataModel.hxx \
+       MyDataModel.cxx
+
+TreeData_guitester_CPPFLAGS = \
+       $(TEST_CPPFLAGS)
+
+TreeData_guitester_LDFLAGS = \
+       $(TEST_LDFLAGS)
+
+TreeData_tester_SOURCES = \
+       tester.cxx \
+       MyDataModel.cxx
+
+TreeData_tester_CPPFLAGS = \
+       $(TEST_CPPFLAGS)
+
+TreeData_tester_LDFLAGS = \
+       $(TEST_LDFLAGS)
+
+# test data files
+testdir = $(salomeresdir)/testdata
+test_DATA = \
+       data.txt
+
+EXTRA_DIST+=$(test_DATA)
diff --git a/src/TreeData/Test/MyDataModel.cxx b/src/TreeData/Test/MyDataModel.cxx
new file mode 100644 (file)
index 0000000..731c8fd
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MyDataModel.hxx"
+
+//
+// =================================================================
+// MyDataObject implementation
+// =================================================================
+//
+
+const string MyDataObject::PROPERTY_KEY_TYPE    = "type";
+const string MyDataObject::PROPERTY_KEY_CIRCUIT ="circuit";
+const string MyDataObject::PROPERTY_KEY_REPFONC ="rf";
+
+MyDataObject::MyDataObject() : DataObject() {
+  this->setProperty(PROPERTY_KEY_TYPE, "Tuyauterie");
+  this->setProperty(PROPERTY_KEY_CIRCUIT,"RRA");
+  this->setProperty(PROPERTY_KEY_REPFONC,"RF_01");
+}
+
+/*! This function specified the localization of the object in the
+ * hierarchical organization
+ */
+string MyDataObject::getPath() {
+  // We choose here a convention for organizing the path for this
+  // class of object.
+  /*
+  string path = getProperty(PROPERTY_KEY_CIRCUIT) + pathsep
+    + getProperty(PROPERTY_KEY_REPFONC) + pathsep
+    + getProperty(PROPERTY_KEY_TYPE);
+  */
+  string path = getProperty(PROPERTY_KEY_TYPE) + pathsep
+    + getProperty(PROPERTY_KEY_CIRCUIT) + pathsep
+    + getProperty(PROPERTY_KEY_REPFONC);
+    
+  return path;
+}
+
+//
+// =================================================================
+// MyDataModel implementation
+// =================================================================
+//
+MyDataModel::MyDataModel() : DataModel() {
+}
+
+DataObject * MyDataModel::newDataObject() {
+  MyDataObject * dataObject = new MyDataObject();
+  return dataObject;
+}
diff --git a/src/TreeData/Test/MyDataModel.hxx b/src/TreeData/Test/MyDataModel.hxx
new file mode 100644 (file)
index 0000000..cf53955
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _MYDATAMODEL_H_
+#define _MYDATAMODEL_H_
+
+//
+// =================================================================
+// Definition of an atom in the data model as an implementation of
+// the virtual class DataObject
+// =================================================================
+//
+
+#include "DataObject.hxx"
+class MyDataObject: public DataObject {
+public:
+  MyDataObject();
+  virtual string getPath();
+  static const string PROPERTY_KEY_TYPE;
+  static const string PROPERTY_KEY_CIRCUIT;
+  static const string PROPERTY_KEY_REPFONC;
+};
+
+
+//
+// =================================================================
+// Definition of the data model as an implementation of the virtual
+// class DataModel. It implements the DataObject factory.
+// =================================================================
+//
+#include "DataModel.hxx"
+class MyDataModel: public DataModel {
+public:
+  MyDataModel();
+  virtual DataObject * newDataObject();
+};
+
+#endif // _MYDATAMODEL_H_
diff --git a/src/TreeData/Test/data.txt b/src/TreeData/Test/data.txt
new file mode 100755 (executable)
index 0000000..d28285b
--- /dev/null
@@ -0,0 +1,15 @@
+Tuyauterie;RF1;T1\r
+Tuyauterie;RF1;T2\r
+Tuyauterie;RF1;T3\r
+Tuyauterie;RF2;T1\r
+Tuyauterie;RF3;T1\r
+Tuyauterie;RF3;T2\r
+Composansts;RF1;T1\r
+Composansts;RF1;T2\r
+Composansts;RF3;T2\r
+Genie Civil;RF1;T1\r
+Genie Civil;RF1;T2\r
+Genie Civil;RF1;T3\r
+Genie Civil;RF2;T1\r
+Genie Civil;RF3;T1\r
+Genie Civil;RF3;T2\r
diff --git a/src/TreeData/Test/guitester.cxx b/src/TreeData/Test/guitester.cxx
new file mode 100644 (file)
index 0000000..c2e45d8
--- /dev/null
@@ -0,0 +1,221 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <QApplication>
+#include <QMainWindow>
+#include <QDockWidget>
+#include <QTreeView>
+
+#include <Basics_Utils.hxx>
+
+//
+// =================================================================
+// Generic helper functions
+// =================================================================
+//
+/*!
+ * This functions displays a main window that embeds the specified
+ * widget. A dockwidget is used to create a context similar to as the
+ * SALOME target context.
+ */
+void showWidget(QWidget * widget) {
+
+  QMainWindow * window = new QMainWindow();
+
+  // Prepare a gui framework for testing the widget. We use a
+  // dockwidget, just to be in a context similar to as the SALOME
+  // target context.
+  QDockWidget * dwDataPanel = new QDockWidget(window);
+  dwDataPanel->setVisible(true);
+  dwDataPanel->setWindowTitle("XCAD data model");
+  window->addDockWidget(Qt::LeftDockWidgetArea, dwDataPanel);
+
+  // Then plug the widget in the dock widget framework:
+  widget->setParent(dwDataPanel);
+  widget->setMinimumHeight(300);
+  dwDataPanel->setWidget(widget);
+
+  window->show();
+}
+
+//
+// =================================================================
+// Tests functions for TreeModel
+// =================================================================
+//
+#include "TreeModel.hxx"
+#include "MyDataModel.hxx"
+#include "testhelper.hxx"
+
+
+/*!
+ * This function fills the specified tree with data that show
+ * different levels of path in the tree.
+ */
+void _TEST_treemodel_addData_01(TreeModel * dataTreeModel) {
+  // We can first add categories (for example to set categories
+  // properties)
+  QStringList path;
+  DataObject * folder;
+
+  path << "folder_1";
+  folder = TESTHELPER_dummyObject("folder_1.1");
+  dataTreeModel->addData(folder, path);
+  folder = TESTHELPER_dummyObject("folder_1.2");
+  dataTreeModel->addData(folder, path);
+
+  path.clear();
+  path << "folder_2";
+  folder = TESTHELPER_dummyObject("folder_2.1");
+  dataTreeModel->addData(folder, path);
+  
+  // Then we can add data
+  DataObject * data;
+  path.clear();
+  path << "folder_1" << "folder_1.1";
+  data = TESTHELPER_dummyObject("data_1.1.1");
+  dataTreeModel->addData(data, path);
+  data = TESTHELPER_dummyObject("data_1.1.2");
+  dataTreeModel->addData(data, path);
+  // You can notice that there is no conceptual difference between a
+  // folder and an item, as in the QTreeModel.
+  
+  // No limit to the depth
+  path.clear();
+  path << "xcad" << "data1" << "x" << "y";
+  data = TESTHELPER_dummyObject("z");
+  dataTreeModel->addData(data,path);
+}
+
+#define LOOPSIZE 15
+/*!
+ * This function fills the specified tree with a huge amount of data
+ */
+void _TEST_treemodel_addData_02(TreeModel * dataTreeModel) {
+  QStringList path;
+  DataObject * data;
+  
+  START_TIMING(treemodel);
+  for (int i=0; i<LOOPSIZE; i++) {
+    END_TIMING(treemodel,1);
+    for (int j=0; j<LOOPSIZE; j++) {
+      for (int k=0; k<LOOPSIZE; k++) {
+        // The data list corresponds to the path of the item in the tree
+        path << QString("folder_%0").arg(i)
+             << QString("subfolder_%0_%1").arg(i).arg(j);
+        data = TESTHELPER_dummyObject(QString("item_%0_%1_%2").arg(i).arg(j).arg(k));
+        dataTreeModel->addData(data,path);
+        path.clear();
+      } 
+    }
+  }
+  END_TIMING(treemodel,1);
+}
+
+void _TEST_treemodel_addData_03(TreeModel * dataTreeModel) {
+  MyDataObject * dataObject = new MyDataObject();
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE,    "Tuyauterie");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+  dataTreeModel->addData(dataObject);
+
+  dataObject = new MyDataObject();
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE,    "Tuyauterie");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+  dataTreeModel->addData(dataObject);
+
+  dataObject = new MyDataObject();
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE,    "Tuyauterie");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF2");
+  dataTreeModel->addData(dataObject);
+
+  dataObject = new MyDataObject();
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE,    "Tuyauterie");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RRA");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+  dataTreeModel->addData(dataObject);
+
+  dataObject = new MyDataObject();
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE,    "Génie civil");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RRA");
+  dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+  dataTreeModel->addData(dataObject);
+}
+
+/*!
+ * This test function shows how it's possible to load data from a file
+ * to populate the tree model.
+ */
+void _TEST_treemodel_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename) {
+  TESTHELPER_loadDataFromFile(dataTreeModel, filename);
+}
+
+/*!
+ * Main test function for the tree model demo.
+ */
+#include "TreeModel.hxx"
+#include "TreeView.hxx"
+void TEST_treemodel() {
+
+  START_TIMING(treemodel);
+
+  // We first prepare a data view embedding a tree model
+  TreeView * dataView = new TreeView();
+  QStringList headers;
+  headers << QObject::tr("Name") << QObject::tr("Value");
+  TreeModel * dataTreeModel = new TreeModel(headers);
+  dataView->setModel(dataTreeModel);
+  END_TIMING(treemodel,1);
+
+  // Then we can fill the tree model with data. Can proceed with
+  // different ways (comment/uncomment which you want to test):
+  _TEST_treemodel_loadDataFromFile(dataTreeModel, TESTHELPER_testfilename(DATAFILENAME));
+  //_TEST_treemodel_addData_01(dataTreeModel);
+  //_TEST_treemodel_addData_02(dataTreeModel);
+  //_TEST_treemodel_addData_03(dataTreeModel);
+  // Finally, show the widget in a main window
+  END_TIMING(treemodel,1);
+
+  showWidget(dataView);
+  END_TIMING(treemodel,1);
+}
+
+//
+// =================================================================
+// Tests functions for TreeModel with interactive changes
+// =================================================================
+//
+#include "mainwindow.hxx"
+void TEST_treemodel_interactif() {
+  MainWindow * window = new MainWindow();
+  window->show();
+}
+
+//
+// =================================================================
+//
+int main(int argc, char * argv[ ])
+{
+  QApplication app(argc, argv);
+  TEST_treemodel();
+  //TST_treemodel_interactif();
+  return app.exec();
+}
diff --git a/src/TreeData/Test/mainwindow.cxx b/src/TreeData/Test/mainwindow.cxx
new file mode 100644 (file)
index 0000000..bb31011
--- /dev/null
@@ -0,0 +1,188 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <QtGui>
+
+#include "mainwindow.hxx"
+#include "TreeModel.hxx"
+
+#include <Basics_Utils.hxx>
+#include "testhelper.hxx"
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+{
+    setupUi(this);
+
+    QStringList headers;
+    headers << tr("Title") << tr("Description");
+
+    TreeModel *model = new TreeModel(headers);
+    TESTHELPER_loadDataFromFile(model, TESTHELPER_testfilename(DATAFILENAME));
+
+    view->setModel(model);
+    for (int column = 0; column < model->columnCount(); ++column)
+        view->resizeColumnToContents(column);
+
+    connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+    connect(view->selectionModel(),
+            SIGNAL(selectionChanged(const QItemSelection &,
+                                    const QItemSelection &)),
+            this, SLOT(updateActions()));
+
+    connect(actionsMenu, SIGNAL(aboutToShow()), this, SLOT(updateActions()));
+    connect(insertRowAction, SIGNAL(triggered()), this, SLOT(insertRow()));
+    connect(insertColumnAction, SIGNAL(triggered()), this, SLOT(insertColumn()));
+    connect(removeRowAction, SIGNAL(triggered()), this, SLOT(removeRow()));
+    connect(removeColumnAction, SIGNAL(triggered()), this, SLOT(removeColumn()));
+    connect(insertChildAction, SIGNAL(triggered()), this, SLOT(insertChild()));
+    connect(newDataAction, SIGNAL(triggered()), this, SLOT(newData()));
+
+    updateActions();
+}
+
+void MainWindow::newData() {
+  LOG("MainWindow::newData(): START");
+
+  bool ok;
+  QString text = QInputDialog::getText(this, tr("QInputDialog::getText()"),
+                                       tr("Data path:"), QLineEdit::Normal,
+                                       "folder/subfolder/item", &ok);
+  if (!ok || text.trimmed().isEmpty())
+    return;
+
+  QStringList path = text.trimmed().split("/");
+  TreeModel *model = (TreeModel *)view->model();
+
+  QString label = path.last();
+  path.removeLast();
+  DataObject * data = TESTHELPER_dummyObject(label);
+  model->addData(data,path);
+
+  LOG("MainWindow::newData(): END");
+}
+
+void MainWindow::insertChild()
+{
+    QModelIndex index = view->selectionModel()->currentIndex();
+    QAbstractItemModel *model = view->model();
+
+    if (model->columnCount(index) == 0) {
+        if (!model->insertColumn(0, index))
+            return;
+    }
+
+    if (!model->insertRow(0, index))
+        return;
+
+    for (int column = 0; column < model->columnCount(index); ++column) {
+        QModelIndex child = model->index(0, column, index);
+        model->setData(child, QVariant("[No data]"), Qt::EditRole);
+        if (!model->headerData(column, Qt::Horizontal).isValid())
+            model->setHeaderData(column, Qt::Horizontal, QVariant("[No header]"),
+                                 Qt::EditRole);
+    }
+
+    view->selectionModel()->setCurrentIndex(model->index(0, 0, index),
+                                            QItemSelectionModel::ClearAndSelect);
+    updateActions();
+}
+
+bool MainWindow::insertColumn(const QModelIndex &parent)
+{
+    QAbstractItemModel *model = view->model();
+    int column = view->selectionModel()->currentIndex().column();
+
+    // Insert a column in the parent item.
+    bool changed = model->insertColumn(column + 1, parent);
+    if (changed)
+        model->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"),
+                             Qt::EditRole);
+
+    updateActions();
+
+    return changed;
+}
+
+void MainWindow::insertRow()
+{
+    QModelIndex index = view->selectionModel()->currentIndex();
+    QAbstractItemModel *model = view->model();
+
+    if (!model->insertRow(index.row()+1, index.parent()))
+        return;
+
+    updateActions();
+
+    for (int column = 0; column < model->columnCount(index.parent()); ++column) {
+        QModelIndex child = model->index(index.row()+1, column, index.parent());
+        model->setData(child, QVariant("[No data]"), Qt::EditRole);
+    }
+}
+
+bool MainWindow::removeColumn(const QModelIndex &parent)
+{
+    QAbstractItemModel *model = view->model();
+    int column = view->selectionModel()->currentIndex().column();
+
+    // Insert columns in each child of the parent item.
+    bool changed = model->removeColumn(column, parent);
+
+    if (!parent.isValid() && changed)
+        updateActions();
+
+    return changed;
+}
+
+void MainWindow::removeRow()
+{
+    QModelIndex index = view->selectionModel()->currentIndex();
+    QAbstractItemModel *model = view->model();
+    if (model->removeRow(index.row(), index.parent()))
+        updateActions();
+}
+
+void MainWindow::updateActions()
+{
+    bool hasSelection = !view->selectionModel()->selection().isEmpty();
+    removeRowAction->setEnabled(hasSelection);
+    removeColumnAction->setEnabled(hasSelection);
+
+    bool hasCurrent = view->selectionModel()->currentIndex().isValid();
+    insertRowAction->setEnabled(hasCurrent);
+    insertColumnAction->setEnabled(hasCurrent);
+
+    if (hasCurrent) {
+        view->closePersistentEditor(view->selectionModel()->currentIndex());
+
+        int row = view->selectionModel()->currentIndex().row();
+        int column = view->selectionModel()->currentIndex().column();
+        if (view->selectionModel()->currentIndex().parent().isValid())
+            statusBar()->showMessage(tr("Position: (%1,%2)").arg(row).arg(column));
+        else
+            statusBar()->showMessage(tr("Position: (%1,%2) in top level").arg(row).arg(column));
+    }
+}
+
+void MainWindow::contextMenuEvent(QContextMenuEvent *event) {
+  QMenu menu(this);
+  menu.addAction(newDataAction);
+  menu.exec(event->globalPos());
+}
diff --git a/src/TreeData/Test/mainwindow.hxx b/src/TreeData/Test/mainwindow.hxx
new file mode 100644 (file)
index 0000000..5f973f3
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QModelIndex>
+
+#include "ui_mainwindow.h"
+
+class QAction;
+class QTreeView;
+class QWidget;
+
+class MainWindow : public QMainWindow, private Ui::MainWindow
+{
+    Q_OBJECT
+
+public:
+    MainWindow(QWidget *parent = 0);
+
+protected:
+  void contextMenuEvent(QContextMenuEvent *event);
+
+public slots:
+    void updateActions();
+
+private slots:
+    void insertChild();
+    bool insertColumn(const QModelIndex &parent = QModelIndex());
+    void insertRow();
+    bool removeColumn(const QModelIndex &parent = QModelIndex());
+    void removeRow();
+    void newData();
+};
+
+#endif
diff --git a/src/TreeData/Test/mainwindow.ui b/src/TreeData/Test/mainwindow.ui
new file mode 100644 (file)
index 0000000..a7cfe6b
--- /dev/null
@@ -0,0 +1,140 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>573</width>
+    <height>468</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Editable Tree Model</string>
+  </property>
+  <widget class="QWidget" name="centralwidget" >
+   <layout class="QVBoxLayout" >
+    <property name="margin" >
+     <number>0</number>
+    </property>
+    <property name="spacing" >
+     <number>0</number>
+    </property>
+    <item>
+     <widget class="QTreeView" name="view" >
+      <property name="alternatingRowColors" >
+       <bool>true</bool>
+      </property>
+      <property name="selectionBehavior" >
+       <enum>QAbstractItemView::SelectItems</enum>
+      </property>
+      <property name="horizontalScrollMode" >
+       <enum>QAbstractItemView::ScrollPerPixel</enum>
+      </property>
+      <property name="animated" >
+       <bool>false</bool>
+      </property>
+      <property name="allColumnsShowFocus" >
+       <bool>true</bool>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar" >
+   <property name="geometry" >
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>573</width>
+     <height>29</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="actionsMenu" >
+    <property name="title" >
+     <string>&amp;Actions</string>
+    </property>
+    <addaction name="insertRowAction" />
+    <addaction name="insertColumnAction" />
+    <addaction name="separator" />
+    <addaction name="removeRowAction" />
+    <addaction name="removeColumnAction" />
+    <addaction name="separator" />
+    <addaction name="insertChildAction" />
+   </widget>
+   <widget class="QMenu" name="fileMenu" >
+    <property name="title" >
+     <string>&amp;File</string>
+    </property>
+    <addaction name="exitAction" />
+   </widget>
+   <widget class="QMenu" name="menuData" >
+    <property name="title" >
+     <string>Data</string>
+    </property>
+    <addaction name="newDataAction" />
+   </widget>
+   <addaction name="fileMenu" />
+   <addaction name="actionsMenu" />
+   <addaction name="menuData" />
+  </widget>
+  <widget class="QStatusBar" name="statusbar" />
+  <action name="exitAction" >
+   <property name="text" >
+    <string>E&amp;xit</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+Q</string>
+   </property>
+  </action>
+  <action name="insertRowAction" >
+   <property name="text" >
+    <string>Insert Row</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+I, R</string>
+   </property>
+  </action>
+  <action name="removeRowAction" >
+   <property name="text" >
+    <string>Remove Row</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+R, R</string>
+   </property>
+  </action>
+  <action name="insertColumnAction" >
+   <property name="text" >
+    <string>Insert Column</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+I, C</string>
+   </property>
+  </action>
+  <action name="removeColumnAction" >
+   <property name="text" >
+    <string>Remove Column</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+R, C</string>
+   </property>
+  </action>
+  <action name="insertChildAction" >
+   <property name="text" >
+    <string>Insert Child</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+N</string>
+   </property>
+  </action>
+  <action name="newDataAction" >
+   <property name="text" >
+    <string>new</string>
+   </property>
+  </action>
+ </widget>
+ <resources>
+  <include location="editabletreemodel.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/TreeData/Test/tester.cxx b/src/TreeData/Test/tester.cxx
new file mode 100644 (file)
index 0000000..e26206d
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtHelper.hxx"
+
+//
+// =================================================================
+// Helper functions for DataObject and DataModel classes
+// =================================================================
+//
+
+// ----
+// A DataObject can't be used as is but must be specialized to
+// specify the behavior in the hierarchic model.
+#include "MyDataModel.hxx"
+
+void TEST_DataObject() {
+  // In this test, the object id should increase at each instance
+  DataObject * dataObject;
+  for (int i=0; i<100; i++) {
+    dataObject = new MyDataObject();
+    QLOG("object nameId = " << dataObject->getNameId().c_str());
+  }
+  QLOG("path     = " << dataObject->getPath().c_str());
+  QLOG("pathname = " << dataObject->getPathName().c_str());
+
+  QLOG("serialize= " << dataObject->toString().c_str());
+
+}
+
+void TEST_DataModel() {
+  MyDataModel * dataModel = new MyDataModel();
+
+  int refIter = 53;
+  string refNameId;
+
+  DataObject * dataObject;
+  for (int i=0; i<100; i++) {
+    // We can either create the data object using its constructor or
+    // using the factory of the model (the prefered way):
+    // dataObject = new MyDataObject();
+    dataObject = dataModel->newDataObject();
+    dataObject->setLabel("myobject"+ToString(i));
+    if ( i == refIter ) {
+      refNameId = dataObject->getNameId();
+    }
+    dataModel->addDataObject(dataObject);
+  }
+
+  dataObject = dataModel->getDataObject(refNameId);
+  QLOG("object nameId = " << dataObject->getNameId().c_str());
+  QLOG("path     = " << dataObject->getPath().c_str());
+  QLOG("pathname = " << dataObject->getPathName().c_str());
+}
+
+//
+// =================================================================
+//
+int main(int argc, char * argv[ ])
+{
+  TEST_DataObject();
+  //TEST_DataModel();
+}
diff --git a/src/TreeData/Test/testhelper.cxx b/src/TreeData/Test/testhelper.cxx
new file mode 100644 (file)
index 0000000..c993c64
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "testhelper.hxx"
+
+#include <QFile>
+#include <QString>
+
+#include "QtHelper.hxx"
+#include "MyDataModel.hxx"
+
+// Standard C include (for getenv)
+#include <stdlib.h>
+
+QString TESTHELPER_testfilename(const char * basefilename) {
+  QString aFile;
+  char * GUI_ROOT_DIR = getenv("GUI_ROOT_DIR");
+  QString * root;
+  if ( GUI_ROOT_DIR != NULL ) {
+    root = new QString(GUI_ROOT_DIR);
+  }
+  else {
+    root = new QString("/home/gboulant/development/projets/salome/devel/XSALOME/install");
+  }
+  QString relativePathName = "/share/salome/resources/gui/testdata/";
+  aFile.append(*root + relativePathName + basefilename);
+
+  QLOG("The test file is : "<<aFile);
+  return aFile;
+}
+
+/*!
+ * This creates a dummy data object for the needs of the test
+ * functions. The label is the basename of the spécified pathname.
+ */
+DataObject * TESTHELPER_dummyObject(QString label) {
+  MyDataObject * dataObject = new MyDataObject();
+  dataObject->setLabel(QCHARSTAR(label));
+  return dataObject;
+}
+
+
+#define SEP ";"
+/*!
+ * This test function shows how it's possible to load data from a file
+ * to populate the tree model.
+ */
+void TESTHELPER_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename) {
+  QFile file ( filename );
+  file.open ( QIODevice::ReadOnly );
+  
+  MyDataObject * dataObject;
+  while ( 1 ) {
+    QByteArray byteArray = file.readLine();
+
+    if ( byteArray.isEmpty() )
+      break;
+    
+    QString data = (QString ( byteArray.mid(0, byteArray.size()-1))).trimmed();
+    QStringList dataList = data.split ( SEP );
+    // The data list is used here to set properties (and then the path
+    // of location in the tree model).
+
+    dataObject = new MyDataObject();
+    // The label is autogenerated, but we may specify here a custom
+    // one. We just fill the properties with data values read in the
+    // file.
+    dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE,    QCHARSTAR(dataList[0]));
+    dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, QCHARSTAR(dataList[1]));
+    dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, QCHARSTAR(dataList[2]));
+    if ( ! dataTreeModel->addData(dataObject) ) {
+      QLOG("ERR: data not added");
+    }
+  }
+
+  file.close();
+}
diff --git a/src/TreeData/Test/testhelper.hxx b/src/TreeData/Test/testhelper.hxx
new file mode 100644 (file)
index 0000000..ca0680e
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _TESTHELPER_HXX_
+#define _TESTHELPER_HXX_
+
+#include <QString>
+#include "TreeModel.hxx"
+#include "DataObject.hxx"
+
+#define DATAFILENAME "data.txt"
+
+QString      TESTHELPER_testfilename(const char * basefilename);
+DataObject * TESTHELPER_dummyObject(QString label);
+void         TESTHELPER_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename);
+
+#endif // _TESTHELPER_HXX_
diff --git a/src/TreeData/TreeData.hxx b/src/TreeData/TreeData.hxx
new file mode 100755 (executable)
index 0000000..6d98c97
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef TREEDATA_HXX
+#define TREEDATA_HXX
+
+#ifdef WIN32
+#  if defined SALOMETREEDATA_EXPORTS || defined SalomeTreeData_EXPORTS
+#    define TREEDATA_EXPORT __declspec( dllexport )
+#  else
+#    define TREEDATA_EXPORT __declspec( dllimport )
+#  endif
+#else
+#  define TREEDATA_EXPORT
+#endif
+
+#endif //TREEDATA_HXX
diff --git a/src/TreeData/TreeGuiManager.cxx b/src/TreeData/TreeGuiManager.cxx
new file mode 100644 (file)
index 0000000..22594e1
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "TreeGuiManager.hxx"
+
+// SALOME includes
+#include <QStringList>
+
+// XCAD includes
+#include "TreeView.hxx"
+#include "QtHelper.hxx"
+
+// TODO:
+// IMP: The constructor should have a dockwidget as argument.
+// The creation of the void dockwidget (without the data tree
+// embedded) should be done previously by the StandardApp_Module.
+// The constructor would fill the dockwidget with a data tree view
+
+/*!
+ * The construction of the gui manager setups a graphic framework that
+ * consists in a set of dock widgets implanted in the SALOME GUI and
+ * embedding a tree view rendering a data model (collection of data
+ * objects) in a hierarchic graphical organisation.
+ *
+ * The data model is a straith list of data objects while the view is
+ * a tree representation of this collection where folders corresponds
+ * to specific properties of the objects.
+ *
+ * This represention is for the needs of navigation in a huge amount
+ * of data and to ease the selection and processing of items.
+ */
+TreeGuiManager::TreeGuiManager(SalomeApp_Application * salomeApp, const char * title)
+  : TreeObserver()
+{
+  _salomeApp = salomeApp;
+  
+  bool tabify = false;
+  _dockWidgets = new DockWidgets(_salomeApp, tabify, title);
+
+  // Create a TreeView to be associated to a TreeModel dedicated to
+  // the Xcad data:
+  _dataTreeView = new TreeView();
+  QStringList headers;
+  headers << tr("Name") << tr("Value");
+  _dataTreeModel = new TreeModel(headers);
+  _dataTreeView->setModel(_dataTreeModel);
+
+  // Then plug the TreeView in the dock widget:
+  _dockWidgets->setDataView(_dataTreeView);
+
+  // We specify here the dataview to be observed
+  this->observe(_dataTreeView);
+}
+
+/*!
+ * This returns the SALOME application (SalomeApp_Application
+ * instance) associated to this TreeGuiManager.
+ */
+SalomeApp_Application * TreeGuiManager::getSalomeApplication() {
+  return _salomeApp;
+}
+
+
+/*!
+ * This function set a layout of the different dock widgets in one
+ * single tabbed widget.
+ */
+void TreeGuiManager::tabifyDockWidgets(bool tabify) {
+  _dockWidgets->tabify(tabify);
+}
+
+/*!
+ * This function switch on/off the dock widgets managed by this
+ * gui manager.
+ */
+void TreeGuiManager::showDockWidgets(bool isVisible) {
+  _dockWidgets->show(isVisible);
+}
+
+/*!
+ * This returns the data tree model defined in this
+ * TreeGuiManager. The data tree model is a tree representation of the
+ * data model associated to this TreeGuiManager.
+ */
+TreeModel * TreeGuiManager::getDataTreeModel() {
+  return _dataTreeModel;
+}
+
+/*!
+ * This returns the data tree view defined in this
+ * TreeGuiManager. The data tree view can be request to customize the
+ * popup menu associated to the tree representation.
+ */
+TreeView * TreeGuiManager::getDataTreeView() {
+  return _dataTreeView;
+}
+
+
+/*!
+ * This function specifies the data model to be used by the
+ * TreeGuiManager.
+ */
+void TreeGuiManager::setDataModel(DataModel * dataModel) {
+  _dataModel = dataModel;
+}
+
+DataModel * TreeGuiManager::getDataModel() {
+  return _dataModel;
+}
+
+/*!
+ * This function processes the edit signals received from the
+ * TreeView. This is a default implementation that only prints the
+ * reception of the signal and some information about the dataObject
+ * associated to the item whose id is specified. In practice, the data
+ * model could be requested here to retrieve the data object to be
+ * edited from the nameId.
+ * TO BE IMPLEMENTED IN A DOMAIN SPECIFIC VERSION OF THIS CLASS
+ */
+
+void TreeGuiManager::processItemList(QStringList itemNameIdList,
+                                    int actionId)
+{
+  // WARN: THIS IS A DEFAULT IMPLEMENTATION GIVEN FOR DEMONSTRATION
+  // OF WHAT TO DO WITH THE PARAMETERS
+
+  QString itemNameId = itemNameIdList[0];
+  LOG("TreeGuiManager: signal received : process item "<<itemNameId);
+  DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+  if ( dataObject != NULL ) {
+    LOG("TreeGuiManager: dataObject = "<<dataObject->toString().c_str());
+  } else {
+    LOG("TreeGuiManager: no data object associated to this item");
+  }
+}
diff --git a/src/TreeData/TreeGuiManager.hxx b/src/TreeData/TreeGuiManager.hxx
new file mode 100644 (file)
index 0000000..6d79fc8
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _TREEGUIMANAGER_H_
+#define _TREEGUIMANAGER_H_
+
+#include "TreeData.hxx"
+
+// SALOME includes
+#include <SalomeApp_Application.h>
+
+// TREEDATA includes
+#include "DockWidgets.hxx"
+#include "TreeModel.hxx"
+#include "DataModel.hxx"
+#include "TreeView.hxx"
+#include "TreeObserver.hxx"
+
+class TREEDATA_EXPORT TreeGuiManager : public TreeObserver {
+  
+public:
+  TreeGuiManager(SalomeApp_Application * salomeApp, const char * title="Data Model");
+  void tabifyDockWidgets(bool tabify);
+  void showDockWidgets(bool isVisible);
+  SalomeApp_Application * getSalomeApplication();
+  
+  TreeModel * getDataTreeModel();
+  TreeView * getDataTreeView();
+  
+  void setDataModel(DataModel * dataModel);
+  DataModel * getDataModel();
+  
+private:
+  SalomeApp_Application * _salomeApp;
+  
+  DockWidgets * _dockWidgets;
+  TreeView * _dataTreeView;
+  
+  TreeModel * _dataTreeModel;
+  DataModel * _dataModel;
+  
+public slots:
+  virtual void processItemList(QStringList itemNameIdList, int actionId);
+};
+
+#endif /* _TREEGUIMANAGER_H_ */
diff --git a/src/TreeData/TreeItem.cxx b/src/TreeData/TreeItem.cxx
new file mode 100644 (file)
index 0000000..26394f6
--- /dev/null
@@ -0,0 +1,242 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include <QStringList>
+#include "TreeItem.hxx"
+
+TreeItem::TreeItem(const QString &nameId,
+                   const QVector<QVariant> &columnValues,
+                   TreeItem *parent)
+{
+  this->initialize(nameId, columnValues, parent);
+}
+
+/*!
+ * This initializes the tree item. Called by the constructors.
+ */
+void TreeItem::initialize(const QString &nameId,
+                          const QVector<QVariant> &columnValues,
+                          TreeItem *parent) {
+  _itemNameId = nameId;
+  _itemData   = columnValues;
+  _parentItem = parent;
+
+  // An item is associated to the model of its parent. It can't be
+  //done automatically in the case where the item has no parent. Then
+  //the function associatedToModel has to be called explicitely from
+  //within the user code (for exemple at construction of the model,
+  //when creating the root item).
+  if ( parent != NULL ) {
+    this->associateToModel(parent->associatedModel());
+  }  
+}
+
+TreeItem::~TreeItem()
+{
+  qDeleteAll(_childItems);
+  qDeleteAll(_childItemsMapById);
+  qDeleteAll(_childItemsMapByLabel);
+}
+
+/*!
+ * This must be used to specified which model this item belongs to. It
+ * is required because the item sometimes requests its model for
+ * global informations about the data tree. In standard usage, this
+ * function is automatically set when the item is instantiated by
+ * requested the parent item. Then only the root item needs a manual
+ * setting.
+ */
+void TreeItem::associateToModel(TreeModel * model) {
+  _associatedModel = model;
+}
+
+TreeModel * TreeItem::associatedModel() {
+  return _associatedModel;
+}
+
+/*!
+ * This provide an identifier for this item
+ */
+QString TreeItem::nameId() {
+  return _itemNameId;
+}
+
+/*!
+ * This creates an item from the specified dataObject and put it in
+ * the decendency of this item at the specified relativePath. The
+ * created item could not be a direct child of this item in the case
+ * where the relative path is not null. Note that no reference on the
+ * dataObject is kept in this instance. Only the identifier is used to
+ * set the item identifier, and the properties may be used to set the
+ * values of the item (stored in columns).
+ */
+void TreeItem::appendChild(DataObject * dataObject,
+                           const QStringList &relativePath) {
+  // Definition of the nameId
+  QString nameId = QString(dataObject->getNameId().c_str());
+
+  // Definition of columns data values
+  QVector<QVariant> columnValues;
+  columnValues << QString(dataObject->getLabel().c_str());
+  columnValues << "No value"; // We could use the dataObject properties
+
+  // Append the item at the specified location with the specified values:
+  this->appendChild(nameId, columnValues, relativePath);
+}
+
+void TreeItem::appendChild(const QString &nameId,
+                           const QVector<QVariant> &columnValues,
+                           const QStringList &relativePath) {
+
+  if ( relativePath.isEmpty() ) {
+    // It is a direct child => just create and append to this.
+    TreeItem * child = new TreeItem(nameId, columnValues, this);
+    this->appendChild(child);
+    return;
+  }
+
+  // The child is embedded in a sub-folder (to be created if doesn't
+  // exist).
+  // We first check if the sub-folder already exist:
+  TreeItem * folder = this->childByLabel(relativePath[0]);
+  if ( folder == NULL ) {
+    // The folder does not exist. It must be created before going any
+    // further. By convention we choose the folder name as
+    // identifier.
+    QString folderNameId = relativePath[0];
+    QVector<QVariant> folderColumnValues;
+    folderColumnValues << relativePath[0] << "No value";
+    folder = new TreeItem(folderNameId, folderColumnValues, this);
+    this->appendChild(folder);
+  }
+    
+  // We create the relative path of the next iteration (delete the
+  // first folder path).
+  QStringList nextRelativePath;
+  for (int i = 1; i < relativePath.size(); ++i)
+    nextRelativePath << relativePath[i];
+    
+  folder->appendChild(nameId, columnValues, nextRelativePath);
+}
+
+/*!
+ * This appends the specified child to this item. This item is the
+ * direct parent of the specified child.
+ */
+void TreeItem::appendChild(TreeItem *item)
+{
+  TreeModel * model = this->associatedModel();
+
+  int position = this->childCount();
+  model->beginInsertRows(this->modelIndex(), position, position);
+  _childItems.append(item);
+  _childItemsMapById[item->nameId()] = item;
+  _childItemsMapByLabel[item->data(0).toString()] = item;
+  model->endInsertRows();
+}
+
+/*!
+ * The child() function returns the child that corresponds to the
+ * specified row number in the item's list of child items.
+ */
+TreeItem *TreeItem::child(int row)
+{
+  return _childItems.value(row);
+}
+
+TreeItem *TreeItem::childById(const QString &nameId)
+{
+  QMap <QString, TreeItem*>::iterator it;
+  it = _childItemsMapById.find ( nameId );
+
+  if ( it != _childItemsMapById.end() ) {
+    return it.value();
+  }
+  return NULL;
+}
+
+TreeItem *TreeItem::childByLabel(const QString &label)
+{
+  QMap <QString, TreeItem*>::iterator it;
+  it = _childItemsMapByLabel.find ( label );
+
+  if ( it != _childItemsMapByLabel.end() ) {
+    return it.value();
+  }
+  return NULL;
+}
+
+
+
+int TreeItem::childCount() const
+{
+  return _childItems.count();
+}
+
+/*!
+ * The rowIndex() function reports the item's location within its
+ * parent's list of items.
+ */
+int TreeItem::rowIndex() const
+{
+  if (_parentItem)
+    return _parentItem->_childItems.indexOf(const_cast<TreeItem*>(this));
+
+  return 0;
+}
+
+int TreeItem::columnCount() const
+{
+  return _itemData.count();
+}
+
+QVariant TreeItem::data(int column) const
+{
+  return _itemData.value(column);
+}
+
+TreeItem *TreeItem::parent()
+{
+  return _parentItem;
+}
+
+bool TreeItem::setData(int column, const QVariant &value)
+{
+  if (column < 0 || column >= _itemData.size())
+    return false;
+
+  _itemData[column] = value;
+  return true;
+}
+
+QModelIndex TreeItem::modelIndex(int column)
+{
+  TreeModel * model = this->associatedModel();
+  if (_parentItem && (_parentItem != model->getRootItem()))
+    return model->index(rowIndex(),
+                        column,
+                        _parentItem->modelIndex());
+  else
+    return model->index(rowIndex(),
+                        column,
+                        QModelIndex());
+}
diff --git a/src/TreeData/TreeItem.hxx b/src/TreeData/TreeItem.hxx
new file mode 100644 (file)
index 0000000..c7f25a7
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef TREEITEM_H
+#define TREEITEM_H
+
+#include "TreeData.hxx"
+
+#include <QList>
+#include <QVariant>
+#include <QVector>
+#include <QModelIndex>
+
+#include "DataObject.hxx"
+#include "TreeModel.hxx"
+
+class TREEDATA_EXPORT TreeItem
+{
+ public:
+  TreeItem(const QString &nameId, const QVector<QVariant> &columnValues, TreeItem *parent = 0);
+  ~TreeItem();
+
+  QString nameId();
+  void associateToModel(TreeModel * model);
+  TreeModel * associatedModel();
+  QModelIndex modelIndex(int column=0);
+  TreeItem *parent();
+
+  void appendChild(TreeItem * child);
+  void appendChild(DataObject * dataObject,
+                   const QStringList &relativePath=QStringList());
+  void appendChild(const QString &nameId,
+                   const QVector<QVariant> &columnValues,
+                   const QStringList &relativePath=QStringList());
+
+  
+  
+  TreeItem *child(int row);
+  TreeItem *childById(const QString &nameId);
+  TreeItem *childByLabel(const QString &label);
+  int childCount() const;
+  int columnCount() const;
+  int rowIndex() const;
+  QVariant data(int column) const;
+  bool setData(int column, const QVariant &value);
+
+
+ private:
+  void initialize(const QString &nameId,
+                  const QVector<QVariant> &columnValues,
+                  TreeItem *parent);
+
+  QList<TreeItem*> _childItems;
+  QMap <QString, TreeItem *> _childItemsMapById;
+  QMap <QString, TreeItem *> _childItemsMapByLabel;
+
+  QString _itemNameId;
+  QVector<QVariant> _itemData;
+  TreeItem  * _parentItem;
+  TreeModel * _associatedModel;
+
+};
+
+#endif
diff --git a/src/TreeData/TreeModel.cxx b/src/TreeData/TreeModel.cxx
new file mode 100644 (file)
index 0000000..1014e05
--- /dev/null
@@ -0,0 +1,210 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include <QtGui>
+
+#include "TreeItem.hxx"
+#include "TreeModel.hxx"
+
+TreeModel::TreeModel(const QStringList &headers, QObject *parent)
+  : QAbstractItemModel(parent)
+{
+  QVector<QVariant> rootData;
+  foreach (QString header, headers)
+    rootData << header;
+
+  // _MEM_ We have to specify a string identifier for each item so
+  // that it could be easily retrieved by its parent. In the case of
+  // the root item, the value of the identifier doesn't matter => we
+  // choose an arbitrary value
+  //QString rootNameId = "rootItem";
+  _rootItem = new TreeItem("rootItem", rootData);
+  _rootItem->associateToModel(this);
+}
+
+TreeModel::~TreeModel()
+{
+  delete _rootItem;
+}
+
+TreeItem * TreeModel::getRootItem() {
+  return _rootItem;
+}
+
+//
+// =================================================================
+// This part of the implementation is the standard interface required
+// for providing an operational TreeModel. These methods are used by
+// the TreeView for display purpose. We just have to implement how we
+// want the items to be displayed in the view.
+// =================================================================
+//
+int TreeModel::columnCount(const QModelIndex & /* parent */) const
+{
+  return _rootItem->columnCount();
+}
+
+/*!
+ * This function is used by the tree model to inform the tree view of
+ * what data used for rendering of the item in the different possible
+ * role (edition, ...).
+ */
+QVariant TreeModel::data(const QModelIndex &index, int role) const
+{
+  if (!index.isValid())
+    return QVariant();
+
+  if (role != Qt::DisplayRole && role != Qt::EditRole)
+    return QVariant();
+
+  TreeItem *item = getItem(index);
+
+  return item->data(index.column());
+}
+
+Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
+{
+  if (!index.isValid())
+    return 0;
+
+  return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+/*!
+ * This retrieves the item asociated to the specified index.
+ */
+TreeItem *TreeModel::getItem(const QModelIndex &index) const
+{
+  // The item associated to an index can be retrieved using the
+  // internalPointer() function on the index object.
+  if (index.isValid()) {
+    TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
+    if (item) return item;
+  }
+  return _rootItem;
+}
+
+QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
+                               int role) const
+{
+  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+    return _rootItem->data(section);
+
+  return QVariant();
+}
+
+/*!
+ * This retrieves the index of the item located at (row,column) place
+ * relative to the parent specified by its index.
+ */
+QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
+{
+  if (parent.isValid() && parent.column() != 0)
+    return QModelIndex();
+
+  TreeItem *parentItem = getItem(parent);
+
+  TreeItem *childItem = parentItem->child(row);
+  if (childItem)
+    return createIndex(row, column, childItem);
+  else
+    return QModelIndex();
+}
+
+QModelIndex TreeModel::parent(const QModelIndex &index) const
+{
+  if (!index.isValid())
+    return QModelIndex();
+
+  TreeItem *childItem = getItem(index);
+  TreeItem *parentItem = childItem->parent();
+
+  if (parentItem == _rootItem)
+    return QModelIndex();
+
+  return createIndex(parentItem->rowIndex(), 0, parentItem);
+}
+
+int TreeModel::rowCount(const QModelIndex &parent) const
+{
+  TreeItem *parentItem = getItem(parent);
+
+  return parentItem->childCount();
+}
+
+bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
+                        int role)
+{
+  if (role != Qt::EditRole)
+    return false;
+
+  TreeItem *item = getItem(index);
+  bool result = item->setData(index.column(), value);
+
+  if (result)
+    emit dataChanged(index, index);
+
+  return result;
+}
+
+bool TreeModel::setHeaderData(int section, Qt::Orientation orientation,
+                              const QVariant &value, int role)
+{
+  if (role != Qt::EditRole || orientation != Qt::Horizontal)
+    return false;
+
+  bool result = _rootItem->setData(section, value);
+
+  if (result)
+    emit headerDataChanged(orientation, section, section);
+
+  return result;
+}
+
+
+//
+// =================================================================
+// This part is a specific behavior to get a TreeModel that can
+// organize itself the tree hierarchy using data provided in a
+// filesystem-like format:
+// 
+// data="a/b/c" ==> creation/filling of the hierarchy a->b->c
+// The "folder" categories are unique whereas the leaves may exists
+// in multiple instances.
+// =================================================================
+//
+
+/*
+ * The addData functions run a recurcive filling of the tree model, starting
+ * form the rootItem and descending in the tree using the recurcive
+ * function TreeItem::addData.
+ */
+
+bool TreeModel::addData(DataObject * dataObject) {
+  QStringList path = QString(dataObject->getPath().c_str()).split(DataObject::pathsep.c_str());
+  return addData(dataObject, path);
+}
+bool TreeModel::addData(DataObject * dataObject, const QStringList &path) {
+  TreeItem * rootItem = this->getItem();
+  rootItem->appendChild(dataObject, path);
+  return true;
+}
diff --git a/src/TreeData/TreeModel.hxx b/src/TreeData/TreeModel.hxx
new file mode 100644 (file)
index 0000000..dce9771
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef TREEMODEL_H
+#define TREEMODEL_H
+
+#include "TreeData.hxx"
+
+#include <QAbstractItemModel>
+#include <QModelIndex>
+#include <QVariant>
+#include <QStringList>
+
+#include "DataObject.hxx"
+
+class TreeItem;
+class TreeView;
+
+class TREEDATA_EXPORT TreeModel : public QAbstractItemModel
+{
+  Q_OBJECT
+
+  // IMPORTANT NOTE:
+  // In this implementation of QAbstractItemModel, a tree item is
+  // associated to the tree model it belongs to (it can request its
+  // model throw a pointer to this model). Then we declare the
+  // TreeItem as a friend class so that it can request the protected
+  // methods (for example beginInsertRows and endInsertRows, required
+  // to manage correctly the addition of an item in the model. An
+  // item can append a child to itself, so it needs to inform the
+  // model when it begins and when it ends).
+  friend class TreeItem;
+  friend class TreeView;
+
+public:
+  TreeModel(const QStringList &headers, QObject *parent = 0);
+  ~TreeModel();
+
+  //
+  // =================================================================
+  // This part of the specification is the standard interface required
+  // for providing an operational TreeModel. These methods are used by
+  // the TreeView for display purpose. We just have to implement how
+  // we want the items to be displayed in the view.
+  // =================================================================
+  //
+  // MEM: note that these methods are not intended to be used
+  // directly. That's the job of the viewer to know how to use
+  // them. We just have to give the implementation for customizing the
+  // appearance of the tree. The implementation generally requests the
+  // items'data to set the appearance features.
+  QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+  QModelIndex parent(const QModelIndex &index) const;
+  int rowCount(const QModelIndex &parent = QModelIndex()) const;
+  int columnCount(const QModelIndex &parent = QModelIndex()) const;
+  QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
+  bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+  Qt::ItemFlags flags(const QModelIndex &index) const;
+
+  //
+  // =================================================================
+  // This part is a specific behavior to get a TreeModel that can
+  // organize itself the tree hierarchy using data provided in a
+  // filesystem-like format:
+  // 
+  // data="a/b/c" ==> creation/filling of the hierarchy a->b->c
+  // The "folder" categories are unique whereas the leaves may exists
+  // in multiple instances.
+  // =================================================================
+  //
+  bool addData(DataObject * dataObject);
+  bool addData(DataObject * dataObject, const QStringList &path);
+
+  // TODO: We should implement the delete and the update fucntions
+
+  // This part contains helper functions for general purposes
+  TreeItem * getRootItem();
+
+private:
+  TreeItem *getItem(const QModelIndex &index = QModelIndex()) const;
+  TreeItem * _rootItem;
+};
+
+#endif // TREEMODEL_H
diff --git a/src/TreeData/TreeObserver.cxx b/src/TreeData/TreeObserver.cxx
new file mode 100644 (file)
index 0000000..8bf9103
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "TreeObserver.hxx"
+#include "QtHelper.hxx"
+
+TreeObserver::TreeObserver() : QObject() {
+}
+
+/*!
+ * This declares the TreeView to be observed by this tree events
+ * listener.
+ */
+void TreeObserver::observe(TreeView * treeView) {
+  // We just connect the signals emitted from the treeview to
+  // corresponding slots of this observer.
+  connect(treeView, SIGNAL(itemListToProcess(QStringList,int)),
+          this, SLOT(processItemList(QStringList,int)));
+}
+
+/*!
+ * This slot should be implemented in a specialized version of
+ * TreeObserver to process the signal emitted from the TreeView. The
+ * parameters are:
+ * - itemNameIdList: the list of name identifiers of model objects
+ *   associated to the selected qt items in the TreeView (ids for
+ *   requesting directly the data model).
+ * - actionId: the identifier of the action selected in the popup menu
+ *   that triggered this signal.
+ */
+void TreeObserver::processItemList(QStringList itemNameIdList, int actionId) {
+  LOG("TreeObserver::processItemList: signal received:\n"<<
+      "item list: "<<itemNameIdList<<"\n"<<
+      "action id: "<<actionId);
+}
+
diff --git a/src/TreeData/TreeObserver.hxx b/src/TreeData/TreeObserver.hxx
new file mode 100644 (file)
index 0000000..e0e1bf8
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _TREEOBSERVER_
+#define _TREEOBSERVER_
+
+#include "TreeData.hxx"
+
+#include <QObject>
+#include "TreeView.hxx"
+
+class TREEDATA_EXPORT TreeObserver : public QObject {
+
+  Q_OBJECT
+
+public:
+  TreeObserver();
+  void observe(TreeView * treeView);
+
+public slots:
+ /* These slots should be implemented in a specialized version of
+    the TreeObserver to process signals emitted from the TreeView */
+  virtual void processItemList(QStringList itemNameIdList, int actionId);
+};
+
+#endif // _TREEOBSERVER_
diff --git a/src/TreeData/TreeView.cxx b/src/TreeData/TreeView.cxx
new file mode 100644 (file)
index 0000000..bb82e5c
--- /dev/null
@@ -0,0 +1,144 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+// include Qt
+#include <QString>
+#include <QMenu>
+#include <QModelIndex>
+#include <QAbstractItemView>
+
+// include Xcad
+#include "TreeView.hxx"
+#include "TreeModel.hxx"
+#include "TreeItem.hxx"
+#include "QtHelper.hxx"
+
+TreeView::TreeView(QWidget * parent)
+  : QTreeView(parent)
+{
+  // We authorize the multiple selection of items
+  this->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+  _lastActionId = 0;
+
+  // Default actions for tests
+  int displayActionId = addAction(QObject::tr("Afficher"));
+  int editActionId    = addAction(QObject::tr("Editer"));
+}
+
+TreeView::~TreeView() {
+}
+
+/*!
+ * This function defines a menu item to add in the popup menu
+ * associated to this TreeView, and return an integer that corresponds
+ * to the unique identifier of this action (identifier used in the
+ * signal emitted to notify observers that an action has been
+ * selected). Then the caller of this function has to take care of
+ * this return id (i.e. has to store it in its internal tables) to be
+ * able to process the notifications from this TreeView.
+ */
+int TreeView::addAction(QString label) {
+  QAction * action = new QAction(this);
+  int actionId = _lastActionId;
+  action->setObjectName(_idToName(actionId));
+  action->setText(label);
+  _listActions << action;
+  _lastActionId++;
+
+  return actionId;
+}
+
+/*!
+ * This function removes all actions previously defined for the popup
+ * menu of this TreeView.
+ */
+void TreeView::clearActions() {
+  _listActions.clear();
+}
+
+/*!
+ * You must use this function to create the name of an action object
+ * from its id.
+ */
+QString TreeView::_idToName(int actionId) {
+  return QString::number(actionId);
+}
+/*!
+ * You must use this function to create the id of an action object
+ * from its name (stored in objectName() attribute of the QAction).
+ */
+int TreeView::_nameToId(QString actionName) {
+  return actionName.toInt();
+}
+
+void TreeView::contextMenuEvent(QContextMenuEvent *event) {
+  if ( _listActions.size() == 0 ) {
+    // Just return there is no actions defined for this popup menu
+    return;
+  }
+
+  // _TODO_ display the QMenu only if the selected item is acceptable
+  QMenu menu(this);
+  for (int i = 0; i < _listActions.size(); ++i) {
+    menu.addAction(_listActions.at(i));
+  }
+  connect(&menu, SIGNAL(triggered(QAction*)),
+         this,  SLOT(processMenuAction(QAction*)));
+
+  menu.exec(event->globalPos());
+}
+
+/*!
+ * This SLOT is connected on the signal emited by the menu when an
+ * action is selected.
+ */
+void TreeView::processMenuAction(QAction * actionSelected) {
+  LOG("processMenuAction: START");
+
+  // We first check than at least on item is selected
+  QModelIndexList indexList = this->selectionModel()->selectedRows(0);
+  if ( indexList.isEmpty() ) {
+    LOG("No item selected");
+    return;
+  }
+
+  // Then we can gather the list of model item ids associated the
+  // selection.
+  TreeModel *model = (TreeModel *)this->model();
+  QListIterator<QModelIndex> it(indexList);
+  QStringList nameIdList;
+  while (it.hasNext()) {
+    TreeItem * item = model->getItem(it.next());
+    nameIdList << item->nameId();
+  }
+
+  // Finally, one can emit a signal to observers specifying the list of
+  // id and the type of action (i.e. the action identifier)
+  int actionId = _nameToId(actionSelected->objectName());
+  LOG("TreeView::processMenuAction: signal emitted:\n"<<
+      "item list: "<<nameIdList<<"\n"<<
+      "action id: "<<actionId);
+  emit itemListToProcess(nameIdList, actionId);
+
+  LOG("processMenuAction: END");
+}
diff --git a/src/TreeData/TreeView.hxx b/src/TreeData/TreeView.hxx
new file mode 100644 (file)
index 0000000..a3711f0
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef TREEVIEW_H
+#define TREEVIEW_H
+
+#include "TreeData.hxx"
+
+#include <QTreeView>
+#include <QAction>
+#include <QContextMenuEvent>
+#include <QList>
+
+class TREEDATA_EXPORT TreeView : public QTreeView
+{
+  Q_OBJECT
+
+public:
+  TreeView(QWidget * parent = 0 );
+  ~TreeView();
+  int  addAction(QString label);
+  void clearActions();
+  
+protected:
+  void contextMenuEvent(QContextMenuEvent *event);
+
+private:
+  int _lastActionId;
+  QList<QAction*> _listActions;
+  QString _idToName(int actionId);
+  int _nameToId(QString actionName);
+  
+  // ---
+
+private slots:
+  void processMenuAction(QAction * actionSelected);
+  
+signals:
+  void itemListToProcess(QStringList itemNameIdList, int actionId);
+};
+
+#endif // TREEVIEW_H
+
diff --git a/src/VTKViewer/textures/texture1.dat b/src/VTKViewer/textures/texture1.dat
new file mode 100644 (file)
index 0000000..eb5e52c
--- /dev/null
@@ -0,0 +1,284 @@
+000000000
+000000000
+000000000
+000000000
+000010000
+000000000
+000000000
+000000000
+000000000
+
+00000000000
+00000000000
+00000000000
+00000000000
+00000110000
+00000110000
+00000000000
+00000000000
+00000000000
+00000000000
+00000000000
+
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000001100000
+0000001100000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000011000000
+000000011000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000001110000000
+00000001110000000
+00000001110000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000011110000000
+0000000011110000000
+0000000011110000000
+0000000011110000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000111100000000
+000000000111100000000
+000000000111100000000
+000000000111100000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000001111000000000
+00000000001111000000000
+00000000001111000000000
+00000000001111000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
diff --git a/src/VTKViewer/textures/texture2.dat b/src/VTKViewer/textures/texture2.dat
new file mode 100644 (file)
index 0000000..431f780
--- /dev/null
@@ -0,0 +1,284 @@
+000010000
+000010000
+000010000
+000010000
+111111111
+000010000
+000010000
+000010000
+000010000
+
+00000100000
+00000100000
+00000100000
+00000100000
+00000100000
+11111111111
+00000100000
+00000100000
+00000100000
+00000100000
+00000100000
+
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+1111111111111
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+111111111111111
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+11111111111111111
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+1111111111111111111
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+111111111111111111111
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+11111111111111111111111
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+1111111111111111111111111
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+111111111111111111111111111
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+11111111111111111111111111111
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+1111111111111111111111111111111
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+11111111111111111111111111111111
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
diff --git a/src/VTKViewer/textures/texture3.dat b/src/VTKViewer/textures/texture3.dat
new file mode 100644 (file)
index 0000000..21683f1
--- /dev/null
@@ -0,0 +1,284 @@
+000010000
+000010000
+110010011
+001111100
+000010000
+001111100
+110010011
+000010000
+000010000
+
+00000100000
+00000100000
+10000100001
+01100100110
+00011111000
+00000100000
+00011111000
+01100100110
+10000100001
+00000100000
+00000100000
+
+0000001000000
+0000001000000
+0000001000000
+1100001000011
+0011001001100
+0000111110000
+0000001000000
+0000111110000
+0011001001100
+1100001000011
+0000001000000
+0000001000000
+0000001000000
+
+000000010000000
+000000010000000
+000000010000000
+100000010000001
+011000010000110
+000110010011000
+000001111100000
+000000010000000
+000001111100000
+000110010011000
+011000010000110
+100000010000001
+000000010000000
+000000010000000
+000000010000000
+
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+11000000100000011
+00110000100001100
+00001100100110000
+00000011111000000
+00000000100000000
+00000011111000000
+00001100100110000
+00110000100001100
+11000000100000011
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+1000000001000000001
+0110000001000000110
+0001100001000011000
+0000011001001100000
+0000000111110000000
+0000000001000000000
+0000000111110000000
+0000011001001100000
+0001100001000011000
+0110000001000000110
+1000000001000000001
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+110000000010000000011
+001100000010000001100
+000011000010000110000
+000000110010011000000
+000000001111100000000
+000000000010000000000
+000000001111100000000
+000000110010011000000
+000011000010000110000
+001100000010000001100
+110000000010000000011
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+10000000000100000000001
+01100000000100000000110
+00011000000100000011000
+00000110000100001100000
+00000001100100110000000
+00000000011111000000000
+00000000000100000000000
+00000000011111000000000
+00000001100100110000000
+00000110000100001100000
+00011000000100000011000
+01100000000100000000110
+10000000000100000000001
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+1100000000001000000000011
+0011000000001000000001100
+0000110000001000000110000
+0000001100001000011000000
+0000000011001001100000000
+0000000000111110000000000
+0000000000001000000000000
+0000000000111110000000000
+0000000011001001100000000
+0000001100001000011000000
+0000110000001000000110000
+0011000000001000000001100
+1100000000001000000000011
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+100000000000010000000000001
+011000000000010000000000110
+000110000000010000000011000
+000001100000010000001100000
+000000011000010000110000000
+000000000110010011000000000
+000000000001111100000000000
+000000000000010000000000000
+000000000001111100000000000
+000000000110010011000000000
+000000011000010000110000000
+000001100000010000001100000
+000110000000010000000011000
+011000000000010000000000110
+100000000000010000000000001
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+11000000000000100000000000011
+00110000000000100000000001100
+00001100000000100000000110000
+00000011000000100000011000000
+00000000110000100001100000000
+00000000001100100110000000000
+00000000000011111000000000000
+00000000000000100000000000000
+00000000000011111000000000000
+00000000001100100110000000000
+00000000110000100001100000000
+00000011000000100000011000000
+00001100000000100000000110000
+00110000000000100000000001100
+11000000000000100000000000011
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+1000000000000001000000000000001
+0110000000000001000000000000110
+0001100000000001000000000011000
+0000011000000001000000001100000
+0000000110000001000000110000000
+0000000001100001000011000000000
+0000000000011001001100000000000
+0000000000000111110000000000000
+0000000000000001000000000000000
+0000000000000111110000000000000
+0000000000011001001100000000000
+0000000001100001000011000000000
+0000000110000001000000110000000
+0000011000000001000000001100000
+0001100000000001000000000011000
+0110000000000001000000000000110
+1000000000000001000000000000001
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+10000000000000010000000000000010
+01100000000000010000000000001100
+00011000000000010000000000110000
+00000110000000010000000011000000
+00000001100000010000001100000000
+00000000011000010000110000000000
+00000000000110010011000000000000
+00000000000001111100000000000000
+00000000000001111100000000000000
+00000000000110010011000000000000
+00000000011000010000110000000000
+00000001100000010000001100000000
+00000110000000010000000011000000
+00011000000000010000000000110000
+01100000000000010000000000001100
+10000000000000010000000000000010
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
diff --git a/src/VTKViewer/textures/texture4.dat b/src/VTKViewer/textures/texture4.dat
new file mode 100644 (file)
index 0000000..3d69641
--- /dev/null
@@ -0,0 +1,284 @@
+000111000
+011000110
+010000010
+100000001
+100000001
+100000001
+010000010
+011000110
+000111000
+
+00001110000
+00110001100
+01000000010
+01000000010
+10000000001
+10000000001
+10000000001
+01000000010
+01000000010
+00110001100
+00001110000
+
+0000111110000
+0001000001000
+0010000000100
+0100000000010
+0100000000010
+1000000000001
+1000000000001
+1000000000001
+0100000000010
+0100000000010
+0010000000100
+0001000001000
+0000111110000
+
+000001111100000
+000110000011000
+001000000000100
+010000000000010
+010000000000010
+100000000000001
+100000000000001
+100000000000001
+100000000000001
+100000000000001
+010000000000010
+010000000000010
+001000000000100
+000110000011000
+000001111100000
+
+00000011111000000
+00001100000110000
+00010000000001000
+00100000000000100
+01000000000000010
+01000000000000010
+10000000000000001
+10000000000000001
+10000000000000001
+10000000000000001
+10000000000000001
+01000000000000010
+01000000000000010
+00100000000000100
+00010000000001000
+00001100000110000
+00000011111000000
+
+0000000111110000000
+0000011000001100000
+0001100000000011000
+0010000000000000100
+0010000000000000100
+0100000000000000010
+0100000000000000010
+1000000000000000001
+1000000000000000001
+1000000000000000001
+1000000000000000001
+1000000000000000001
+0100000000000000010
+0100000000000000010
+0010000000000000100
+0010000000000000100
+0001100000000011000
+0000011000001100000
+0000000111110000000
+
+000000001111100000000
+000000110000011000000
+000011000000000110000
+000100000000000001000
+001000000000000000100
+001000000000000000100
+010000000000000000010
+010000000000000000010
+100000000000000000001
+100000000000000000001
+100000000000000000001
+100000000000000000001
+100000000000000000001
+010000000000000000010
+010000000000000000010
+001000000000000000100
+001000000000000000100
+000100000000000001000
+000011000000000110000
+000000110000011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100000111000000
+00000100000000000100000
+00011000000000000011000
+00010000000000000001000
+00100000000000000000100
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+10000000000000000000001
+10000000000000000000001
+10000000000000000000001
+10000000000000000000001
+10000000000000000000001
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+00100000000000000000100
+00010000000000000001000
+00011000000000000011000
+00000100000000000100000
+00000011100000111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111000001110000000
+0000011000000000001100000
+0000100000000000000010000
+0001000000000000000001000
+0010000000000000000000100
+0010000000000000000000100
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+1000000000000000000000001
+1000000000000000000000001
+1000000000000000000000001
+1000000000000000000000001
+1000000000000000000000001
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+0010000000000000000000100
+0010000000000000000000100
+0001000000000000000001000
+0000100000000000000010000
+0000011000000000001100000
+0000000111000001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110000011100000000
+000000110000000000011000000
+000001000000000000000100000
+000010000000000000000010000
+000100000000000000000001000
+001000000000000000000000100
+001000000000000000000000100
+010000000000000000000000010
+010000000000000000000000010
+010000000000000000000000010
+100000000000000000000000001
+100000000000000000000000001
+100000000000000000000000001
+100000000000000000000000001
+100000000000000000000000001
+010000000000000000000000010
+010000000000000000000000010
+010000000000000000000000010
+001000000000000000000000100
+001000000000000000000000100
+000100000000000000000001000
+000010000000000000000010000
+000001000000000000000100000
+000000110000000000011000000
+000000001110000011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100000111100000000
+00000001100000000000010000000
+00000010000000000000001100000
+00001100000000000000000010000
+00001000000000000000000001000
+00010000000000000000000001000
+00100000000000000000000000100
+00100000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+10000000000000000000000000001
+10000000000000000000000000001
+10000000000000000000000000001
+10000000000000000000000000001
+10000000000000000000000000001
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+00100000000000000000000000010
+00100000000000000000000000100
+00010000000000000000000001000
+00001000000000000000000001000
+00001100000000000000000110000
+00000010000000000000001000000
+00000001100000000000110000000
+00000000011100000111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111000001111000000000
+0000000010000000000000100000000
+0000001100000000000000011000000
+0000010000000000000000000100000
+0000100000000000000000000010000
+0001000000000000000000000001000
+0001000000000000000000000001000
+0010000000000000000000000000100
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+1000000000000000000000000000001
+1000000000000000000000000000001
+1000000000000000000000000000001
+1000000000000000000000000000001
+1000000000000000000000000000001
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0010000000000000000000000000100
+0001000000000000000000000001000
+0001000000000000000000000001000
+0000100000000000000000000010000
+0000010000000000000000000100000
+0000001100000000000000011000000
+0000000010000000000000100000000
+0000000001111000001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110000001110000000000
+00000000110000000000001100000000
+00000001000000000000000010000000
+00000110000000000000000001100000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00010000000000000000000000001000
+00100000000000000000000000000100
+00100000000000000000000000000100
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+10000000000000000000000000000001
+10000000000000000000000000000001
+10000000000000000000000000000001
+10000000000000000000000000000001
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+00100000000000000000000000000100
+00100000000000000000000000000100
+00010000000000000000000000001000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00000110000000000000000001100000
+00000001000000000000000010000000
+00000000110000000000001100000000
+00000000001110000001110000000000
+00000000000001111110000000000000
diff --git a/src/VTKViewer/textures/texture5.dat b/src/VTKViewer/textures/texture5.dat
new file mode 100644 (file)
index 0000000..221e1e9
--- /dev/null
@@ -0,0 +1,284 @@
+100000001
+010000010
+001000100
+000101000
+000010000
+000101000
+001000100
+010000010
+100000001
+
+10000000001
+01000000010
+00100000100
+00010001000
+00001010000
+00000100000
+00001010000
+00010001000
+00100000100
+01000000010
+10000000001
+
+1000000000001
+0100000000010
+0010000000100
+0001000001000
+0000100010000
+0000010100000
+0000001000000
+0000010100000
+0000100010000
+0001000001000
+0010000000100
+0100000000010
+1000000000001
+
+100000000000001
+010000000000010
+001000000000100
+000100000001000
+000010000010000
+000001000100000
+000000101000000
+000000010000000
+000000101000000
+000001000100000
+000010000010000
+000100000001000
+001000000000100
+010000000000010
+100000000000001
+
+10000000000000001
+01000000000000010
+00100000000000100
+00010000000001000
+00001000000010000
+00000100000100000
+00000010001000000
+00000001010000000
+00000000100000000
+00000001010000000
+00000010001000000
+00000100000100000
+00001000000010000
+00010000000001000
+00100000000000100
+01000000000000010
+10000000000000001
+
+1000000000000000001
+0100000000000000010
+0010000000000000100
+0001000000000001000
+0000100000000010000
+0000010000000100000
+0000001000001000000
+0000000100010000000
+0000000010100000000
+0000000001000000000
+0000000010100000000
+0000000100010000000
+0000001000001000000
+0000010000000100000
+0000100000000010000
+0001000000000001000
+0010000000000000100
+0100000000000000010
+1000000000000000001
+
+100000000000000000001
+010000000000000000010
+001000000000000000100
+000100000000000001000
+000010000000000010000
+000001000000000100000
+000000100000001000000
+000000010000010000000
+000000001000100000000
+000000000101000000000
+000000000010000000000
+000000000101000000000
+000000001000100000000
+000000010000010000000
+000000100000001000000
+000001000000000100000
+000010000000000010000
+000100000000000001000
+001000000000000000100
+010000000000000000010
+100000000000000000001
+
+10000000000000000000001
+01000000000000000000010
+00100000000000000000100
+00010000000000000001000
+00001000000000000010000
+00000100000000000100000
+00000010000000001000000
+00000001000000010000000
+00000000100000100000000
+00000000010001000000000
+00000000001010000000000
+00000000000100000000000
+00000000001010000000000
+00000000010001000000000
+00000000100000100000000
+00000001000000010000000
+00000010000000001000000
+00000100000000000100000
+00001000000000000010000
+00010000000000000001000
+00100000000000000000100
+01000000000000000000010
+10000000000000000000001
+
+1000000000000000000000001
+0100000000000000000000010
+0010000000000000000000100
+0001000000000000000001000
+0000100000000000000010000
+0000010000000000000100000
+0000001000000000001000000
+0000000100000000010000000
+0000000010000000100000000
+0000000001000001000000000
+0000000000100010000000000
+0000000000010100000000000
+0000000000001000000000000
+0000000000010100000000000
+0000000000100010000000000
+0000000001000001000000000
+0000000010000000100000000
+0000000100000000010000000
+0000001000000000001000000
+0000010000000000000100000
+0000100000000000000010000
+0001000000000000000001000
+0010000000000000000000100
+0100000000000000000000010
+1000000000000000000000001
+
+100000000000000000000000001
+010000000000000000000000010
+001000000000000000000000100
+000100000000000000000001000
+000010000000000000000010000
+000001000000000000000100000
+000000100000000000001000000
+000000010000000000010000000
+000000001000000000100000000
+000000000100000001000000000
+000000000010000010000000000
+000000000001000100000000000
+000000000000101000000000000
+000000000000010000000000000
+000000000000101000000000000
+000000000001000100000000000
+000000000010000010000000000
+000000000100000001000000000
+000000001000000000100000000
+000000010000000000010000000
+000000100000000000001000000
+000001000000000000000100000
+000010000000000000000010000
+000100000000000000000001000
+001000000000000000000000100
+010000000000000000000000010
+100000000000000000000000001
+
+10000000000000000000000000001
+01000000000000000000000000010
+00100000000000000000000000100
+00010000000000000000000001000
+00001000000000000000000010000
+00000100000000000000000100000
+00000010000000000000001000000
+00000001000000000000010000000
+00000000100000000000100000000
+00000000010000000001000000000
+00000000001000000010000000000
+00000000000100000100000000000
+00000000000010001000000000000
+00000000000001010000000000000
+00000000000000100000000000000
+00000000000001010000000000000
+00000000000010001000000000000
+00000000000100000100000000000
+00000000001000000010000000000
+00000000010000000001000000000
+00000000100000000000100000000
+00000001000000000000010000000
+00000010000000000000001000000
+00000100000000000000000100000
+00001000000000000000000010000
+00010000000000000000000001000
+00100000000000000000000000100
+01000000000000000000000000010
+10000000000000000000000000001
+
+1000000000000000000000000000001
+0100000000000000000000000000010
+0010000000000000000000000000100
+0001000000000000000000000001000
+0000100000000000000000000010000
+0000010000000000000000000100000
+0000001000000000000000001000000
+0000000100000000000000010000000
+0000000010000000000000100000000
+0000000001000000000001000000000
+0000000000100000000010000000000
+0000000000010000000100000000000
+0000000000001000001000000000000
+0000000000000100010000000000000
+0000000000000010100000000000000
+0000000000000001000000000000000
+0000000000000010100000000000000
+0000000000000100010000000000000
+0000000000001000001000000000000
+0000000000010000000100000000000
+0000000000100000000010000000000
+0000000001000000000001000000000
+0000000010000000000000100000000
+0000000100000000000000010000000
+0000001000000000000000001000000
+0000010000000000000000000100000
+0000100000000000000000000010000
+0001000000000000000000000001000
+0010000000000000000000000000100
+0100000000000000000000000000010
+1000000000000000000000000000001
+
+10000000000000000000000000000001
+01000000000000000000000000000010
+00100000000000000000000000000100
+00010000000000000000000000001000
+00001000000000000000000000010000
+00000100000000000000000000100000
+00000010000000000000000001000000
+00000001000000000000000010000000
+00000000100000000000000100000000
+00000000010000000000001000000000
+00000000001000000000010000000000
+00000000000100000000100000000000
+00000000000010000001000000000000
+00000000000001000010000000000000
+00000000000000100100000000000000
+00000000000000011000000000000000
+00000000000000011000000000000000
+00000000000000100100000000000000
+00000000000001000010000000000000
+00000000000010000001000000000000
+00000000000100000000100000000000
+00000000001000000000010000000000
+00000000010000000000001000000000
+00000000100000000000000100000000
+00000001000000000000000010000000
+00000010000000000000000001000000
+00000100000000000000000000100000
+00001000000000000000000000010000
+00010000000000000000000000001000
+00100000000000000000000000000100
+01000000000000000000000000000010
+10000000000000000000000000000001
diff --git a/src/VTKViewer/textures/texture6.dat b/src/VTKViewer/textures/texture6.dat
new file mode 100644 (file)
index 0000000..caf5163
--- /dev/null
@@ -0,0 +1,284 @@
+000111000
+011000110
+010000010
+100000001
+100010001
+100000001
+010000010
+011000110
+000111000
+
+00001110000
+00110001100
+01000000010
+01000000010
+10000110001
+10000110001
+10000000001
+01000000010
+01000000010
+00110001100
+00001110000
+
+0000111110000
+0001000001000
+0010000000100
+0100000000010
+0100000000010
+1000001100001
+1000001100001
+1000000000001
+0100000000010
+0100000000010
+0010000000100
+0001000001000
+0000111110000
+
+000001111100000
+000110000011000
+001000000000100
+010000000000010
+010000000000010
+100000000000001
+100000011000001
+100000011000001
+100000000000001
+100000000000001
+010000000000010
+010000000000010
+001000000000100
+000110000011000
+000001111100000
+
+00000011111000000
+00001100000110000
+00010000000001000
+00100000000000100
+01000000000000010
+01000000000000010
+10000000000000001
+10000001110000001
+10000001110000001
+10000001110000001
+10000000000000001
+01000000000000010
+01000000000000010
+00100000000000100
+00010000000001000
+00001100000110000
+00000011111000000
+
+0000000111110000000
+0000011000001100000
+0001100000000011000
+0010000000000000100
+0010000000000000100
+0100000000000000010
+0100000000000000010
+1000000011110000001
+1000000011110000001
+1000000011110000001
+1000000011110000001
+1000000000000000001
+0100000000000000010
+0100000000000000010
+0010000000000000100
+0010000000000000100
+0001100000000011000
+0000011000001100000
+0000000111110000000
+
+000000001111100000000
+000000110000011000000
+000011000000000110000
+000100000000000001000
+001000000000000000100
+001000000000000000100
+010000000000000000010
+010000000000000000010
+100000000111100000001
+100000000111100000001
+100000000111100000001
+100000000111100000001
+100000000000000000001
+010000000000000000010
+010000000000000000010
+001000000000000000100
+001000000000000000100
+000100000000000001000
+000011000000000110000
+000000110000011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100000111000000
+00000100000000000100000
+00011000000000000011000
+00010000000000000001000
+00100000000000000000100
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+10000000001111000000001
+10000000001111000000001
+10000000001111000000001
+10000000001111000000001
+10000000000000000000001
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+00100000000000000000100
+00010000000000000001000
+00011000000000000011000
+00000100000000000100000
+00000011100000111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111000001110000000
+0000011000000000001100000
+0000100000000000000010000
+0001000000000000000001000
+0010000000000000000000100
+0010000000000000000000100
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+1000000000111110000000001
+1000000000111110000000001
+1000000000111110000000001
+1000000000111110000000001
+1000000000111110000000001
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+0010000000000000000000100
+0010000000000000000000100
+0001000000000000000001000
+0000100000000000000010000
+0000011000000000001100000
+0000000111000001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110000011100000000
+000000110000000000011000000
+000001000000000000000100000
+000010000000000000000010000
+000100000000000000000001000
+001000000000000000000000100
+001000000000000000000000100
+010000000000000000000000010
+010000000000000000000000010
+010000000001111110000000010
+100000000001111110000000001
+100000000001111110000000001
+100000000001111110000000001
+100000000001111110000000001
+100000000001111110000000001
+010000000000000000000000010
+010000000000000000000000010
+010000000000000000000000010
+001000000000000000000000100
+001000000000000000000000100
+000100000000000000000001000
+000010000000000000000010000
+000001000000000000000100000
+000000110000000000011000000
+000000001110000011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100000111100000000
+00000001100000000000010000000
+00000010000000000000001100000
+00001100000000000000000010000
+00001000000000000000000001000
+00010000000000000000000001000
+00100000000000000000000000100
+00100000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000011111100000000010
+10000000000011111100000000001
+10000000000011111100000000001
+10000000000011111100000000001
+10000000000011111100000000001
+10000000000011111100000000001
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+00100000000000000000000000010
+00100000000000000000000000100
+00010000000000000000000001000
+00001000000000000000000001000
+00001100000000000000000110000
+00000010000000000000001000000
+00000001100000000000110000000
+00000000011100000111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111000001111000000000
+0000000010000000000000100000000
+0000001100000000000000011000000
+0000010000000000000000000100000
+0000100000000000000000000010000
+0001000000000000000000000001000
+0001000000000000000000000001000
+0010000000000000000000000000100
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000111111000000000010
+1000000000000111111000000000001
+1000000000000111111000000000001
+1000000000000111111000000000001
+1000000000000111111000000000001
+1000000000000111111000000000001
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0010000000000000000000000000100
+0001000000000000000000000001000
+0001000000000000000000000001000
+0000100000000000000000000010000
+0000010000000000000000000100000
+0000001100000000000000011000000
+0000000010000000000000100000000
+0000000001111000001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110000001110000000000
+00000000110000000000001100000000
+00000001000000000000000010000000
+00000110000000000000000001100000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00010000000000000000000000001000
+00100000000000000000000000000100
+00100000000000000000000000000100
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000001111111000000000010
+01000000000001111111000000000010
+10000000000001111111000000000001
+10000000000001111111000000000001
+10000000000001111111000000000001
+10000000000001111111000000000001
+01000000000001111111000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+00100000000000000000000000000100
+00100000000000000000000000000100
+00010000000000000000000000001000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00000110000000000000000001100000
+00000001000000000000000010000000
+00000000110000000000001100000000
+00000000001110000001110000000000
+00000000000001111110000000000000
diff --git a/src/VTKViewer/textures/texture7.dat b/src/VTKViewer/textures/texture7.dat
new file mode 100644 (file)
index 0000000..a75e7bb
--- /dev/null
@@ -0,0 +1,284 @@
+000111000
+011010110
+010010010
+100010001
+111111111
+100010001
+010010010
+011010110
+000111000
+
+00001110000
+00110101100
+01000100010
+01000100010
+10000100001
+11111111111
+10000100001
+01000100010
+01000100010
+00110101100
+00001110000
+
+0000111110000
+0001001001000
+0010001000100
+0100001000010
+0100001000010
+1000001000001
+1111111111111
+1000001000001
+0100001000010
+0100001000010
+0010001000100
+0001001001000
+0000111110000
+
+000001111100000
+000110010011000
+001000010000100
+010000010000010
+010000010000010
+100000010000001
+100000010000001
+111111111111111
+100000010000001
+100000010000001
+010000010000010
+010000010000010
+001000010000100
+000110010011000
+000001111100000
+
+00000011111000000
+00001100100110000
+00010000100001000
+00100000100000100
+01000000100000010
+01000000100000010
+10000000100000001
+10000000100000001
+11111111111111111
+10000000100000001
+10000000100000001
+01000000100000010
+01000000100000010
+00100000100000100
+00010000100001000
+00001100100110000
+00000011111000000
+
+0000000111110000000
+0000011001001100000
+0001100001000011000
+0010000001000000100
+0010000001000000100
+0100000001000000010
+0100000001000000010
+1000000001000000001
+1000000001000000001
+1111111111111111111
+1000000001000000001
+1000000001000000001
+0100000001000000010
+0100000001000000010
+0010000001000000100
+0010000001000000100
+0001100001000011000
+0000011001001100000
+0000000111110000000
+
+000000001111100000000
+000000110010011000000
+000011000010000110000
+000100000010000001000
+001000000010000000100
+001000000010000000100
+010000000010000000010
+010000000010000000010
+100000000010000000001
+100000000010000000001
+111111111111111111111
+100000000010000000001
+100000000010000000001
+010000000010000000010
+010000000010000000010
+001000000010000000100
+001000000010000000100
+000100000010000001000
+000011000010000110000
+000000110010011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100100111000000
+00000100000100000100000
+00011000000100000011000
+00010000000100000001000
+00100000000100000000100
+01000000000100000000010
+01000000000100000000010
+01000000000100000000010
+10000000000100000000001
+10000000000100000000001
+11111111111111111111111
+10000000000100000000001
+10000000000100000000001
+01000000000100000000010
+01000000000100000000010
+01000000000100000000010
+00100000000100000000100
+00010000000100000001000
+00011000000100000011000
+00000100000100000100000
+00000011100100111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111001001110000000
+0000011000001000001100000
+0000100000001000000010000
+0001000000001000000001000
+0010000000001000000000100
+0010000000001000000000100
+0100000000001000000000010
+0100000000001000000000010
+0100000000001000000000010
+1000000000001000000000001
+1000000000001000000000001
+1111111111111111111111111
+1000000000001000000000001
+1000000000001000000000001
+0100000000001000000000010
+0100000000001000000000010
+0100000000001000000000010
+0010000000001000000000100
+0010000000001000000000100
+0001000000001000000001000
+0000100000001000000010000
+0000011000001000001100000
+0000000111001001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110010011100000000
+000000110000010000011000000
+000001000000010000000100000
+000010000000010000000010000
+000100000000010000000001000
+001000000000010000000000100
+001000000000010000000000100
+010000000000010000000000010
+010000000000010000000000010
+010000000000010000000000010
+100000000000010000000000001
+100000000000010000000000001
+111111111111111111111111111
+100000000000010000000000001
+100000000000010000000000001
+010000000000010000000000010
+010000000000010000000000010
+010000000000010000000000010
+001000000000010000000000100
+001000000000010000000000100
+000100000000010000000001000
+000010000000010000000010000
+000001000000010000000100000
+000000110000010000011000000
+000000001110010011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100100111100000000
+00000001100000100000010000000
+00000010000000100000001100000
+00001100000000100000000010000
+00001000000000100000000001000
+00010000000000100000000001000
+00100000000000100000000000100
+00100000000000100000000000010
+01000000000000100000000000010
+01000000000000100000000000010
+01000000000000100000000000010
+10000000000000100000000000001
+10000000000000100000000000001
+11111111111111111111111111111
+10000000000000100000000000001
+10000000000000100000000000001
+01000000000000100000000000010
+01000000000000100000000000010
+01000000000000100000000000010
+00100000000000100000000000010
+00100000000000100000000000100
+00010000000000100000000001000
+00001000000000100000000001000
+00001100000000100000000110000
+00000010000000100000001000000
+00000001100000100000110000000
+00000000011100100111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111001001111000000000
+0000000010000001000000100000000
+0000001100000001000000011000000
+0000010000000001000000000100000
+0000100000000001000000000010000
+0001000000000001000000000001000
+0001000000000001000000000001000
+0010000000000001000000000000100
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+1000000000000001000000000000001
+1000000000000001000000000000001
+1111111111111111111111111111111
+1000000000000001000000000000001
+1000000000000001000000000000001
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+0010000000000001000000000000100
+0001000000000001000000000001000
+0001000000000001000000000001000
+0000100000000001000000000010000
+0000010000000001000000000100000
+0000001100000001000000011000000
+0000000010000001000000100000000
+0000000001111001001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110010001110000000000
+00000000110000010000001100000000
+00000001000000010000000010000000
+00000110000000010000000001100000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00010000000000010000000000001000
+00100000000000010000000000000100
+00100000000000010000000000000100
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+10000000000000010000000000000001
+11111111111111111111111111111111
+10000000000000010000000000000001
+10000000000000010000000000000001
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+00100000000000010000000000000100
+00100000000000010000000000000100
+00010000000000010000000000001000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00000110000000010000000001100000
+00000001000000010000000010000000
+00000000110000010000001100000000
+00000000001110010001110000000000
+00000000000001111110000000000000
diff --git a/src/VTKViewer/textures/texture8.dat b/src/VTKViewer/textures/texture8.dat
new file mode 100644 (file)
index 0000000..7ffdbf0
--- /dev/null
@@ -0,0 +1,284 @@
+000111000
+011010110
+110010011
+101111101
+100010001
+101111101
+110010011
+011010110
+000111000
+
+00001110000
+00110101100
+11000100011
+01100100110
+10011111001
+10000100001
+10011111001
+01100100110
+11000100011
+00110101100
+00001110000
+
+0000111110000
+0001001001000
+0010001000100
+1100001000011
+0111001001110
+1000111110001
+1000001000001
+1000111110001
+0111001001110
+1100001000011
+0010001000100
+0001001001000
+0000111110000
+
+000001111100000
+000110010011000
+001000010000100
+110000010000011
+011000010000110
+100110010011001
+100001111100001
+100000010000001
+100001111100001
+100110010011001
+011000010000110
+110000010000011
+001000010000100
+000110010011000
+000001111100000
+
+00000011111000000
+00001100100110000
+00010000100001000
+00100000100000100
+11000000100000011
+01110000100001110
+10001100100110001
+10000011111000001
+10000000100000001
+10000011111000001
+10001100100110001
+01110000100001110
+11000000100000011
+00100000100000100
+00010000100001000
+00001100100110000
+00000011111000000
+
+0000000111110000000
+0000011001001100000
+0001100001000011000
+0010000001000000100
+1010000001000000101
+0110000001000000110
+0101100001000011010
+1000011001001100001
+1000000111110000001
+1000000001000000001
+1000000111110000001
+1000011001001100001
+0101100001000011010
+0110000001000000110
+1010000001000000101
+0010000001000000100
+0001100001000011000
+0000011001001100000
+0000000111110000000
+
+000000001111100000000
+000000110010011000000
+000011000010000110000
+000100000010000001000
+001000000010000000100
+111000000010000000111
+011100000010000001110
+010011000010000110010
+100000110010011000001
+100000001111100000001
+100000000010000000001
+100000001111100000001
+100000110010011000001
+010011000010000110010
+011100000010000001110
+111000000010000000111
+001000000010000000100
+000100000010000001000
+000011000010000110000
+000000110010011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100100111000000
+00000100000100000100000
+00011000000100000011000
+00010000000100000001000
+10100000000100000000101
+01100000000100000000110
+01011000000100000011010
+01000110000100001100010
+10000001100100110000001
+10000000011111000000001
+10000000000100000000001
+10000000011111000000001
+10000001100100110000001
+01000110000100001100010
+01011000000100000011010
+01100000000100000000110
+10100000000100000000101
+00010000000100000001000
+00011000000100000011000
+00000100000100000100000
+00000011100100111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111001001110000000
+0000011000001000001100000
+0000100000001000000010000
+0001000000001000000001000
+0010000000001000000000100
+1110000000001000000000111
+0111000000001000000001110
+0100110000001000000110010
+0100001100001000011000010
+1000000011001001100000001
+1000000000111110000000001
+1000000000001000000000001
+1000000000111110000000001
+1000000011001001100000001
+0100001100001000011000010
+0100110000001000000110010
+0111000000001000000001110
+1110000000001000000000111
+0010000000001000000000100
+0001000000001000000001000
+0000100000001000000010000
+0000011000001000001100000
+0000000111001001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110010011100000000
+000000110000010000011000000
+000001000000010000000100000
+000010000000010000000010000
+000100000000010000000001000
+101000000000010000000000101
+011000000000010000000000110
+010110000000010000000011010
+010001100000010000001100010
+010000011000010000110000010
+100000000110010011000000001
+100000000001111100000000001
+100000000000010000000000001
+100000000001111100000000001
+100000000110010011000000001
+010000011000010000110000010
+010001100000010000001100010
+010110000000010000000011010
+011000000000010000000000110
+101000000000010000000000101
+000100000000010000000001000
+000010000000010000000010000
+000001000000010000000100000
+000000110000010000011000000
+000000001110010011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100100111100000000
+00000001100000100000010000000
+00000010000000100000001100000
+00001100000000100000000010000
+00001000000000100000000001000
+00010000000000100000000001000
+11100000000000100000000000111
+00110000000000100000000001110
+01001100000000100000000110010
+01000011000000100000011000010
+01000000110000100001100000010
+10000000001100100110000000001
+10000000000011111000000000001
+10000000000000100000000000001
+10000000000011111000000000001
+10000000001100100110000000001
+01000000110000100001100000010
+01000011000000100000011000010
+01001100000000100000000110010
+00110000000000100000000001110
+11100000000000100000000000111
+00010000000000100000000001000
+00001000000000100000000001000
+00001100000000100000000110000
+00000010000000100000001000000
+00000001100000100000110000000
+00000000011100100111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111001001111000000000
+0000000010000001000000100000000
+0000001100000001000000011000000
+0000010000000001000000000100000
+0000100000000001000000000010000
+0001000000000001000000000001000
+1001000000000001000000000001001
+0110000000000001000000000000110
+0101100000000001000000000011010
+0100011000000001000000001100010
+0100000110000001000000110000010
+0100000001100001000011000000010
+1000000000011001001100000000001
+1000000000000111110000000000001
+1000000000000001000000000000001
+1000000000000111110000000000001
+1000000000011001001100000000001
+0100000001100001000011000000010
+0100000110000001000000110000010
+0100011000000001000000001100010
+0101100000000001000000000011010
+0110000000000001000000000000110
+1001000000000001000000000001001
+0001000000000001000000000001000
+0000100000000001000000000010000
+0000010000000001000000000100000
+0000001100000001000000011000000
+0000000010000001000000100000000
+0000000001111001001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110010001110000000000
+00000000110000010000001100000000
+00000001000000010000000010000000
+00000110000000010000000001100000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00010000000000010000000000001000
+10100000000000010000000000000110
+01100000000000010000000000001100
+01011000000000010000000000110010
+01000110000000010000000011000010
+01000001100000010000001100000010
+01000000011000010000110000000010
+10000000000110010011000000000001
+10000000000001111100000000000001
+10000000000001111100000000000001
+10000000000110010011000000000001
+01000000011000010000110000000010
+01000001100000010000001100000010
+01000110000000010000000011000010
+01011000000000010000000000110010
+01100000000000010000000000001100
+10100000000000010000000000000110
+00010000000000010000000000001000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00000110000000010000000001100000
+00000001000000010000000010000000
+00000000110000010000001100000000
+00000000001110010001110000000000
+00000000000001111110000000000000
diff --git a/src/VTKViewer/textures/texture9.dat b/src/VTKViewer/textures/texture9.dat
new file mode 100644 (file)
index 0000000..01fa9ee
--- /dev/null
@@ -0,0 +1,284 @@
+100111001
+011000110
+011000110
+100101001
+100010001
+100101001
+011000110
+011000110
+100111001
+
+10001110001
+01110001110
+01100000110
+01010001010
+10001010001
+10000100001
+10001010001
+01010001010
+01100000110
+01110001110
+10001110001
+
+1000111110001
+0101000001010
+0010000000100
+0101000001010
+0100100010010
+1000010100001
+1000001000001
+1000010100001
+0100100010010
+0101000001010
+0010000000100
+0101000001010
+1000111110001
+
+100001111100001
+010110000011010
+001000000000100
+010100000001010
+010010000010010
+100001000100001
+100000101000001
+100000010000001
+100000101000001
+100001000100001
+010010000010010
+010100000001010
+001000000000100
+010110000011010
+100001111100001
+
+10000011111000001
+01001100000110010
+00110000000001100
+00110000000001100
+01001000000010010
+01000100000100010
+10000010001000001
+10000001010000001
+10000000100000001
+10000001010000001
+10000010001000001
+01000100000100010
+01001000000010010
+00110000000001100
+00110000000001100
+01001100000110010
+10000011111000001
+
+1000000111110000001
+0100011000001100010
+0011100000000011100
+0011000000000001100
+0010100000000010100
+0100010000000100010
+0100001000001000010
+1000000100010000001
+1000000010100000001
+1000000001000000001
+1000000010100000001
+1000000100010000001
+0100001000001000010
+0100010000000100010
+0010100000000010100
+0011000000000001100
+0011100000000011100
+0100011000001100010
+1000000111110000001
+
+100000001111100000001
+010000110000011000010
+001011000000000110100
+000100000000000001000
+001010000000000010100
+001001000000000100100
+010000100000001000010
+010000010000010000010
+100000001000100000001
+100000000101000000001
+100000000010000000001
+100000000101000000001
+100000001000100000001
+010000010000010000010
+010000100000001000010
+001001000000000100100
+001010000000000010100
+000100000000000001000
+001011000000000110100
+010000110000011000010
+100000001111100000001
+
+10000000011111000000001
+01000011100000111000010
+00100100000000000100100
+00011000000000000011000
+00011000000000000011000
+00100100000000000100100
+01000010000000001000010
+01000001000000010000010
+01000000100000100000010
+10000000010001000000001
+10000000001010000000001
+10000000000100000000001
+10000000001010000000001
+10000000010001000000001
+01000000100000100000010
+01000001000000010000010
+01000010000000001000010
+00100100000000000100100
+00011000000000000011000
+00011000000000000011000
+00100100000000000100100
+01000011100000111000010
+10000000011111000000001
+
+1000000000111110000000001
+0100000111000001110000010
+0010011000000000001100100
+0001100000000000000011000
+0001100000000000000011000
+0010010000000000000100100
+0010001000000000001000100
+0100000100000000010000010
+0100000010000000100000010
+0100000001000001000000010
+1000000000100010000000001
+1000000000010100000000001
+1000000000001000000000001
+1000000000010100000000001
+1000000000100010000000001
+0100000001000001000000010
+0100000010000000100000010
+0100000100000000010000010
+0010001000000000001000100
+0010010000000000000100100
+0001100000000000000011000
+0001100000000000000011000
+0010011000000000001100100
+0100000111000001110000010
+1000000000111110000000001
+
+100000000001111100000000001
+010000001110000011100000010
+001000110000000000011000100
+000101000000000000000101000
+000010000000000000000010000
+000101000000000000000101000
+001000100000000000001000100
+001000010000000000010000100
+010000001000000000100000010
+010000000100000001000000010
+010000000010000010000000010
+100000000001000100000000001
+100000000000101000000000001
+100000000000010000000000001
+100000000000101000000000001
+100000000001000100000000001
+010000000010000010000000010
+010000000100000001000000010
+010000001000000000100000010
+001000010000000000010000100
+001000100000000000001000100
+000101000000000000000101000
+000010000000000000000010000
+000101000000000000000101000
+001000110000000000011000100
+010000001110000011100000010
+100000000001111100000000001
+
+10000000000011111000000000001
+01000000011100000111100000010
+00100001100000000000010000100
+00010010000000000000001101000
+00001100000000000000000010000
+00001100000000000000000101000
+00010010000000000000001001000
+00100001000000000000010000100
+00100000100000000000100000010
+01000000010000000001000000010
+01000000001000000010000000010
+01000000000100000100000000010
+10000000000010001000000000001
+10000000000001010000000000001
+10000000000000100000000000001
+10000000000001010000000000001
+10000000000010001000000000001
+01000000000100000100000000010
+01000000001000000010000000010
+01000000010000000001000000010
+00100000100000000000100000010
+00100001000000000000010000100
+00010010000000000000001001000
+00001100000000000000000101000
+00001100000000000000000110000
+00010010000000000000001001000
+00100001100000000000110000100
+01000000011100000111000000010
+10000000000011111000000000001
+
+1000000000000111110000000000001
+0100000001111000001111000000010
+0010000010000000000000100000100
+0001001100000000000000011001000
+0000110000000000000000000110000
+0000110000000000000000000110000
+0001001000000000000000001001000
+0001000100000000000000010001000
+0010000010000000000000100000100
+0100000001000000000001000000010
+0100000000100000000010000000010
+0100000000010000000100000000010
+0100000000001000001000000000010
+1000000000000100010000000000001
+1000000000000010100000000000001
+1000000000000001000000000000001
+1000000000000010100000000000001
+1000000000000100010000000000001
+0100000000001000001000000000010
+0100000000010000000100000000010
+0100000000100000000010000000010
+0100000001000000000001000000010
+0010000010000000000000100000100
+0001000100000000000000010001000
+0001001000000000000000001001000
+0000110000000000000000000110000
+0000110000000000000000000110000
+0001001100000000000000011001000
+0010000010000000000000100000100
+0100000001111000001111000000010
+1000000000000111110000000000001
+
+10000000000001111110000000000001
+01000000001110000001110000000010
+00100000110000000000001100000100
+00010001000000000000000010001000
+00001110000000000000000001110000
+00001100000000000000000000110000
+00001010000000000000000001010000
+00010001000000000000000010001000
+00100000100000000000000100000100
+00100000010000000000001000000100
+01000000001000000000010000000010
+01000000000100000000100000000010
+01000000000010000001000000000010
+01000000000001000010000000000010
+10000000000000100100000000000001
+10000000000000011000000000000001
+10000000000000011000000000000001
+10000000000000100100000000000001
+01000000000001000010000000000010
+01000000000010000001000000000010
+01000000000100000000100000000010
+01000000001000000000010000000010
+00100000010000000000001000000100
+00100000100000000000000100000100
+00010001000000000000000010001000
+00001010000000000000000001010000
+00001100000000000000000000110000
+00001110000000000000000001110000
+00010001000000000000000010001000
+00100000110000000000001100000100
+01000000001110000001110000000010
+10000000000001111110000000000001
diff --git a/src/ViewerTools/Makefile.am b/src/ViewerTools/Makefile.am
new file mode 100755 (executable)
index 0000000..ec04f6c
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+lib_LTLIBRARIES = libViewerTools.la
+
+salomeinclude_HEADERS= \
+       ViewerTools.h \
+       ViewerTools_CubeAxesDlgBase.h \
+       ViewerTools_DialogBase.h \
+       ViewerTools_FontWidgetBase.h
+
+dist_libViewerTools_la_SOURCES= \
+       ViewerTools_CubeAxesDlgBase.cxx \
+       ViewerTools_DialogBase.cxx \
+       ViewerTools_FontWidgetBase.cxx
+
+MOC_FILES= \
+       ViewerTools_CubeAxesDlgBase_moc.cxx \
+       ViewerTools_DialogBase_moc.cxx \
+       ViewerTools_FontWidgetBase_moc.cxx
+
+nodist_libViewerTools_la_SOURCES= $(MOC_FILES)
+
+nodist_salomeres_DATA =        \
+       ViewerTools_msg_en.qm \
+       ViewerTools_msg_fr.qm
+
+libViewerTools_la_CPPFLAGS =   \
+       $(QT_INCLUDES)          \
+       -I$(srcdir)/../Qtx
+
+libViewerTools_la_LDFLAGS =    \
+       $(QT_MT_LIBS)
+
+libViewerTools_la_LIBADD = ../Qtx/libqtx.la
diff --git a/src/ViewerTools/ViewerTools.h b/src/ViewerTools/ViewerTools.h
new file mode 100644 (file)
index 0000000..64e9f26
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_H
+#define VIEWERTOOLS_H
+
+#ifdef WIN32
+#  if defined VIEWERTOOLS_EXPORTS || defined ViewerTools_EXPORTS
+#    define VIEWERTOOLS_EXPORT __declspec(dllexport)
+#  else
+#   define VIEWERTOOLS_EXPORT __declspec(dllimport)
+#  endif
+#else
+#  define VIEWERTOOLS_EXPORT
+#endif
+
+#if defined WIN32
+#pragma warning ( disable: 4251 )
+#pragma warning ( disable: 4786 )
+#endif
+
+#endif
diff --git a/src/ViewerTools/ViewerTools_CubeAxesDlgBase.cxx b/src/ViewerTools/ViewerTools_CubeAxesDlgBase.cxx
new file mode 100644 (file)
index 0000000..1cc2181
--- /dev/null
@@ -0,0 +1,322 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ViewerTools_CubeAxesDlgBase.h"
+
+#include "ViewerTools_FontWidgetBase.h"
+
+#include "QtxAction.h"
+#include "QtxIntSpinBox.h"
+
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QTabWidget>
+#include <QCheckBox>
+#include <QGroupBox>
+#include <QLineEdit>
+#include <QLabel>
+
+/*!
+ * Class       : ViewerTools_AxisWidgetBase
+ * Description : Axis tab widget of the "Graduated axis" dialog box
+*/
+
+/*!
+  Constructor
+*/
+ViewerTools_AxisWidgetBase::ViewerTools_AxisWidgetBase (QWidget* theParent)
+: QFrame(theParent)
+{
+}
+
+/*!
+  Destructor
+*/
+ViewerTools_AxisWidgetBase::~ViewerTools_AxisWidgetBase()
+{
+}
+
+/*!
+  Initialize controls
+*/
+void ViewerTools_AxisWidgetBase::initialize()
+{
+  QList< QLabel* > aLabels;
+
+  // "Name" grp
+
+  myNameGrp = new QGroupBox(ViewerTools_CubeAxesDlgBase::tr("AXIS_NAME"), this);
+  myNameGrp->setCheckable( true );
+
+  QVBoxLayout* aVBox = new QVBoxLayout;
+  
+  QHBoxLayout* aHBox = new QHBoxLayout;
+  aHBox->setSpacing(5);
+  QLabel* aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("NAME"));
+  aHBox->addWidget(aLabel);
+  myAxisName = new QLineEdit;
+  aHBox->addWidget(myAxisName);
+  aLabels.append(aLabel);
+  aVBox->addLayout(aHBox);
+
+  aHBox = new QHBoxLayout;
+  aHBox->setSpacing(5);
+  aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("FONT"));
+  aHBox->addWidget(aLabel);
+  myNameFont = createFontWidget(myNameGrp);
+  aHBox->addWidget(myNameFont);
+  aLabels.append(aLabel);
+  aVBox->addLayout(aHBox);
+
+  myNameGrp->setLayout(aVBox);
+
+  // "Labels" grp
+
+  myLabelsGrp = new QGroupBox(ViewerTools_CubeAxesDlgBase::tr("LABELS"), this);
+  myLabelsGrp->setCheckable( true );
+
+  aVBox = new QVBoxLayout;
+
+  aHBox = new QHBoxLayout;
+  aHBox->setSpacing(5);
+  aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("NUMBER"));
+  aHBox->addWidget(aLabel);
+  myLabelNumber = new QtxIntSpinBox(2,25,1,myLabelsGrp);
+  aHBox->addWidget(myLabelNumber);
+  aLabels.append(aLabel);
+  aVBox->addLayout(aHBox);
+
+  aHBox = new QHBoxLayout;
+  aHBox->setSpacing(5);
+  aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("OFFSET"));
+  aHBox->addWidget(aLabel);
+  myLabelOffset = new QtxIntSpinBox(0,100,1,myLabelsGrp);
+  aHBox->addWidget(myLabelOffset);
+  aLabels.append(aLabel);
+  aVBox->addLayout(aHBox);
+
+  aHBox = new QHBoxLayout;
+  aHBox->setSpacing(5);
+  aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("FONT"));
+  aHBox->addWidget(aLabel);
+  myLabelsFont = createFontWidget(myLabelsGrp);
+  aHBox->addWidget(myLabelsFont);
+  aLabels.append(aLabel);
+  aVBox->addLayout(aHBox);
+
+  myLabelsGrp->setLayout(aVBox);
+
+  // "Tick marks" grp
+
+  myTicksGrp = new QGroupBox(ViewerTools_CubeAxesDlgBase::tr("TICK_MARKS"), this);
+  myTicksGrp->setCheckable( true );
+
+  aVBox = new QVBoxLayout;
+
+  aHBox = new QHBoxLayout;
+  aHBox->setSpacing(5);
+  aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("LENGTH"));
+  aHBox->addWidget(aLabel);
+  myTickLength = new QtxIntSpinBox(0,100,1,myTicksGrp);
+  aHBox->addWidget(myTickLength);
+  aLabels.append(aLabel);
+  aVBox->addLayout(aHBox);
+
+  myTicksGrp->setLayout(aVBox);
+
+  // Layout
+
+  QVBoxLayout* aLay = new QVBoxLayout(this);
+  aLay->setMargin(5);
+  aLay->setSpacing(5);
+  aLay->addWidget(myNameGrp);
+  aLay->addWidget(myLabelsGrp);
+  aLay->addWidget(myTicksGrp);
+
+  // init
+  myNameGrp->setChecked( true );
+  myLabelsGrp->setChecked( true );
+  myTicksGrp->setChecked( true );
+
+  // Adjust label widths
+  QList< QLabel* >::iterator anIter;
+  int aMaxWidth = 0;
+  for (anIter = aLabels.begin(); anIter != aLabels.end(); anIter++)
+    aMaxWidth = qMax(aMaxWidth, (*anIter)->sizeHint().width());
+  for (anIter = aLabels.begin(); anIter != aLabels.end(); anIter++)
+    (*anIter)->setFixedWidth(aMaxWidth);
+}
+
+void ViewerTools_AxisWidgetBase::UseName(const bool toUse)
+{
+  myNameGrp->setChecked(toUse);
+}
+
+void ViewerTools_AxisWidgetBase::SetName(const QString& theName)
+{
+  myAxisName->setText(theName);
+}
+
+void ViewerTools_AxisWidgetBase::SetNameFont(const QColor& theColor,
+                                             const int theFont,
+                                             const bool theIsBold,
+                                             const bool theIsItalic,
+                                             const bool theIsShadow)
+{
+  myNameFont->SetData(theColor, theFont, theIsBold, theIsItalic, theIsShadow);
+}
+
+/*
+  Class       : ViewerTools_CubeAxesDlgBase
+  Description : Dialog for specifying cube axes properties
+*/
+
+/*!
+  Constructor
+*/
+ViewerTools_CubeAxesDlgBase::ViewerTools_CubeAxesDlgBase(QtxAction* theAction,
+                                                         QWidget* theParent,
+                                                         const char* theName):
+  ViewerTools_DialogBase(theAction,
+                         theParent,
+                         theName)
+{
+  setWindowTitle(tr("CAPTION"));
+}
+
+/*!
+  Initialize controls
+*/
+void ViewerTools_CubeAxesDlgBase::initialize()
+{
+  QVBoxLayout* aLay = new QVBoxLayout(this);
+  aLay->setMargin(5);
+  aLay->setSpacing(5);
+  aLay->addWidget(createMainFrame(this));
+  aLay->addWidget(createButtonFrame(this));
+}
+
+/*!
+  Create frame containing dialog's input fields
+*/
+QWidget* ViewerTools_CubeAxesDlgBase::createMainFrame(QWidget* theParent)
+{
+  QFrame* aFrame = new QFrame(theParent);
+
+  myTabWg = new QTabWidget(aFrame);
+
+  myAxes[ 0 ] = createAxisWidget(myTabWg);
+  myAxes[ 1 ] = createAxisWidget(myTabWg);
+  myAxes[ 2 ] = createAxisWidget(myTabWg);
+
+  myTabWg->addTab(myAxes[ 0 ], tr("X_AXIS"));
+  myTabWg->addTab(myAxes[ 1 ], tr("Y_AXIS"));
+  myTabWg->addTab(myAxes[ 2 ], tr("Z_AXIS"));
+
+  myIsVisible = new QCheckBox(tr("IS_VISIBLE"), aFrame);
+
+  QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+  aLay->setMargin(0);
+  aLay->setSpacing(5);
+  aLay->addWidget(myTabWg);
+  aLay->addWidget(myIsVisible);
+
+  return aFrame;
+}
+
+/*!
+  Create frame containing buttons
+*/
+QWidget* ViewerTools_CubeAxesDlgBase::createButtonFrame(QWidget* theParent)
+{
+  QFrame* aFrame = new QFrame(theParent);
+  aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
+
+  myOkBtn    = new QPushButton(tr("BUT_OK"), aFrame);
+  myApplyBtn = new QPushButton(tr("BUT_APPLY"), aFrame);
+  myCloseBtn = new QPushButton(tr("BUT_CLOSE"), aFrame);
+
+  QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+  QHBoxLayout* aLay = new QHBoxLayout(aFrame);
+  aLay->setMargin(5);
+  aLay->setSpacing(5);
+
+  aLay->addWidget(myOkBtn);
+  aLay->addWidget(myApplyBtn);
+  aLay->addItem(aSpacer);
+  aLay->addWidget(myCloseBtn);
+
+  connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
+  connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
+  connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
+
+  return aFrame;
+}
+
+/*!
+  Destructor
+*/
+ViewerTools_CubeAxesDlgBase::~ViewerTools_CubeAxesDlgBase()
+{
+}
+
+/*!
+  Update dialog fields, connect signals and slots, show dialog
+*/
+void ViewerTools_CubeAxesDlgBase::Update()
+{
+}
+
+/*!
+  Verify validity of entry data
+*/
+bool ViewerTools_CubeAxesDlgBase::isValid() const
+{
+  return true;
+}
+
+/*!
+  Verify validity of entry data
+*/
+bool ViewerTools_CubeAxesDlgBase::onApply()
+{
+  return true;
+}
+
+/*!
+  SLOT called when "Ok" button pressed.
+*/
+void ViewerTools_CubeAxesDlgBase::onOk()
+{
+  if (onApply())
+    onClose();
+}
+
+/*!
+  SLOT: called when "Close" button pressed. Close dialog
+*/
+void ViewerTools_CubeAxesDlgBase::onClose()
+{
+  reject();
+}
diff --git a/src/ViewerTools/ViewerTools_CubeAxesDlgBase.h b/src/ViewerTools/ViewerTools_CubeAxesDlgBase.h
new file mode 100644 (file)
index 0000000..25a6aa2
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_CUBEAXESDLGBASE_H
+#define VIEWERTOOLS_CUBEAXESDLGBASE_H
+
+#include "ViewerTools_DialogBase.h"
+
+#include <QFrame>
+
+class QWidget;
+class QPushButton;
+class QTabWidget;
+class QCheckBox;
+class QGroupBox;
+class QLineEdit;
+
+class QtxAction;
+class QtxIntSpinBox;
+
+class ViewerTools_FontWidgetBase;
+
+/*!
+ * Class       : ViewerTools_AxisWidgetBase
+ * Description : Axis tab widget of the "Graduated axis" dialog box
+*/
+class VIEWERTOOLS_EXPORT ViewerTools_AxisWidgetBase : public QFrame
+{
+public:
+  ViewerTools_AxisWidgetBase( QWidget* );
+  ~ViewerTools_AxisWidgetBase();
+
+  void             UseName( const bool );
+  void             SetName( const QString& );
+  void             SetNameFont( const QColor&, const int, const bool, const bool, const bool );
+
+public:
+  virtual void     initialize();
+
+protected:
+  virtual ViewerTools_FontWidgetBase* createFontWidget( QWidget* ) = 0;
+
+protected:
+  // name
+  QGroupBox*       myNameGrp;
+  QLineEdit*       myAxisName;
+  ViewerTools_FontWidgetBase* myNameFont;
+
+  // labels
+  QGroupBox*       myLabelsGrp;
+  QtxIntSpinBox*   myLabelNumber;
+  QtxIntSpinBox*   myLabelOffset;
+  ViewerTools_FontWidgetBase* myLabelsFont;
+
+  // tick marks
+  QGroupBox*       myTicksGrp;
+  QtxIntSpinBox*   myTickLength;
+};
+
+/*!
+ * Class       : ViewerTools_CubeAxesDlgBase
+ * Description : Dialog for specifying cube axes properties
+ */
+class VIEWERTOOLS_EXPORT ViewerTools_CubeAxesDlgBase : public ViewerTools_DialogBase
+{
+  Q_OBJECT
+
+public:
+                  ViewerTools_CubeAxesDlgBase(QtxAction* theAction,
+                                              QWidget* theParent,
+                                              const char* theName);
+  virtual         ~ViewerTools_CubeAxesDlgBase();
+
+  virtual void    initialize();
+
+  virtual void    Update();
+
+protected slots:
+  virtual void    onOk();
+  virtual bool    onApply();
+  virtual void    onClose();
+
+protected:
+  virtual QWidget* createButtonFrame( QWidget* );
+  virtual QWidget* createMainFrame  ( QWidget* );
+  virtual bool    isValid() const;
+
+  virtual ViewerTools_AxisWidgetBase* createAxisWidget( QWidget* ) = 0;
+
+protected:
+  QTabWidget*     myTabWg;
+  QCheckBox*      myIsVisible;
+
+  QPushButton*    myOkBtn;
+  QPushButton*    myApplyBtn;
+  QPushButton*    myCloseBtn;
+  ViewerTools_AxisWidgetBase* myAxes[ 3 ];
+};
+
+#endif
diff --git a/src/ViewerTools/ViewerTools_DialogBase.cxx b/src/ViewerTools/ViewerTools_DialogBase.cxx
new file mode 100644 (file)
index 0000000..31b0fdc
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ViewerTools_DialogBase.h"
+
+#include "QtxAction.h"
+
+/*!
+  Constructor
+*/
+ViewerTools_DialogBase
+::ViewerTools_DialogBase(QtxAction* theAction,
+                         QWidget* theParent,
+                         const char* theName, 
+                         bool theModal, 
+                         Qt::WindowFlags theWFalgs):
+  QDialog(theParent, 
+          theWFalgs | Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
+  myAction(theAction)
+{
+  setObjectName(theName);
+  setModal(theModal);
+
+  connect(theParent, SIGNAL(Show( QShowEvent * )), this, SLOT(onParentShow()));
+  connect(theParent, SIGNAL(Hide( QHideEvent * )), this, SLOT(onParentHide()));
+}
+
+/*
+ *  Destroys the object and frees any allocated resources
+ */
+ViewerTools_DialogBase
+::~ViewerTools_DialogBase()
+{
+  // no need to delete child widgets, Qt does it all for us
+}
+
+void 
+ViewerTools_DialogBase
+::onParentShow()
+{
+  if(myAction->isChecked())
+    show();
+  else
+    hide();
+}
+
+void 
+ViewerTools_DialogBase
+::onParentHide()
+{
+  hide();
+}
+
+void 
+ViewerTools_DialogBase
+::done( int r )
+{
+  myAction->setChecked( false );
+  QDialog::done( r );
+}
diff --git a/src/ViewerTools/ViewerTools_DialogBase.h b/src/ViewerTools/ViewerTools_DialogBase.h
new file mode 100644 (file)
index 0000000..7f9a775
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_DIALOGBASE_H
+#define VIEWERTOOLS_DIALOGBASE_H
+
+#include "ViewerTools.h"
+
+#include <QDialog>
+
+class QtxAction;
+
+class VIEWERTOOLS_EXPORT ViewerTools_DialogBase : public QDialog
+{
+  Q_OBJECT;
+
+public:
+  ViewerTools_DialogBase(QtxAction* theAction,
+                         QWidget* theParent,
+                         const char* theName = "", 
+                         bool theModal = FALSE, 
+                         Qt::WindowFlags theWFalgs = 0);
+
+  ~ViewerTools_DialogBase();
+
+protected slots:
+  void onParentShow();
+  void onParentHide();
+  virtual void done( int );
+
+protected:
+  QtxAction* myAction;
+};
+
+#endif // VIEWERTOOLS_DIALOGBASE_H
diff --git a/src/ViewerTools/ViewerTools_FontWidgetBase.cxx b/src/ViewerTools/ViewerTools_FontWidgetBase.cxx
new file mode 100644 (file)
index 0000000..f78c137
--- /dev/null
@@ -0,0 +1,128 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ViewerTools_FontWidgetBase.h"
+
+#include <QToolButton>
+#include <QComboBox>
+#include <QColorDialog>
+#include <QCheckBox>
+#include <QHBoxLayout>
+
+/*!
+ * Class       : ViewerTools_FontWidgetBase
+ * Description : Dialog for specifynig font
+ */
+
+/*!
+  Constructor
+*/
+ViewerTools_FontWidgetBase::ViewerTools_FontWidgetBase( QWidget* theParent )
+: QWidget( theParent )
+{
+}
+
+/*!
+  Destructor
+*/
+ViewerTools_FontWidgetBase::~ViewerTools_FontWidgetBase()
+{
+}
+
+void ViewerTools_FontWidgetBase::Initialize()
+{
+  myColorBtn = new QToolButton( this );
+  myColorBtn->setMinimumWidth( 20 );
+
+  myFamily = new QComboBox( this );
+  InitializeFamilies();
+
+  myBold = new QCheckBox( tr( "BOLD" ), this );
+  myItalic = new QCheckBox( tr( "ITALIC" ), this );
+  myShadow = new QCheckBox( tr( "SHADOW" ), this );
+
+  QHBoxLayout* aHBLayout = new QHBoxLayout;
+  aHBLayout->setMargin( 0 );
+  aHBLayout->setSpacing( 5 );
+  aHBLayout->addWidget(myColorBtn);
+  aHBLayout->addWidget(myFamily);
+  aHBLayout->addWidget(myBold);
+  aHBLayout->addWidget(myItalic);
+  aHBLayout->addWidget(myShadow);
+  aHBLayout->addStretch();
+  this->setLayout(aHBLayout);
+
+  connect( myColorBtn, SIGNAL( clicked() ), SLOT( onColor() ) );
+
+  if( myFamily->count() == 0 )
+  {
+    myFamily->hide();
+    myBold->hide();
+    myItalic->hide();
+    myShadow->hide();
+  }
+}
+
+void ViewerTools_FontWidgetBase::SetColor( const QColor& theColor )
+{
+  QPalette palette;
+  palette.setColor(myColorBtn->backgroundRole(), theColor);
+  myColorBtn->setPalette(palette);
+}
+
+QColor ViewerTools_FontWidgetBase::GetColor() const
+{
+  return myColorBtn->palette().color( myColorBtn->backgroundRole() );
+}
+
+void ViewerTools_FontWidgetBase::onColor()
+{
+  QColor aColor = QColorDialog::getColor( GetColor(), this );
+  if ( aColor.isValid() )
+    SetColor( aColor );
+}
+
+void ViewerTools_FontWidgetBase::SetData( const QColor& theColor,
+                                          const int theFamily,
+                                          const bool theBold,
+                                          const bool theItalic,
+                                          const bool theShadow )
+{
+  SetColor( theColor );
+
+  myBold->setChecked( theBold );
+  myItalic->setChecked( theItalic );
+  myShadow->setChecked( theShadow );
+}
+
+void ViewerTools_FontWidgetBase::GetData( QColor& theColor,
+                                          int& theFamily,
+                                          bool& theBold,
+                                          bool& theItalic,
+                                          bool& theShadow ) const
+{
+  theColor = GetColor();
+
+  theBold = myBold->isChecked();
+  theItalic = myItalic->isChecked();
+  theShadow = myShadow->isChecked();
+}
diff --git a/src/ViewerTools/ViewerTools_FontWidgetBase.h b/src/ViewerTools/ViewerTools_FontWidgetBase.h
new file mode 100644 (file)
index 0000000..ae4ef37
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_FONTWIDGETBASE_H
+#define VIEWERTOOLS_FONTWIDGETBASE_H
+
+#include "ViewerTools.h"
+
+#include <QWidget>
+
+class QToolButton;
+class QComboBox;
+class QCheckBox;
+class QColor;
+
+/*!
+ * Class       : ViewerTools_FontWidgetBase
+ * Description : Dialog for specifying font
+ */
+class VIEWERTOOLS_EXPORT ViewerTools_FontWidgetBase : public QWidget
+{
+  Q_OBJECT
+
+public:
+                ViewerTools_FontWidgetBase( QWidget* );
+  virtual       ~ViewerTools_FontWidgetBase();
+
+  void          SetColor( const QColor& );
+  QColor        GetColor() const;
+
+  virtual void  SetData( const QColor&, const int, const bool, const bool, const bool );
+
+  virtual void  GetData( QColor&, int&, bool&, bool&, bool& ) const;
+
+public:
+  virtual void  Initialize();
+
+protected:
+  virtual void  InitializeFamilies() = 0;
+
+protected slots:
+  void          onColor();
+
+protected:
+  QToolButton*  myColorBtn;
+  QComboBox*    myFamily;
+  QCheckBox*    myBold;
+  QCheckBox*    myItalic;
+  QCheckBox*    myShadow;
+};
+
+#endif
diff --git a/src/ViewerTools/resources/ViewerTools_msg_en.ts b/src/ViewerTools/resources/ViewerTools_msg_en.ts
new file mode 100644 (file)
index 0000000..bfb45c8
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="en_US">
+<context>
+    <name>ViewerTools_CubeAxesDlgBase</name>
+    <message>
+        <source>X_AXIS</source>
+        <translation>X axis</translation>
+    </message>
+    <message>
+        <source>Y_AXIS</source>
+        <translation>Y axis</translation>
+    </message>
+    <message>
+        <source>Z_AXIS</source>
+        <translation>Z axis</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Graduated axes</translation>
+    </message>
+    <message>
+        <source>IS_VISIBLE</source>
+        <translation>Is visible</translation>
+    </message>
+    <message>
+        <source>FONT</source>
+        <translation>Font</translation>
+    </message>
+    <message>
+        <source>NAME</source>
+        <translation>Name</translation>
+    </message>
+    <message>
+        <source>TICK_MARKS</source>
+        <translation>Tick marks</translation>
+    </message>
+    <message>
+        <source>LABELS</source>
+        <translation>Labels</translation>
+    </message>
+    <message>
+        <source>LENGTH</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>NUMBER</source>
+        <translation>Number</translation>
+    </message>
+    <message>
+        <source>OFFSET</source>
+        <translation>Offset</translation>
+    </message>
+    <message>
+        <source>AXIS_NAME</source>
+        <translation>Axis name</translation>
+    </message>
+</context>
+<context>
+    <name>ViewerTools_FontWidgetBase</name>
+    <message>
+        <source>BOLD</source>
+        <translation>Bold</translation>
+    </message>
+    <message>
+        <source>ITALIC</source>
+        <translation>Italic</translation>
+    </message>
+    <message>
+        <source>SHADOW</source>
+        <translation>Shadow</translation>
+    </message>
+</context>
+</TS>
diff --git a/src/ViewerTools/resources/ViewerTools_msg_fr.ts b/src/ViewerTools/resources/ViewerTools_msg_fr.ts
new file mode 100755 (executable)
index 0000000..1fb1f71
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+    <name>ViewerTools_CubeAxesDlgBase</name>
+    <message>
+        <source>X_AXIS</source>
+        <translation>Axe X</translation>
+    </message>
+    <message>
+        <source>Y_AXIS</source>
+        <translation>Axe Y</translation>
+    </message>
+    <message>
+        <source>Z_AXIS</source>
+        <translation>Axe Z</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Axes gradués</translation>
+    </message>
+    <message>
+        <source>IS_VISIBLE</source>
+        <translation>Visible</translation>
+    </message>
+    <message>
+        <source>FONT</source>
+        <translation>Couleur</translation>
+    </message>
+    <message>
+        <source>NAME</source>
+        <translation>Nom</translation>
+    </message>
+    <message>
+        <source>TICK_MARKS</source>
+        <translation>Marques de graduation</translation>
+    </message>
+    <message>
+        <source>LABELS</source>
+        <translation>Etiquettes</translation>
+    </message>
+    <message>
+        <source>LENGTH</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>NUMBER</source>
+        <translation>Nombre</translation>
+    </message>
+    <message>
+        <source>OFFSET</source>
+        <translation>Décalage</translation>
+    </message>
+    <message>
+        <source>AXIS_NAME</source>
+        <translation>Nom de l&apos;axe </translation>
+    </message>
+</context>
+<context>
+    <name>ViewerTools_FontWidgetBase</name>
+    <message>
+        <source>BOLD</source>
+        <translation>Gras</translation>
+    </message>
+    <message>
+        <source>ITALIC</source>
+        <translation>Italique</translation>
+    </message>
+    <message>
+        <source>SHADOW</source>
+        <translation>Ombré</translation>
+    </message>
+</context>
+</TS>
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644 (file)
index 0000000..96794db
--- /dev/null
@@ -0,0 +1,23 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+SUBDIRS = vtkEDFOverloads dlgfactory
diff --git a/tools/dlgfactory/GenericDialog.cxx b/tools/dlgfactory/GenericDialog.cxx
new file mode 100644 (file)
index 0000000..9b84566
--- /dev/null
@@ -0,0 +1,29 @@
+#include "GenericDialog.hxx"
+
+GenericDialog::GenericDialog(QDialog *parent) : QDialog(parent)
+{
+  ui.setupUi(this); // A faire en premier
+  
+  /*
+    Personnalisez vos widgets ici si nécessaire
+    Réalisez des connexions supplémentaires entre signaux et slots
+  */
+  
+  // The slots accept() and reject() are already connected to the
+  // buttonbox (inherited features) 
+}
+
+QFrame * GenericDialog::getPanel() {
+  return ui.centralPanel;
+}
+
+QDialogButtonBox * GenericDialog::getButtonBox() {
+  return ui.buttonBox;
+}
+
+
+#include <QDebug>
+void GenericDialog::accept() {
+  qDebug() << "accept() is not implemented yet";
+  QDialog::accept();
+}
diff --git a/tools/dlgfactory/GenericDialog.hxx b/tools/dlgfactory/GenericDialog.hxx
new file mode 100644 (file)
index 0000000..ee94661
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _GenericDialog_HXX
+#define _GenericDialog_HXX
+
+#include <QtGui>
+#include "ui_GenericDialog.hxx"
+
+class GenericDialog : public QDialog
+{
+  Q_OBJECT
+    
+public:
+  GenericDialog(QDialog *parent = 0);
+
+ protected:
+  QFrame * getPanel();
+  QDialogButtonBox * getButtonBox();
+  
+ protected slots:    
+    void accept();
+  //void reject();
+  
+ private:
+  Ui_GenericDialog ui; // instance of the class defined in ui_GenericDialog.h
+};
+
+
+#endif // _GenericDialog_HXX
diff --git a/tools/dlgfactory/GenericDialog.ui b/tools/dlgfactory/GenericDialog.ui
new file mode 100644 (file)
index 0000000..1fe7ae9
--- /dev/null
@@ -0,0 +1,89 @@
+<ui version="4.0" >
+ <class>GenericDialog</class>
+ <widget class="QDialog" name="GenericDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <layout class="QHBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <layout class="QVBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <widget class="QFrame" name="centralPanel" >
+       <property name="frameShape" >
+        <enum>QFrame::StyledPanel</enum>
+       </property>
+       <property name="frameShadow" >
+        <enum>QFrame::Raised</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox" >
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons" >
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>GenericDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>GenericDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/tools/dlgfactory/Makefile.am b/tools/dlgfactory/Makefile.am
new file mode 100644 (file)
index 0000000..c83870f
--- /dev/null
@@ -0,0 +1,105 @@
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF/R&D) 
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# moc-files generation (using MOC)
+%_moc.cxx: %.hxx
+       $(MOC) $< -o $@
+
+# Qt form files generation (using UIC)
+ui_%.hxx: %.ui
+       $(UIC) -o $@ $<
+
+# Program targets
+bin_PROGRAMS = qtester gtester
+
+# QDialog uic files
+UIC_FILES_QDIALOG = \
+       ui_QDialogTest.hxx
+
+# QDialog moc files
+MOC_FILES_QDIALOG = \
+       QDialogTest_moc.cxx
+
+# GDialog uic files
+UIC_FILES_GDIALOG= \
+       ui_GenericDialog.hxx \
+       ui_GDialogTest.hxx
+
+# GDialog moc files
+MOC_FILES_GDIALOG= \
+       GenericDialog_moc.cxx \
+       GDialogTest_moc.cxx
+
+QDIALOG_TEMPLATES = __QDIALOG__.ui __QDIALOG__.hxx __QDIALOG__.cxx
+GDIALOG_TEMPLATES = __GDIALOG__.ui __GDIALOG__.hxx __GDIALOG__.cxx
+
+# generated sources
+BUILT_SOURCES = $(UIC_FILES_QDIALOG) $(UIC_FILES_GDIALOG)
+
+# extra distributed files
+EXTRA_DIST += $(QDIALOG_TEMPLATES) $(GDIALOG_TEMPLATES) GenericDialog.ui README.txt dlgfactory.py
+
+mostlyclean-local:
+       rm @builddir@/QDialogTest*
+       rm @builddir@/GDialogTest*
+       rm -f @builddir@/*_moc.cxx @builddir@/ui_*.hxx
+
+QDialogTest.hxx QDialogTest.cxx QDialogTest.ui: $(QDIALOG_TEMPLATES) dlgfactory.py
+       $(srcdir)/dlgfactory.py -s -n QDialogTest -t qdialog
+
+GDialogTest.hxx GDialogTest.cxx GDialogTest.ui : $(GDIALOG_TEMPLATES) dlgfactory.py
+       $(srcdir)/dlgfactory.py -s -n GDialogTest -t gdialog
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+QT_LIBS=@QT_LIBS@
+
+# QDialog tester
+qtester_SOURCES = \
+        qtester.cxx
+nodist_qtester_SOURCES =  \
+       QDialogTest.cxx \
+       $(MOC_FILES_QDIALOG) \
+       $(UIC_FILES_QDIALOG)
+
+qtester_CPPFLAGS = \
+       $(QT_CXXFLAGS) \
+       -I.
+
+qtester_LDFLAGS = \
+        $(QT_LIBS)
+
+gtester_SOURCES = \
+       gtester.cxx \
+       GenericDialog.hxx \
+       GenericDialog.cxx
+nodist_gtester_SOURCES = \
+       GDialogTest.cxx \
+       $(MOC_FILES_GDIALOG) \
+       $(UIC_FILES_GDIALOG)
+
+gtester_CPPFLAGS = \
+       $(QT_CXXFLAGS) \
+       -I@srcdir@ \
+       -I.
+
+gtester_LDFLAGS = \
+        $(QT_LIBS)
diff --git a/tools/dlgfactory/README.txt b/tools/dlgfactory/README.txt
new file mode 100644 (file)
index 0000000..ec1c005
--- /dev/null
@@ -0,0 +1,12 @@
+This package provides a simple tool to generates the bootstrap files
+of a standard Qt dialog. Nothing original neither very smart, but just
+help to initiate all this stuff the good way.
+
+See the header of the script dlgfactory.py for details.
+
+Some use cases (basic unit test) are given in the files qtester.cxx
+and gtester.cxx. The build procedure (when you type make) create test
+classes called QDialogTest and GDialogTest and used respectively in
+qtester and gtester.
+
+(gboulant - 26 oct. 2011)
diff --git a/tools/dlgfactory/__GDIALOG__.cxx b/tools/dlgfactory/__GDIALOG__.cxx
new file mode 100644 (file)
index 0000000..705c721
--- /dev/null
@@ -0,0 +1,6 @@
+#include "__CLASSNAME__.hxx"
+
+__CLASSNAME__::__CLASSNAME__(QDialog *parent) : GenericDialog(parent)
+{
+  ui.setupUi(this->getPanel());
+}
diff --git a/tools/dlgfactory/__GDIALOG__.hxx b/tools/dlgfactory/__GDIALOG__.hxx
new file mode 100644 (file)
index 0000000..ab805a1
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef ___CLASSNAME___HXX
+#define ___CLASSNAME___HXX
+
+#include <QtGui>
+#include "ui___CLASSNAME__.hxx"
+#include "GenericDialog.hxx"
+
+class __CLASSNAME__ : public GenericDialog
+{
+  Q_OBJECT
+    
+ public:
+  __CLASSNAME__(QDialog *parent = 0);
+  
+ private:
+  Ui___CLASSNAME__ ui; // instance of the class defined in ui___CLASSNAME__.hxx
+};
+
+
+#endif // ___CLASSNAME___HXX
diff --git a/tools/dlgfactory/__GDIALOG__.ui b/tools/dlgfactory/__GDIALOG__.ui
new file mode 100644 (file)
index 0000000..7f5c27d
--- /dev/null
@@ -0,0 +1,99 @@
+<ui version="4.0" >
+ <class>__CLASSNAME__</class>
+ <widget class="QWidget" name="__CLASSNAME__" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>340</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <layout class="QVBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <layout class="QHBoxLayout" >
+       <property name="margin" >
+        <number>0</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item>
+        <layout class="QVBoxLayout" >
+         <property name="margin" >
+          <number>0</number>
+         </property>
+         <property name="spacing" >
+          <number>6</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="label" >
+           <property name="text" >
+            <string>Pression :</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_2" >
+           <property name="text" >
+            <string>Température :</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QVBoxLayout" >
+         <property name="margin" >
+          <number>0</number>
+         </property>
+         <property name="spacing" >
+          <number>6</number>
+         </property>
+         <item>
+          <widget class="QLineEdit" name="lineEdit" />
+         </item>
+         <item>
+          <widget class="QLineEdit" name="lineEdit_2" />
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>20</width>
+         <height>121</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/dlgfactory/__QDIALOG__.cxx b/tools/dlgfactory/__QDIALOG__.cxx
new file mode 100644 (file)
index 0000000..32134c3
--- /dev/null
@@ -0,0 +1,20 @@
+#include "__CLASSNAME__.hxx"
+
+__CLASSNAME__::__CLASSNAME__(QDialog *parent) : QDialog(parent)
+{
+  ui.setupUi(this); // A faire en premier
+  
+  /*
+    Personnalisez vos widgets ici si nécessaire
+    Réalisez des connexions supplémentaires entre signaux et slots
+  */
+  
+  // The slots accept() and reject() are already connected to the
+  // buttonbox (inherited features) 
+}
+
+#include <QDebug>
+void __CLASSNAME__::accept() {
+  qDebug() << "accept() is not implemented yet";
+  QDialog::accept();
+}
diff --git a/tools/dlgfactory/__QDIALOG__.hxx b/tools/dlgfactory/__QDIALOG__.hxx
new file mode 100644 (file)
index 0000000..3865e17
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef ___CLASSNAME___HXX
+#define ___CLASSNAME___HXX
+
+#include <QtGui>
+#include "ui___CLASSNAME__.hxx"
+
+class __CLASSNAME__ : public QDialog
+{
+  Q_OBJECT
+    
+ public:
+  __CLASSNAME__(QDialog *parent = 0);
+
+ protected slots:    
+    void accept();
+  //void reject();
+  
+ private:
+  Ui___CLASSNAME__ ui; // instance of the class defined in ui___CLASSNAME__.hxx
+};
+
+
+#endif // ___CLASSNAME___HXX
diff --git a/tools/dlgfactory/__QDIALOG__.ui b/tools/dlgfactory/__QDIALOG__.ui
new file mode 100644 (file)
index 0000000..88cf24d
--- /dev/null
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>__CLASSNAME__</class>
+ <widget class="QDialog" name="__CLASSNAME__" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <widget class="QDialogButtonBox" name="buttonBox" >
+   <property name="geometry" >
+    <rect>
+     <x>30</x>
+     <y>240</y>
+     <width>341</width>
+     <height>32</height>
+    </rect>
+   </property>
+   <property name="orientation" >
+    <enum>Qt::Horizontal</enum>
+   </property>
+   <property name="standardButtons" >
+    <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>__CLASSNAME__</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>__CLASSNAME__</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/tools/dlgfactory/dlgfactory.py b/tools/dlgfactory/dlgfactory.py
new file mode 100755 (executable)
index 0000000..5eca0ee
--- /dev/null
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import sys, os
+
+__descr_str = ""
+__descr_str += "This script generates a set of files to initiate a dialog Qt window "
+__descr_str += "(i.e. MyDialog.ui, MyDialog.hxx and MyDialog.cxx files). "
+__descr_str += "The dialog window can be a self-consistent class (i.e. depends only "
+__descr_str += "on Qt classes) or a class that inherits class GenericDialog "
+__descr_str += "which implementation is provided in this package and "
+__descr_str += "which design is defined by the GenericDialog.ui file (editable using "
+__descr_str += "the Qt designer). "
+__descr_str += "The -t option let you choose between the two possibilities (specify "
+__descr_str += "\"-t qdialog\" for the first case, \"-t gdialog\" otherwise)."
+
+__msg_str = """
+#
+# ---------------------------------------------------------
+# Generation rules to create moc files from QObject headers
+# and form source files from ui files
+# ---------------------------------------------------------
+
+%_moc.cxx: %.hxx
+       $(MOC) $< -o $@
+
+ui_%.hxx: %.ui
+       $(UIC) -o $@ $<
+
+
+# ---------------------------------------------------------
+# Declaration of form files generated by UIC and MOC files
+# as BUILT_SOURCES to be used in the building process.
+# ---------------------------------------------------------
+#
+UIC_FILES = \
+       ui___CLASSNAME__.hxx
+#
+MOC_FILES = \
+       __CLASSNAME___moc.cxx
+
+BUILT_SOURCES = $(UIC_FILES)
+
+#
+# ---------------------------------------------------------
+# Declaration of sources files to the building process
+# ---------------------------------------------------------
+# MOC files and UIC files should be added to the list of undistributed
+# source files with something like (where <MyLibrary> should be
+# replaced by the name of the product declared by the directive
+# lib_LTLIBRARIES):
+#
+nodist_<MyLibrary>_la_SOURCES += $(MOC_FILES) $(UIC_FILES)
+
+dist_<MyLibrary>_la_SOURCES += __CLASSNAME__.cxx
+salomeinclude_HEADERS       += __CLASSNAME__.hxx
+
+<MyLibrary>_la_CPPFLAGS = \\
+       $(QT_CXXFLAGS)
+
+<MyLibrary>_la_LDFLAGS = \\
+        $(QT_LIBS)
+""" 
+
+if __name__ == "__main__":
+  from optparse import OptionParser
+  import shutil, fileinput
+
+  tool_path = os.path.dirname( os.path.abspath( sys.argv[0] ) )
+
+  parser = OptionParser( description = __descr_str )
+  parser.add_option( "-n", action="store", default="TestDialog", dest="className", metavar="className",
+                     help="specify the name of the class (default is TestDialog)" )
+  parser.add_option( "-t", action="store", default="qdialog", dest="classType",
+                     choices=["qdialog", "gdialog"], metavar="classType",
+                     help="specify the type of the class (default is qdialog)" )
+  parser.add_option( "-v", "--verbose", action="store_true", default=True, dest="verbose",
+                     help="verbose mode" )
+  parser.add_option( "-s", "--silent", action="store_false", dest="verbose",
+                     help="silent mode" )
+
+  (options, args) = parser.parse_args()
+  className = options.className
+  classType = options.classType
+
+  for ext in [".cxx", ".hxx", ".ui"]:
+    file_dest = className + ext 
+    if classType == "qdialog":
+      file_src = os.path.join( tool_path, "__QDIALOG__" + ext )
+      pass
+    else:
+      file_src = os.path.join( tool_path, "__GDIALOG__" + ext )
+      pass
+    shutil.copyfile( file_src, file_dest )
+    finput = fileinput.FileInput( file_dest, inplace=1 )
+    for line in finput:
+      line = line[:-1] 
+      line = line.replace( "__CLASSNAME__", className )
+      print line
+      pass
+
+    if options.verbose:
+      print "Note that the following directives should be present in your Makefile.am (or something like that): \n"
+      print __msg_str.replace( "__CLASSNAME__", className )
+      pass
+  pass
+
diff --git a/tools/dlgfactory/dlgfactory.sh b/tools/dlgfactory/dlgfactory.sh
new file mode 100755 (executable)
index 0000000..0f127d5
--- /dev/null
@@ -0,0 +1,155 @@
+#!/bin/sh
+# Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+#
+# ==================================================================
+#_debut_usage
+#
+# USAGE:
+#
+#      dlgfactory.sh -n className [-t classType]
+#
+#
+# DESCRIPTION:
+#
+# This script generates a set of files to initiate a dialog qt window
+# (i.e. MyDialog.ui, MyDialog.hxx and MyDialog.cxx files).
+#
+# The dialog window can be a self-consistent class (i.e. depends only
+# on Qt classes) or a classe that inherits from the class
+# GenericDialog whose implementation is provided in this package and
+# whose design is defined by the GenericDialog.ui file (editable using
+# the qt designer).
+#
+# The -t option let you choose between the two possibilities (specify
+# "-t qdialog" for the first case, "-t gdialog" otherwise).
+#
+# OPTION:
+#          -n : specify the name of the class (default is TestDialog)
+#
+#          -t : specify the type of the class (default is qdialog)
+#
+#_fin_usage
+# ==================================================================
+#
+
+thisScript=$(which $0)
+TOOLDIRNAME=$(dirname $0)
+
+displayUsage()
+{
+  cat $thisScript | sed -e '/^#_debut_usage/,/^#_fin_usage/!d' \
+   -e '/^#_debut_usage/d' \
+   -e '/^#_fin_usage/d' \
+   -e 's/^#//g'
+}
+
+#
+# Read the options on the command line
+#
+className=TestDialog
+classType=dialog
+if [ $# -eq 0 ]; then
+    displayUsage
+    exit 1
+else
+    while [ $# -ne 0 ]; do
+        case $1 in
+            -n)
+                shift; className=$1; shift ;;
+            -t)
+                shift; classType=$1; shift ;;
+            *)
+                displayUsage;;
+        esac
+    done
+fi
+
+if [ "$classType" = "qdialog" ]; then
+    sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__QDIALOG__.ui > $className.ui
+    sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__QDIALOG__.hxx > $className.hxx
+    sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__QDIALOG__.cxx > $className.cxx
+else
+    sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__GDIALOG__.ui > $className.ui
+    sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__GDIALOG__.hxx > $className.hxx
+    sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__GDIALOG__.cxx > $className.cxx    
+fi
+
+displayMessage()
+{
+  cat $thisScript | sed -e '/^#_debut_message/,/^#_fin_message/!d' \
+   -e '/^#_debut_message/d' \
+   -e '/^#_fin_message/d' \
+   -e 's/^#//g' \
+   -e "s/__CLASSNAME__/$className/g"
+}
+
+#_debut_message
+##
+## ---------------------------------------------------------
+## Generation rules to create moc files from QObject headers
+## and form source files from ui files
+## ---------------------------------------------------------
+##
+#%_moc.cxx: %.hxx
+#      $(MOC) $< -o $@
+#
+#ui_%.hxx: %.ui
+#      $(UIC) -o $@ $<
+#
+##
+## ---------------------------------------------------------
+## Declaration of form files generated by UIC and MOC files
+## as BUILT_SOURCES to be used in the building process.
+## ---------------------------------------------------------
+##
+#UIC_FILES = \
+#      ui___CLASSNAME__.hxx
+##
+#MOC_FILES = \
+#      __CLASSNAME___moc.cxx
+#
+#BUILT_SOURCES = $(UIC_FILES)
+#
+##
+## ---------------------------------------------------------
+## Declaration of sources files to the building process
+## ---------------------------------------------------------
+## MOC files and UIC files should be added to the list of undistributed
+## source files with something like (where <MyLibrary> should be
+## replaced by the name of the product declared by the directive
+## lib_LTLIBRARIES):
+##
+#nodist_<MyLibrary>_la_SOURCES += $(MOC_FILES) $(UIC_FILES)
+#
+#dist_<MyLibrary>_la_SOURCES += __CLASSNAME__.cxx
+#salomeinclude_HEADERS       += __CLASSNAME__.hxx
+#
+#<MyLibrary>_la_CPPFLAGS = \
+#      $(QT_CXXFLAGS)
+#
+#<MyLibrary>_la_LDFLAGS = \
+#        $(QT_LIBS)
+
+#_fin_message
+
+echo "Note that the following directives should be present in your Makefile.am (or something like that):"
+echo ""
+displayMessage
+
diff --git a/tools/dlgfactory/gtester.cxx b/tools/dlgfactory/gtester.cxx
new file mode 100644 (file)
index 0000000..0f636c2
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// This program can be used for unit test of dialog box.
+// You just have to include the interface file (*.h) and
+// use the dialog class as illustrated in the functions TEST_*.
+// (gboulant - 12/10/2010)
+//
+#include <QApplication>
+#include <QtGui>
+#include "GDialogTest.hxx"
+
+void TEST_show() {
+  GDialogTest * dialog = new GDialogTest();
+  dialog->show();
+}
+
+int main(int argc, char *argv[])
+{
+  QApplication app(argc, argv);
+  TEST_show();
+  return app.exec();   
+}
diff --git a/tools/dlgfactory/qtester.cxx b/tools/dlgfactory/qtester.cxx
new file mode 100644 (file)
index 0000000..eeb15e5
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// This program can be used for unit test of dialog box.
+// You just have to include the interface file (*.h) and
+// use the dialog class as illustrated in the functions TEST_*.
+// (gboulant - 12/10/2010)
+//
+#include <QApplication>
+#include <QtGui>
+#include "QDialogTest.hxx"
+
+void TEST_show() {
+  QDialogTest * dialog = new QDialogTest();
+  dialog->show();
+}
+
+int main(int argc, char *argv[])
+{
+  QApplication app(argc, argv);
+  TEST_show();
+  return app.exec();   
+}
diff --git a/tools/vtkEDFOverloads/Makefile.am b/tools/vtkEDFOverloads/Makefile.am
new file mode 100755 (executable)
index 0000000..8d7853f
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+libparaview_LTLIBRARIES = libvtkEDFOverloads.la        
+lib_LTLIBRARIES = libvtkTools.la
+
+salomeinclude_HEADERS = vtkEDFCutter.h \
+                       vtkEDFFactory.h \
+                       vtkEDFOverloadsDefines.h
+
+dist_libvtkEDFOverloads_la_SOURCES = vtkEDFFactory.cxx
+dist_libvtkTools_la_SOURCES = vtkEDFCutter.cxx
+
+libvtkEDFOverloads_la_CPPFLAGS = $(VTK_INCLUDES)
+libvtkTools_la_CPPFLAGS = $(VTK_INCLUDES)
+
+libvtkEDFOverloads_la_LDFLAGS = $(VTK_LIBS)
+libvtkEDFOverloads_la_LIBADD = libvtkTools.la
+libvtkTools_la_LDFLAGS = $(VTK_LIBS)
\ No newline at end of file
diff --git a/tools/vtkEDFOverloads/vtkEDFCutter.cxx b/tools/vtkEDFOverloads/vtkEDFCutter.cxx
new file mode 100755 (executable)
index 0000000..3de2a04
--- /dev/null
@@ -0,0 +1,526 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkEDFCutter.h"
+
+#include "vtkInformationVector.h"
+#include "vtkInformation.h"
+#include "vtkSmartPointer.h"
+#include "vtkGenericCell.h"
+#include "vtkPolyData.h"
+#include "vtkObjectFactory.h"
+#include "vtkIdTypeArray.h"
+#include "vtkCellData.h"
+#include "vtkCellArray.h"
+#include "vtkIdList.h"
+
+#include <list>
+#include <set>
+#include <map>
+#include <deque>
+
+class vtkEDFEdge
+{
+public :
+  vtkIdType v0;
+  vtkIdType v1;
+
+  vtkEDFEdge(vtkIdType a, vtkIdType b) : v0(a), v1(b){}
+  vtkEDFEdge(){}
+};
+
+bool operator == (const vtkEDFEdge& e0, const vtkEDFEdge& e1)
+{
+  return (e0.v0 == e1.v0 && e0.v1 == e1.v1) ||
+      (e0.v1 == e1.v0 && e0.v0 == e1.v1);
+}
+
+bool operator != (const vtkEDFEdge& e0, const vtkEDFEdge& e1)
+{
+  return !(e0==e1);
+}
+
+bool operator < (const vtkEDFEdge& e0, const vtkEDFEdge& e1)
+{
+  vtkEDFEdge the_e0;
+  vtkEDFEdge the_e1;
+  if(e0.v0 < e0.v1)
+    {
+    the_e0.v0 = e0.v0;
+    the_e0.v1 = e0.v1;
+    }
+  else
+    {
+    the_e0.v0 = e0.v1;
+    the_e0.v1 = e0.v0;
+    }
+  if(e1.v0 < e1.v1)
+    {
+    the_e1.v0 = e1.v0;
+    the_e1.v1 = e1.v1;
+    }
+  else
+    {
+    the_e1.v0 = e1.v1;
+    the_e1.v1 = e1.v0;
+    }
+
+  if(the_e0.v0 == the_e1.v0)
+    return (the_e0.v1 < the_e1.v1);
+
+  return the_e0.v0 < the_e1.v0;
+}
+
+vtkStandardNewMacro(vtkEDFCutter);
+vtkCxxRevisionMacro(vtkEDFCutter, "0.0");
+
+vtkEDFCutter::vtkEDFCutter()
+{
+  this->OriginalCellIdsName = NULL;
+}
+
+vtkEDFCutter::~vtkEDFCutter()
+{
+  this->SetOriginalCellIdsName(NULL);
+}
+
+int vtkEDFCutter::RequestData(vtkInformation * request,
+                        vtkInformationVector ** inVector,
+                        vtkInformationVector * outVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkDataSet *input = vtkDataSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkSmartPointer<vtkIdTypeArray> cellIdArray =
+      vtkSmartPointer<vtkIdTypeArray>::New();
+  cellIdArray->SetName(this->GetOriginalCellIdsName());
+  cellIdArray->SetNumberOfComponents(1);
+  cellIdArray->SetNumberOfTuples(input->GetNumberOfCells());
+  for(vtkIdType id=0; id < cellIdArray->GetNumberOfTuples(); id++)
+    {
+    cellIdArray->SetTuple1(id, id);
+    }
+  input->GetCellData()->AddArray(cellIdArray);
+
+  int ret = this->Superclass::RequestData(request, inVector, outVector);
+
+  if(ret == 0)
+    return 0;
+
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkSmartPointer<vtkPolyData> tmpOutput;
+  tmpOutput.TakeReference(output->NewInstance());
+
+  this->AssembleOutputTriangles(output, tmpOutput);
+
+  output->ShallowCopy(tmpOutput);
+
+  return ret;
+}
+
+
+void  vtkEDFCutter::AssembleOutputTriangles(vtkPolyData* inpd,
+                                            vtkPolyData* outpd)
+{
+  outpd->ShallowCopy(inpd);
+
+  vtkIdTypeArray* originalCellIds = vtkIdTypeArray::SafeDownCast(
+      inpd->GetCellData()->GetArray(this->GetOriginalCellIdsName()));
+
+  if(originalCellIds == NULL)
+    {
+    return;
+    }
+
+  outpd->GetCellData()->Initialize();
+  outpd->GetCellData()->CopyAllocate(inpd->GetCellData());
+
+  vtkSmartPointer<vtkCellArray> verts = vtkSmartPointer<vtkCellArray>::New();
+  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
+  vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
+  vtkSmartPointer<vtkCellArray> strips = vtkSmartPointer<vtkCellArray>::New();
+  outpd->SetVerts(verts);
+  outpd->SetLines(lines);
+  outpd->SetPolys(polys);
+  outpd->SetStrips(strips);
+
+  for(vtkIdType cellId=0; cellId<inpd->GetNumberOfCells(); cellId++)
+    {
+    unsigned char type = inpd->GetCellType(cellId);
+    if(type != VTK_TRIANGLE)
+      {
+      vtkIdType npts;
+      vtkIdType* pts = NULL;
+      inpd->GetCellPoints(cellId, npts, pts);
+      vtkIdType newCellId =
+          outpd->InsertNextCell(type, npts, pts);
+      outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+      }
+    else
+      {
+      vtkIdType cellIdEnd = cellId+1;
+      vtkIdType originalCellId = originalCellIds->GetValue(cellId);
+      while(cellIdEnd < inpd->GetNumberOfCells() &&
+            inpd->GetCellType(cellIdEnd) == VTK_TRIANGLE &&
+            originalCellIds->GetValue(cellIdEnd) == originalCellId)
+        {
+        cellIdEnd++;
+        }
+
+      // all triangles from cellId to cellIdEnd come from the same
+      // original cell.
+
+      // A batch is composed of triangles which are connected by the edges.
+      std::map<vtkIdType, std::set<vtkIdType> > connectedTriangles;
+      for(vtkIdType firstCell = cellId; firstCell < cellIdEnd-1; firstCell++)
+        {
+        vtkIdType npts;
+        vtkIdType* pts = NULL;
+        inpd->GetCellPoints(firstCell, npts, pts);
+        vtkEDFEdge fe0 = vtkEDFEdge(pts[0], pts[1]);
+        vtkEDFEdge fe1 = vtkEDFEdge(pts[1], pts[2]);
+        vtkEDFEdge fe2 = vtkEDFEdge(pts[2], pts[0]);
+        for(vtkIdType secondCell = firstCell+1; secondCell < cellIdEnd; secondCell++)
+          {
+          vtkIdType snpts;
+          vtkIdType* spts = NULL;
+          inpd->GetCellPoints(secondCell, snpts, spts);
+          vtkEDFEdge se0 = vtkEDFEdge(spts[0], spts[1]);
+          vtkEDFEdge se1 = vtkEDFEdge(spts[1], spts[2]);
+          vtkEDFEdge se2 = vtkEDFEdge(spts[2], spts[0]);
+
+          if(fe0 == se0 || fe0 == se1 || fe0 == se2 ||
+             fe1 == se0 || fe1 == se1 || fe1 == se2 ||
+             fe2 == se0 || fe2 == se1 || fe2 == se2)
+            {
+            connectedTriangles[firstCell].insert(secondCell);
+            connectedTriangles[secondCell].insert(firstCell);
+            }
+          }
+        }
+
+      std::set<vtkIdType> visitedCell;
+      for(vtkIdType id=cellId; id<cellIdEnd; id++)
+        {
+        if(visitedCell.find(id) != visitedCell.end())
+          continue;
+
+        // if this cell has not yet been visited, I create a batch of all
+        // cells connected to this one
+
+        visitedCell.insert(id);
+        std::set<vtkIdType> batch;
+        std::list<vtkIdType> cellList;
+        cellList.push_back(id);
+        while(cellList.size() > 0)
+          {
+          vtkIdType currentId = *(cellList.begin());
+          batch.insert(currentId);
+          cellList.pop_front();
+          if(connectedTriangles.find(currentId) != connectedTriangles.end())
+            {
+            const std::set<vtkIdType>& adj = connectedTriangles[currentId];
+            std::set<vtkIdType>::const_iterator it = adj.begin();
+            while(it != adj.end())
+              {
+              vtkIdType other = *it;
+              if(visitedCell.find(other) == visitedCell.end())
+                {
+                cellList.push_back(other);
+                visitedCell.insert(other);
+                }
+              it++;
+              }
+            }
+          }
+
+
+
+        // then I add this batch to the output,
+        // creating a unique cell for the whole batch.
+
+        if(batch.size() == 1)
+          {
+          vtkIdType tid = *(batch.begin());
+          vtkIdType npts;
+          vtkIdType* pts = NULL;
+          inpd->GetCellPoints(tid, npts, pts);
+          vtkIdType newCellId =
+              outpd->InsertNextCell(VTK_TRIANGLE, npts, pts);
+          outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+          }
+        else if(batch.size() == 2)
+          { // two triangles connected together --> create a VTK_QUAD
+          vtkIdType fid = *(batch.begin());
+          vtkIdType sid = *(batch.rbegin());
+          vtkIdType fnpts;
+          vtkIdType* fpts = NULL;
+          inpd->GetCellPoints(fid, fnpts, fpts);
+          vtkIdType snpts;
+          vtkIdType* spts = NULL;
+          inpd->GetCellPoints(sid, snpts, spts);
+
+          int findex = 0;
+          vtkIdType fv = fpts[findex];
+          while(((fv == spts[0]) ||
+                 (fv == spts[1]) ||
+                 (fv == spts[2])) && findex < 3)
+            {
+            findex++;
+            fv = fpts[findex];
+            }
+          if(findex == 3)
+            {// this is a degenerate case : one of the triangles use
+            // only 2 vertices
+            findex = 0;
+            }
+          int sindex = 0;
+          vtkIdType sv = spts[sindex];
+          while(((sv == fpts[0]) ||
+                 (sv == fpts[1]) ||
+                 (sv == fpts[2])) && sindex < 3)
+            {
+            sindex++;
+            sv = spts[sindex];
+            }
+          if(sindex == 3)
+            {// this is a degenerate case : one of the triangles use
+            // only 2 vertices
+            sindex = 0;
+            }
+
+          vtkIdType pts[4];
+          pts[0] = fpts[findex];
+          pts[1] = fpts[(findex+1)%3];
+          pts[2] = spts[sindex];
+          pts[3] = fpts[(findex+2)%3];
+
+          vtkIdType newCellId = outpd->InsertNextCell(VTK_QUAD, 4, pts);
+          outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+          }
+        else
+          {
+          std::deque<vtkEDFEdge> contour;
+
+          std::list<vtkIdType> toVisit;
+          std::set<vtkIdType> visited;
+
+          toVisit.push_back(*(batch.begin()));
+
+          std::set<vtkIdType> triedAgain;
+
+          while(toVisit.size() > 0)
+            {
+            vtkIdType currentId = *(toVisit.begin());
+            toVisit.pop_front();
+            if(visited.find(currentId) != visited.end())
+              continue;
+
+            visited.insert(currentId);
+            const std::set<vtkIdType>& adj = connectedTriangles[currentId];
+            std::set<vtkIdType>::const_iterator it = adj.begin();
+            while(it != adj.end())
+              {
+              vtkIdType adjid = *it;
+              it++;
+              if(visited.find(adjid) != visited.end())
+                continue;
+
+              toVisit.push_back(adjid);
+              }
+
+            vtkIdType npts;
+            vtkIdType* pts = NULL;
+            inpd->GetCellPoints(currentId, npts, pts);
+            vtkEDFEdge edge[3] = {vtkEDFEdge(pts[0], pts[1]),
+                                  vtkEDFEdge(pts[1], pts[2]),
+                                  vtkEDFEdge(pts[2], pts[0])};
+
+            // special case : initialization of the contour
+            if(contour.size() == 0)
+              {
+              contour.push_back(edge[0]);
+              contour.push_back(edge[1]);
+              contour.push_back(edge[2]);
+              continue;
+              }
+
+            // Find which edge of the contour
+            // is connected to the current triangle
+            int orient = 0;
+            std::deque<vtkEDFEdge>::iterator contourit = contour.begin();
+            bool found = false;
+            while(contourit != contour.end())
+              {
+              vtkEDFEdge& e = *contourit;
+              for(orient = 0; orient<3; orient++)
+                {
+                if(e == edge[orient])
+                  {
+                  found = true;
+                  break;
+                  }
+                }
+              if(found)
+                break;
+
+              contourit++;
+              }
+            if(contourit == contour.end())
+              {// this triangle is not connected to the current contour.
+              // put it back in the queue for later processing
+              if(triedAgain.find(currentId) == triedAgain.end())
+                {
+                triedAgain.insert(currentId);
+                toVisit.push_back(currentId);
+                visited.erase(currentId);
+                continue;
+                }
+              else
+                {
+                vtkDebugMacro( << "triangle " << currentId
+                  << "could not be added to the contour of the current batch");
+                continue;
+                }
+              }
+            // if I reach this point, I will add the triangle to the contour
+            // --> the contour will be modified and I can try again
+            // to add the previously rejected triangles
+            triedAgain.clear();
+
+            // Now, merge the edges of the current triangle with
+            // the contour
+            vtkEDFEdge& tbeforeedge = edge[(orient+1)%3];
+            vtkEDFEdge& tafteredge = edge[(orient+2)%3];
+
+            std::deque<vtkEDFEdge>::iterator beforeit;
+            if(contourit == contour.begin())
+              beforeit = contour.end()-1;
+            else
+              beforeit = contourit - 1;
+            vtkEDFEdge& beforeedge = *beforeit;
+
+            std::deque<vtkEDFEdge>::iterator afterit;
+            if(contourit == contour.end()-1)
+              afterit = contour.begin();
+            else
+              afterit = contourit + 1;
+            vtkEDFEdge& afteredge = *afterit;
+
+            if(beforeedge == tbeforeedge)
+              {
+              if(afteredge == tafteredge)
+                {// in this case, I am adding a triangle that is fully inside
+                // the contour. I need to remove the three edges from the
+                // contour.
+                if(contour.size() == 3)
+                  {
+                  contour.clear();
+                  }
+                else
+                  {
+                  std::deque<vtkEDFEdge>::iterator lastit;
+                  if(afterit == contour.end()-1)
+                    lastit = contour.begin();
+                  else
+                    lastit = afterit + 1;
+
+                  if(lastit < beforeit)
+                    {
+                    contour.erase(beforeit, contour.end());
+                    contour.erase(contour.begin(), lastit);
+                    }
+                  else
+                    {
+                    contour.erase(beforeit, lastit);
+                    }
+                  }
+                }
+              else
+                {// the edge before is the glued, remove the two adjacent edges
+                // and add the edge after
+                if(beforeit == contour.end()-1)
+                  {
+                  contour.erase(beforeit, contour.end());
+                  contour.erase(contour.begin(), contour.begin()+1);
+                  contour.push_back(tafteredge);
+                  }
+                else
+                  {
+                  int index = beforeit - contour.begin();
+                  contour.erase(beforeit, contourit+1);
+                  contour.insert(contour.begin()+index, tafteredge);
+                  }
+                }
+              }
+            else if(afteredge == tafteredge)
+              {// the edge after is glued, removed the two glued edges and add
+              // the edge new edge
+              if(contourit == contour.end() -1)
+                {
+                contour.erase(contour.end() - 1);
+                contour.erase(contour.begin());
+                contour.push_back(tbeforeedge);
+                }
+              else
+                {
+                int index = contourit - contour.begin();
+                contour.erase(contourit, afterit+1);
+                contour.insert(contour.begin()+index, tbeforeedge);
+                }
+              }
+            else
+              {
+              int index = contourit - contour.begin();
+              contour.erase(contourit);
+              contour.insert(contour.begin()+index, tbeforeedge);
+              contour.insert(contour.begin()+index+1, tafteredge);
+              }
+            }
+          vtkSmartPointer<vtkIdList> ids = vtkSmartPointer<vtkIdList>::New();
+          std::deque<vtkEDFEdge>::iterator cit = contour.begin();
+          while(cit != contour.end())
+            {
+            vtkEDFEdge& e = *cit;
+            cit++;
+            ids->InsertNextId(e.v0);
+            }
+
+          vtkIdType newCellId = outpd->InsertNextCell(VTK_POLYGON, ids);
+          outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+          }
+        }
+      cellId = cellIdEnd - 1;
+      }
+    }
+}
+
+void  vtkEDFCutter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+
diff --git a/tools/vtkEDFOverloads/vtkEDFCutter.h b/tools/vtkEDFOverloads/vtkEDFCutter.h
new file mode 100755 (executable)
index 0000000..66cc6a9
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkEDFCutter_h__
+#define __vtkEDFCutter_h__
+
+#include "vtkEDFOverloadsDefines.h"
+#include "vtkCutter.h"
+
+class VTKTOOLS_EXPORT vtkEDFCutter : public vtkCutter
+{
+public :
+  static vtkEDFCutter* New();
+  vtkTypeRevisionMacro(vtkEDFCutter, vtkCutter);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // these ivars
+  // control the name given to the field in which the ids are written into.  If
+  // set to NULL, then vtkOriginalCellIds or vtkOriginalPointIds (the default)
+  // is used, respectively.
+  vtkSetStringMacro(OriginalCellIdsName);
+  virtual const char *GetOriginalCellIdsName() {
+    return (  this->OriginalCellIdsName
+            ? this->OriginalCellIdsName : "vtkOriginalCellIds");
+  }
+
+protected :
+  virtual int RequestData(vtkInformation *,
+                          vtkInformationVector **,
+                          vtkInformationVector *);
+
+  virtual void  AssembleOutputTriangles(vtkPolyData* inpd,
+                                        vtkPolyData* outpd);
+
+  char* OriginalCellIdsName;
+
+  vtkEDFCutter();
+  ~vtkEDFCutter();
+
+private:
+  vtkEDFCutter(const vtkEDFCutter&);  // Not implemented.
+  void operator=(const vtkEDFCutter&);  // Not implemented.
+};
+
+#endif //__vtkEDFCutter_h__
diff --git a/tools/vtkEDFOverloads/vtkEDFFactory.cxx b/tools/vtkEDFOverloads/vtkEDFFactory.cxx
new file mode 100755 (executable)
index 0000000..5f87f51
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkEDFFactory.h"
+#include "vtkVersion.h"
+#include "vtkEDFCutter.h"
+
+vtkStandardNewMacro(vtkEDFFactory);
+
+VTK_CREATE_CREATE_FUNCTION(vtkEDFCutter);
+
+vtkEDFFactory::vtkEDFFactory()
+{
+  this->RegisterOverride("vtkCutter",
+                         "vtkEDFCutter",
+                         "MergeTriangles",
+                         1,
+                         vtkObjectFactoryCreatevtkEDFCutter);
+}
+
+const char* vtkEDFFactory::GetVTKSourceVersion()
+{
+  return VTK_SOURCE_VERSION;
+}
+
+const char* vtkEDFFactory::GetDescription()
+{
+  return "VTK EDF Factory";
+}
+
+VTK_FACTORY_INTERFACE_IMPLEMENT(vtkEDFFactory);
diff --git a/tools/vtkEDFOverloads/vtkEDFFactory.h b/tools/vtkEDFOverloads/vtkEDFFactory.h
new file mode 100755 (executable)
index 0000000..6693070
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkEDFFactory_h
+#define __vtkEDFFactory_h
+
+#include "vtkEDFOverloadsDefines.h"
+#include "vtkObjectFactory.h"
+
+class VTKEDF_OVERLOADS_EXPORT vtkEDFFactory : public vtkObjectFactory
+{
+public:
+// Methods from vtkObject
+  vtkTypeMacro(vtkEDFFactory,vtkObjectFactory);
+  static vtkEDFFactory *New();
+
+  virtual const char* GetVTKSourceVersion();
+  virtual const char* GetDescription();
+protected:
+  vtkEDFFactory();
+private:
+  vtkEDFFactory(const vtkEDFFactory&);  // Not implemented.
+  void operator=(const vtkEDFFactory&);  // Not implemented.
+};
+
+extern "C" VTK_EXPORT vtkObjectFactory* vtkLoad();
+#endif
diff --git a/tools/vtkEDFOverloads/vtkEDFOverloadsDefines.h b/tools/vtkEDFOverloads/vtkEDFOverloadsDefines.h
new file mode 100755 (executable)
index 0000000..83e9348
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VTKEDF_OVERLOADS_DEFINES_H
+#define VTKEDF_OVERLOADS_DEFINES_H
+
+#if defined WIN32
+#  if defined VTKEDF_OVERLOADS_EXPORTS || defined vtkEDFOverloads_EXPORTS
+#    define VTKEDF_OVERLOADS_EXPORT __declspec( dllexport )
+#  else
+#    define VTKEDF_OVERLOADS_EXPORT __declspec( dllimport )
+#  endif
+
+#  if defined VTKTOOLS_EXPORTS || defined vtkTools_EXPORTS
+#    define VTKTOOLS_EXPORT __declspec( dllexport )
+#  else
+#    define VTKTOOLS_EXPORT __declspec( dllimport )
+#  endif
+
+#else
+#  define VTKEDF_OVERLOADS_EXPORT
+#  define VTKTOOLS_EXPORT
+#endif //WIN32
+
+#endif //VTKEDF_OVERLOADS_DEFINES_H