]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
This commit was generated by cvs2git to create branch 'BR-D5-38-2003'.
authoradmin <salome-admin@opencascade.com>
Thu, 29 Dec 2005 14:27:27 +0000 (14:27 +0000)
committeradmin <salome-admin@opencascade.com>
Thu, 29 Dec 2005 14:27:27 +0000 (14:27 +0000)
Cherrypick from master 2005-12-29 14:27:26 UTC stv <stv@opencascade.com> 'Search item referenced list in the component. If not found then list searched in the dictionary.':
    INSTALL
    Makefile.in
    bin/VERSION
    bin/runLightSalome.sh
    build_configure
    doc/salome/GUI_index.html
    doc/salome/gui/KERNEL/viewers.htm
    src/CAF/CAF_Study.cxx
    src/DDS/DDS.h
    src/DDS/DDS_DicGroup.cxx
    src/DDS/DDS_DicGroup.h
    src/DDS/DDS_DicItem.cxx
    src/DDS/DDS_DicItem.h
    src/DDS/DDS_Dictionary.cxx
    src/DDS/DDS_Dictionary.h
    src/DDS/DDS_KeyWords.cxx
    src/DDS/DDS_KeyWords.h
    src/DDS/Makefile.in
    src/LightApp/LightApp_Application.cxx
    src/LightApp/LightApp_DataObject.cxx
    src/LightApp/LightApp_DataObject.h
    src/LightApp/LightApp_PreferencesDlg.cxx
    src/LightApp/LightApp_PreferencesDlg.h
    src/LightApp/LightApp_Selection.cxx
    src/LightApp/LightApp_Selection.h
    src/LightApp/LightApp_ShowHideOp.cxx
    src/LightApp/Makefile.in
    src/LightApp/resources/LightApp.xml
    src/LightApp/resources/LightApp_msg_en.po
    src/Makefile.in
    src/OCCViewer/Makefile.in
    src/OCCViewer/OCCViewer_ClippingDlg.cxx
    src/OCCViewer/OCCViewer_ClippingDlg.h
    src/OCCViewer/OCCViewer_ViewModel.cxx
    src/OCCViewer/OCCViewer_ViewWindow.cxx
    src/OCCViewer/OCCViewer_ViewWindow.h
    src/OCCViewer/resources/OCCViewer_images.po
    src/OCCViewer/resources/OCCViewer_msg_en.po
    src/OCCViewer/resources/view_clipping.png
    src/OCCViewer/resources/view_clipping_pressed.png
    src/ObjBrowser/OB_ListItem.cxx
    src/ObjBrowser/OB_ListItem.h
    src/ObjBrowser/OB_ListView.cxx
    src/ObjBrowser/OB_ListView.h
    src/Plot2d/Plot2d_Curve.cxx
    src/Plot2d/Plot2d_Curve.h
    src/Plot2d/Plot2d_SetupViewDlg.cxx
    src/Plot2d/Plot2d_ViewFrame.cxx
    src/Plot2d/Plot2d_ViewFrame.h
    src/Plot2d/Plot2d_ViewWindow.cxx
    src/Plot2d/Plot2d_ViewWindow.h
    src/Plot2d/resources/Plot2d_msg_en.po
    src/PyInterp/PyInterp_Dispatcher.cxx
    src/PyInterp/PyInterp_base.cxx
    src/PyInterp/PyInterp_base.h
    src/PythonConsole/PythonConsole_PyEditor.cxx
    src/PythonConsole/PythonConsole_PyInterp.cxx
    src/QDS/Makefile.in
    src/QDS/QDS.cxx
    src/QDS/QDS.h
    src/QDS/QDS_CheckBox.cxx
    src/QDS/QDS_CheckBox.h
    src/QDS/QDS_ComboBox.cxx
    src/QDS/QDS_ComboBox.h
    src/QDS/QDS_Datum.cxx
    src/QDS/QDS_Datum.h
    src/QDS/QDS_LineEdit.cxx
    src/QDS/QDS_LineEdit.h
    src/QDS/QDS_SpinBox.cxx
    src/QDS/QDS_SpinBox.h
    src/QDS/QDS_SpinBoxDbl.cxx
    src/QDS/QDS_SpinBoxDbl.h
    src/QDS/QDS_TextEdit.cxx
    src/QDS/QDS_TextEdit.h
    src/QDS/QDS_Validator.cxx
    src/QDS/QDS_Validator.h
    src/Qtx/QtxColorScale.cxx
    src/Qtx/QtxDblSpinBox.cxx
    src/Qtx/QtxListResourceEdit.cxx
    src/Qtx/QtxListResourceEdit.h
    src/Qtx/QtxMainWindow.cxx
    src/Qtx/QtxMainWindow.h
    src/Qtx/QtxPopupMgr.cxx
    src/Qtx/QtxPopupMgr.h
    src/Qtx/QtxWorkstack.cxx
    src/Qtx/QtxWorkstack.h
    src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx
    src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx
    src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx
    src/SALOME_PYQT/SalomePyQt/SalomePyQt_v4.sip
    src/SALOME_SWIG/salome_test.py
    src/STD/STD_Application.cxx
    src/STD/STD_Application.h
    src/STD/STD_TabDesktop.cxx
    src/STD/resources/STD_msg_en.po
    src/SUIT/SUIT_DataOwner.cxx
    src/SUIT/SUIT_DataOwner.h
    src/SUIT/SUIT_MessageBox.cxx
    src/SUIT/SUIT_MessageBox.h
    src/SUIT/SUIT_SelectionMgr.cxx
    src/SUIT/SUIT_SelectionMgr.h
    src/SUIT/SUIT_ViewWindow.cxx
    src/SUIT/SUIT_ViewWindow.h
    src/SUITApp/SUITApp.cxx
    src/SalomeApp/SalomeApp_Application.cxx
    src/SalomeApp/SalomeApp_Application.h
    src/SalomeApp/SalomeApp_DataObject.cxx
    src/SalomeApp/SalomeApp_DataObject.h
    src/SalomeApp/SalomeApp_Module.cxx
    src/SalomeApp/SalomeApp_Module.h
    src/SalomeApp/SalomeApp_PyInterp.cxx
    src/SalomeApp/resources/SalomeApp_msg_en.po
    src/Session/SALOME_Session_Server.cxx
    src/Session/Session_ServerThread.cxx

114 files changed:
INSTALL [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
bin/VERSION [new file with mode: 0755]
bin/runLightSalome.sh [new file with mode: 0755]
build_configure [new file with mode: 0755]
doc/salome/GUI_index.html [new file with mode: 0755]
doc/salome/gui/KERNEL/viewers.htm [new file with mode: 0755]
src/CAF/CAF_Study.cxx [new file with mode: 0755]
src/DDS/DDS.h [new file with mode: 0644]
src/DDS/DDS_DicGroup.cxx [new file with mode: 0644]
src/DDS/DDS_DicGroup.h [new file with mode: 0644]
src/DDS/DDS_DicItem.cxx [new file with mode: 0644]
src/DDS/DDS_DicItem.h [new file with mode: 0644]
src/DDS/DDS_Dictionary.cxx [new file with mode: 0644]
src/DDS/DDS_Dictionary.h [new file with mode: 0644]
src/DDS/DDS_KeyWords.cxx [new file with mode: 0644]
src/DDS/DDS_KeyWords.h [new file with mode: 0644]
src/DDS/Makefile.in [new file with mode: 0755]
src/LightApp/LightApp_Application.cxx [new file with mode: 0644]
src/LightApp/LightApp_DataObject.cxx [new file with mode: 0644]
src/LightApp/LightApp_DataObject.h [new file with mode: 0644]
src/LightApp/LightApp_PreferencesDlg.cxx [new file with mode: 0644]
src/LightApp/LightApp_PreferencesDlg.h [new file with mode: 0644]
src/LightApp/LightApp_Selection.cxx [new file with mode: 0644]
src/LightApp/LightApp_Selection.h [new file with mode: 0644]
src/LightApp/LightApp_ShowHideOp.cxx [new file with mode: 0644]
src/LightApp/Makefile.in [new file with mode: 0755]
src/LightApp/resources/LightApp.xml [new file with mode: 0644]
src/LightApp/resources/LightApp_msg_en.po [new file with mode: 0644]
src/Makefile.in [new file with mode: 0755]
src/OCCViewer/Makefile.in [new file with mode: 0755]
src/OCCViewer/OCCViewer_ClippingDlg.cxx [new file with mode: 0644]
src/OCCViewer/OCCViewer_ClippingDlg.h [new file with mode: 0644]
src/OCCViewer/OCCViewer_ViewModel.cxx [new file with mode: 0755]
src/OCCViewer/OCCViewer_ViewWindow.cxx [new file with mode: 0755]
src/OCCViewer/OCCViewer_ViewWindow.h [new file with mode: 0755]
src/OCCViewer/resources/OCCViewer_images.po [new file with mode: 0755]
src/OCCViewer/resources/OCCViewer_msg_en.po [new file with mode: 0755]
src/OCCViewer/resources/view_clipping.png [new file with mode: 0644]
src/OCCViewer/resources/view_clipping_pressed.png [new file with mode: 0644]
src/ObjBrowser/OB_ListItem.cxx [new file with mode: 0755]
src/ObjBrowser/OB_ListItem.h [new file with mode: 0755]
src/ObjBrowser/OB_ListView.cxx [new file with mode: 0755]
src/ObjBrowser/OB_ListView.h [new file with mode: 0755]
src/Plot2d/Plot2d_Curve.cxx [new file with mode: 0755]
src/Plot2d/Plot2d_Curve.h [new file with mode: 0755]
src/Plot2d/Plot2d_SetupViewDlg.cxx [new file with mode: 0755]
src/Plot2d/Plot2d_ViewFrame.cxx [new file with mode: 0755]
src/Plot2d/Plot2d_ViewFrame.h [new file with mode: 0755]
src/Plot2d/Plot2d_ViewWindow.cxx [new file with mode: 0755]
src/Plot2d/Plot2d_ViewWindow.h [new file with mode: 0755]
src/Plot2d/resources/Plot2d_msg_en.po [new file with mode: 0755]
src/PyInterp/PyInterp_Dispatcher.cxx [new file with mode: 0755]
src/PyInterp/PyInterp_base.cxx [new file with mode: 0644]
src/PyInterp/PyInterp_base.h [new file with mode: 0644]
src/PythonConsole/PythonConsole_PyEditor.cxx [new file with mode: 0755]
src/PythonConsole/PythonConsole_PyInterp.cxx [new file with mode: 0755]
src/QDS/Makefile.in [new file with mode: 0755]
src/QDS/QDS.cxx [new file with mode: 0644]
src/QDS/QDS.h [new file with mode: 0644]
src/QDS/QDS_CheckBox.cxx [new file with mode: 0644]
src/QDS/QDS_CheckBox.h [new file with mode: 0644]
src/QDS/QDS_ComboBox.cxx [new file with mode: 0644]
src/QDS/QDS_ComboBox.h [new file with mode: 0644]
src/QDS/QDS_Datum.cxx [new file with mode: 0644]
src/QDS/QDS_Datum.h [new file with mode: 0644]
src/QDS/QDS_LineEdit.cxx [new file with mode: 0644]
src/QDS/QDS_LineEdit.h [new file with mode: 0644]
src/QDS/QDS_SpinBox.cxx [new file with mode: 0644]
src/QDS/QDS_SpinBox.h [new file with mode: 0644]
src/QDS/QDS_SpinBoxDbl.cxx [new file with mode: 0644]
src/QDS/QDS_SpinBoxDbl.h [new file with mode: 0644]
src/QDS/QDS_TextEdit.cxx [new file with mode: 0644]
src/QDS/QDS_TextEdit.h [new file with mode: 0644]
src/QDS/QDS_Validator.cxx [new file with mode: 0644]
src/QDS/QDS_Validator.h [new file with mode: 0644]
src/Qtx/QtxColorScale.cxx [new file with mode: 0755]
src/Qtx/QtxDblSpinBox.cxx [new file with mode: 0755]
src/Qtx/QtxListResourceEdit.cxx [new file with mode: 0644]
src/Qtx/QtxListResourceEdit.h [new file with mode: 0644]
src/Qtx/QtxMainWindow.cxx [new file with mode: 0644]
src/Qtx/QtxMainWindow.h [new file with mode: 0644]
src/Qtx/QtxPopupMgr.cxx [new file with mode: 0644]
src/Qtx/QtxPopupMgr.h [new file with mode: 0644]
src/Qtx/QtxWorkstack.cxx [new file with mode: 0644]
src/Qtx/QtxWorkstack.h [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx [new file with mode: 0644]
src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx [new file with mode: 0644]
src/SALOME_PYQT/SalomePyQt/SalomePyQt_v4.sip [new file with mode: 0644]
src/SALOME_SWIG/salome_test.py [new file with mode: 0755]
src/STD/STD_Application.cxx [new file with mode: 0755]
src/STD/STD_Application.h [new file with mode: 0755]
src/STD/STD_TabDesktop.cxx [new file with mode: 0644]
src/STD/resources/STD_msg_en.po [new file with mode: 0755]
src/SUIT/SUIT_DataOwner.cxx [new file with mode: 0755]
src/SUIT/SUIT_DataOwner.h [new file with mode: 0755]
src/SUIT/SUIT_MessageBox.cxx [new file with mode: 0755]
src/SUIT/SUIT_MessageBox.h [new file with mode: 0755]
src/SUIT/SUIT_SelectionMgr.cxx [new file with mode: 0755]
src/SUIT/SUIT_SelectionMgr.h [new file with mode: 0755]
src/SUIT/SUIT_ViewWindow.cxx [new file with mode: 0755]
src/SUIT/SUIT_ViewWindow.h [new file with mode: 0755]
src/SUITApp/SUITApp.cxx [new file with mode: 0644]
src/SalomeApp/SalomeApp_Application.cxx [new file with mode: 0644]
src/SalomeApp/SalomeApp_Application.h [new file with mode: 0644]
src/SalomeApp/SalomeApp_DataObject.cxx [new file with mode: 0644]
src/SalomeApp/SalomeApp_DataObject.h [new file with mode: 0644]
src/SalomeApp/SalomeApp_Module.cxx [new file with mode: 0644]
src/SalomeApp/SalomeApp_Module.h [new file with mode: 0644]
src/SalomeApp/SalomeApp_PyInterp.cxx [new file with mode: 0755]
src/SalomeApp/resources/SalomeApp_msg_en.po [new file with mode: 0644]
src/Session/SALOME_Session_Server.cxx [new file with mode: 0755]
src/Session/Session_ServerThread.cxx [new file with mode: 0755]

diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..dcef3b7
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,3 @@
+This is the version 3.1.0 of SALOMEGUI
+Compatible with :
+        - KERNEL 3.1.0
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..989c6a4
--- /dev/null
@@ -0,0 +1,169 @@
+# -* Makefile *- 
+#
+# Author : Patrick GOLDBRONN (CEA)
+# Date : 28/06/2001
+# $Header$
+#
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=.
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/bin:./bin/salome:@top_srcdir@/resources:./bin:@top_srcdir@/idl
+
+
+@COMMENCE@
+
+SUBDIRS = idl src doc
+
+RESOURCES_FILES = \
+back.xpm \
+cascade.png \
+close.png \
+default.png \
+dl_delete.png \
+dl_insert.png \
+dl_moveup.png \
+dl_movedown.png \
+forward.xpm \
+help.png \
+home.xpm \
+new.png \
+open.png \
+print.png \
+reset.png \
+save.png \
+select1.png \
+tile.png \
+Tools_en.xml \
+view_back.png \
+view_bottom.png \
+view_camera_dump.png \
+view_fitall.png \
+view_fitarea.png \
+view_front.png \
+view_glpan.png \
+view_left.png \
+view_pan.png \
+view_reset.png \
+view_right.png \
+view_rotate.png \
+view_top.png \
+view_triedre.png \
+view_zoom.png \
+copy.png \
+paste.png \
+plot2d_dump.png \
+plot2d_fitall.png \
+plot2d_fitarea.png \
+plot2d_legend.png \
+plot2d_linear.png \
+plot2d_linear_y.png \
+plot2d_lines.png \
+plot2d_log.png \
+plot2d_log_y.png \
+plot2d_pan.png \
+plot2d_points.png \
+plot2d_settings.png \
+plot2d_splines.png \
+plot2d_zoom.png \
+uc_add.png \
+uc_current.png \
+uc_del.png \
+uc_new.png \
+uc_clear.png \
+channel.cfg \
+
+BIN_SCRIPT= VERSION \
+runLightSalome.csh \
+runLightSalome.sh
+
+# copy header files in common directory
+OWN_CONFIG_H=@OWN_CONFIG_H@
+
+ifeq ($(OWN_CONFIG_H),yes)
+    ifeq ($(HAVE_SSTREAM),yes)
+       include_list=include/salome/SALOMEconfig.h include/salome/config.h
+    else
+       include_list=include/salome/SALOMEconfig.h include/salome/config.h include/salome/sstream
+    endif
+else
+    ifeq ($(HAVE_SSTREAM),yes)
+       include_list=include/salome/SALOMEconfig.h
+    else
+       include_list=include/salome/SALOMEconfig.h include/salome/sstream
+    endif
+endif
+
+inc: idl $(include_list)
+
+include/salome/SALOMEconfig.h: salome_adm/unix/SALOMEconfig.ref
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+# test if SALOMEconfig.h has changed (contents)
+salome_adm/unix/SALOMEconfig.ref: salome_adm/unix/SALOMEconfig.h
+       @if ! [ -a $@ ]; then \
+         cp -p $< $@;        \
+       fi;                   \
+       if ! cmp $< $@; then  \
+         cp -p $< $@;        \
+       fi;                   \
+
+include/salome/config.h: salome_adm/unix/config.h
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+include/salome/sstream: salome_adm/unix/sstream
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+depend: depend_idl
+
+depend_idl:
+       (cd idl ; $(MAKE) $@) || exit 1
+
+# doc is already build : if you want to had documents, go manually to doc and run 'make doc'
+#doc:
+#      (cd doc && $(MAKE) $@) || exit 1
+
+# Install make_commence make_conclude ... for other modules
+install-make:
+       ($(INSTALL) -d  $(incmakedir) || exit 1);
+       (sed 's/^prefix=/#prefix=/' $(top_builddir)/adm_local/unix/make_commence > $(incmakedir)/make_commence || exit 1);
+
+
+install-end:
+# finish libtool install
+#      @$(LT) --mode=finish $(libdir)
+
+install-include: $(include_list)
+       $(INSTALL) -d  $(includedir)
+       @for f in X $(include_list); do                         \
+          if test $$f != X; then                               \
+            (cp -p $$f $(includedir) || exit 1);               \
+          fi;                                                  \
+       done
+
+# install script in $(bindir) :
+install-bin: $(BIN_SCRIPT)
+       $(INSTALL) -d  $(bindir)
+       $(INSTALL_PROGRAM) $^ $(bindir)
+
+uninstall: uninstall-idl
+
+uninstall-idl:
+       $(RM) $(idldir)/*.idl
+
+distclean: distclean-other
+
+distclean-other:
+       -$(RM) salome_adm/unix/*~ salome_adm/unix/*% salome_adm/unix/*.bak salome_adm/unix/*.new salome_adm/unix/*.old
+       -$(RM) salome_adm/unix/make_* 
+       -$(RM) salome_adm/unix/depend salome_adm/unix/SALOMEconfig.h salome_adm/unix/config.h 
+       -$(RM) config.cache config.log config.status 
+
+@MODULE@
+
+install: install-bin install-include install-make install-end
+
diff --git a/bin/VERSION b/bin/VERSION
new file mode 100755 (executable)
index 0000000..fe6986e
--- /dev/null
@@ -0,0 +1 @@
+THIS IS SALOME - SALOMEGUI VERSION: 3.1.0
diff --git a/bin/runLightSalome.sh b/bin/runLightSalome.sh
new file mode 100755 (executable)
index 0000000..f99a812
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash -f
+
+if [ -z "$SUITRoot" ] ; then          
+  export SUITRoot=${GUI_ROOT_DIR}/share/salome
+fi
+# this variable necessary for loading .ini or .xml file
+if [ -z "$LightAppConfig" ] ; then
+  export LightAppConfig=${GUI_ROOT_DIR}/share/salome/resources
+fi
+if [ -z "$LightAppResources" ] ; then
+  export LightAppResources=${GUI_ROOT_DIR}/share/salome/resources
+fi
+
+SUITApp LightApp -style salome $* &
diff --git a/build_configure b/build_configure
new file mode 100755 (executable)
index 0000000..ec5cce6
--- /dev/null
@@ -0,0 +1,215 @@
+#!/bin/bash
+
+#
+# Tool for updating list of .in file for the SALOME project 
+# and regenerating configure script
+#
+# Author : Marc Tajchman - CEA
+# Date : 10/10/2002
+# $Header$
+#
+
+ORIG_DIR=`pwd`
+CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"`
+
+########################################################################
+# Test if the KERNEL_ROOT_DIR is set correctly
+if test ! -d "${KERNEL_ROOT_DIR}"; then
+    echo "failed : KERNEL_ROOT_DIR variable is not correct !"
+    exit
+fi
+
+# Test if the KERNEL_SRC is set correctly
+
+#if test ! -d "${KERNEL_SRC}"; then
+#    echo "failed : KERNEL_SRC variable is not correct !"
+#    exit
+#fi
+########################################################################
+# find_in - utility function
+#
+# usage :  
+#    find_in directory filename 
+#
+# Finds files following the *.in pattern, recursively in the
+# directory (first argument).
+# Results are appended into the file (second argument)
+#
+# Difference from the standard unix find is that files are tested
+# before directories
+# 
+
+find_in()
+{
+  local i
+  local f=$2
+
+# if the first argument is not a directory, returns
+
+  if [ ! -d "$1" ] ; then 
+     return 
+  fi
+
+# dont look in the CVS directories
+
+  case $1 in
+    */CVS) return ;;
+    */adm_local/*) return ;;
+    *) ;;
+  esac
+
+# for each regular file contained in the directory
+# test if it's a .in file
+
+  for i in "$1"/*
+  do
+     if [ -f "$i" ] ; then
+       case $i in 
+         *.in) echo "  "$i" \\" >> $f;;
+         *) ;;
+        esac
+     fi
+  done
+
+# for each subdirectory of the first argument, proceeds recursively
+
+  for i in "$1"/*
+  do
+     if [ -d "$i" ] ; then
+        find_in "$i" "$f"
+     fi
+  done
+}
+
+
+#######################################################################
+# Generate list of .in files (Makefile.in, config.h.in, etc)
+# appending it in file configure.in
+
+cd ${CONF_DIR}
+ABS_CONF_DIR=`pwd`
+
+#
+# Common part of the configure.in file
+#
+chmod u+w configure.in.base
+if ! \cp -f configure.in.base configure.in_tmp1 
+then
+       echo
+       echo "error : can't create files in" ${CONF_DIR}
+       echo "aborting ..."
+        chmod u-w configure.in.base 
+       exit
+fi
+chmod u-w configure.in.base 
+
+if [ -e "${CONF_DIR}/salome_adm" ] ; then
+    \rm -rf ${CONF_DIR}/salome_adm
+fi
+
+# make a link allowing AC_OUTPUT to find the salome_adm/.../*.in  files
+echo "" >> configure.in_tmp1
+echo 'ln -fs ${KERNEL_ROOT_DIR}/salome_adm ${ROOT_SRCDIR}/.' >> configure.in_tmp1
+
+echo  "" >> configure.in_tmp1
+echo "AC_OUTPUT([ \\" >> configure.in_tmp1
+
+#
+# List of .in files in the adm/unix directory
+# These files MUST be on top of AC_OUTPUT list so we
+# put them "manually"
+#
+
+echo " ./salome_adm/unix/SALOMEconfig.h \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/F77config.h \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/sstream \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/depend \\" >> configure.in_tmp1
+echo " ./adm_local/unix/make_omniorb \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/envScript \\" >> configure.in_tmp1
+echo " ./adm_local/unix/make_commence \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/make_conclude \\" >> configure.in_tmp1
+echo " ./salome_adm/unix/make_module \\" >> configure.in_tmp1
+
+\rm -f configure.in_tmp2 configure.in_tmp3
+touch configure.in_tmp2
+find_in . configure.in_tmp2
+sed -e '/^...salome_adm/d' configure.in_tmp2 >  configure.in_tmp3
+sed -e '/^...adm_local.unix.make_omniorb/d' configure.in_tmp3 > configure.in_tmp2
+sed -e '/^...adm_local.unix.make_commence/d' configure.in_tmp2 > configure.in_tmp3
+sed -e '/configure.in/d' configure.in_tmp3 >  configure.in_tmp2
+sed -e 's/.in / /' configure.in_tmp2 >>  configure.in_tmp1
+#sed '/^.salome_adm/d' configure.in_tmp2 >  configure.in_tmp3
+#sed '/configure.in/d' configure.in_tmp3 >  configure.in_tmp2
+#sed 's/.in / /' configure.in_tmp2 >> configure.in_tmp1
+
+echo  "])" >> configure.in_tmp1
+
+# delete the link created for AC_OUTPUT
+echo "" >> configure.in_tmp1
+#echo 'rm -f ${ROOT_SRCDIR}/salome_adm' >> configure.in_tmp1
+\mv configure.in_tmp1 configure.in_new
+\rm  -f configure.in_tmp2 configure.in_tmp3
+
+
+########################################################################
+# Create new (or replace old) configure.in file
+# Print a message if the file is write protected
+#
+
+echo
+if test ! -f configure.in
+then
+       echo -n "Creating new file 'configure.in' ... "
+       if \mv configure.in_new configure.in >& /dev/null
+       then
+               echo "done"
+       else
+               echo "error, check your file permissions"
+       fi
+else
+       echo -n "Updating 'configure.in' file ... "
+       if ! \cp configure.in configure.in_old >& /dev/null
+       then
+               echo
+               echo
+               echo "Can't backup previous configure.in"
+               echo -n "Continue (you will not be able to revert) - (Y/N) ? "
+               read R
+                case "x$R" in
+                   xn*) exit;;
+                   xN*) exit;;
+               esac
+               echo
+               echo -n "                                 "
+       fi
+       if \cp configure.in_new configure.in >& /dev/null
+       then
+               echo "done"
+       else
+               echo
+               echo "error, can't update previous configure.in"
+       fi
+fi
+
+########################################################################
+# Use autoconf to rebuild the configure script
+#
+
+if test -f configure
+then
+       echo -n "Updating 'configure' script ...  "
+else
+       echo -n "Creating 'configure' script ...  "
+fi
+
+aclocal --acdir=adm_local/unix/config_files -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files
+if autoconf
+then
+       echo "done"
+else
+       echo "failed (check file permissions and/or user quotas ...)"
+fi
+
+cd ${ORIG_DIR}
+
+echo
diff --git a/doc/salome/GUI_index.html b/doc/salome/GUI_index.html
new file mode 100755 (executable)
index 0000000..465e3ea
--- /dev/null
@@ -0,0 +1,95 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+                                            
+  <meta http-equiv="Content-Type"
+ content="text/html; charset=iso-8859-1">
+                                            
+  <meta name="GENERATOR"
+ content="Mozilla/4.73 [en] (WinNT; I) [Netscape]">
+  <title>Gui Module Documentation</title>
+</head>
+  <body bgcolor="#cccccc" text="#000000" link="#0000ee" alink="#0000ee"
+ vlink="#551a8b">
+       
+<div align="center">    &nbsp;           
+<center>          
+<center>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp;&nbsp;</center>
+       
+<table width="96%" align="center">
+           <tbody>
+              <tr>
+           <td><a href="http://www.opencascade.com"><img
+ src="tui/SUIT/sources/logocorp.gif" border="0" height="46" width="122">
+                </a></td>
+             <td>                                                       
+               
+      <div align="right"><a href="http://www.opencascade.org/SALOME/"><img
+ src="tui/SUIT/sources/application.gif" border="0" height="46" width="108">
+                </a></div>
+           </td>
+           </tr>
+                                                      
+  </tbody>    
+</table>
+       
+<div align="center">    
+<center>    
+<hr width="100%" size="2">   
+<h1>GUI MODULE Documentation</h1>
+                                     </center>
+    </div>
+       
+<table width="96%">
+      <tbody>
+               
+  </tbody>    
+</table>
+    </center>
+       
+<div align="center">       
+<p> <img src="tui/SUIT/sources/Application-About.png"
+ alt="Application-About.png" width="30%" height="20%">
+    &nbsp; &nbsp;&nbsp;          </p>
+             </div>
+       
+<center>    
+<table width="96%">
+      <tbody>
+                 
+  </tbody>    
+</table>
+   <br>
+   <br>
+   <br>
+   </center>
+     
+<address> </address>
+   
+<center><big><a href="gui/KERNEL/kernel.htm">GUI Documentation</a></big></center>
+      
+<address> </address>
+   
+<center></center>
+      
+<center><br>
+   </center>
+     
+<address> </address>
+   
+<center><big><a href="tui/SUIT/index.html">TUI Documentation</a></big></center>
+      
+<address> </address>
+   
+<center></center>
+      
+<center><br>
+   <br>
+    </center>
+    </div>
+     <br>
+  <br>
+ <br>
+</body>
+</html>
diff --git a/doc/salome/gui/KERNEL/viewers.htm b/doc/salome/gui/KERNEL/viewers.htm
new file mode 100755 (executable)
index 0000000..2774379
--- /dev/null
@@ -0,0 +1,212 @@
+<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<title>Viewers</title>\r
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
+<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com">\r
+<link rel="stylesheet" href="default_ns.css"><script type="text/javascript" language="JavaScript" title="WebHelpSplitCss">\r
+<!--\r
+if (navigator.appName !="Netscape")\r
+{   document.write("<link rel='stylesheet' href='default.css'>");}\r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+ul.whs1 { list-style:disc; }\r
+img_whs2 { border:none; width:26px; height:25px; border-style:none; }\r
+img_whs3 { border:none; width:27px; height:26px; border-style:none; }\r
+img_whs4 { border:none; width:28px; height:26px; border-style:none; }\r
+img_whs5 { border:none; width:28px; height:29px; border-style:none; }\r
+img_whs6 { border:none; width:27px; height:25px; border-style:none; }\r
+img_whs7 { border:none; width:26px; height:26px; border-style:none; }\r
+img_whs8 { border:none; width:28px; height:28px; border-style:none; }\r
+img_whs9 { border:none; width:27px; height:27px; border-style:none; }\r
+img_whs10 { border:none; width:29px; height:28px; border-style:none; }\r
+img_whs11 { border:none; width:25px; height:27px; border-style:none; }\r
+img_whs12 { border:none; width:28px; height:30px; border-style:none; }\r
+img_whs13 { border:none; width:402px; height:396px; float:none; border-style:none; }\r
+-->\r
+</style><script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">\r
+<!--\r
+function reDo() {\r
+  if (innerWidth != origWidth || innerHeight != origHeight)\r
+     location.reload();\r
+}\r
+if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {\r
+       origWidth = innerWidth;\r
+       origHeight = innerHeight;\r
+       onresize = reDo;\r
+}\r
+onerror = null; \r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }\r
+-->\r
+</style><script type="text/javascript" language="javascript1.2" src="whmsg.js"></script>\r
+<script type="text/javascript" language="javascript" src="whver.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whproxy.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whutils.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whtopic.js"></script>\r
+</head>\r
+<body><script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.gbWhTopic)\r
+{\r
+       if (window.addTocInfo)\r
+       {\r
+       addTocInfo("GUI module\nViewers");\r
+addButton("show",BTN_TEXT,"Show","","","","",0,0,"","","");\r
+\r
+       }\r
+       if (window.writeBtnStyle)\r
+               writeBtnStyle();\r
+\r
+       if (window.writeIntopicBar)\r
+               writeIntopicBar(1);\r
+\r
+       if (window.setRelStartPage)\r
+       {\r
+       setRelStartPage("kernel.htm");\r
+\r
+               autoSync(1);\r
+               sendSyncInfo();\r
+               sendAveInfoOut();\r
+       }\r
+}\r
+else\r
+       if (window.gbIE4)\r
+               document.location.reload();\r
+//-->\r
+</script>\r
+<h1>Viewers</h1>\r
+\r
+<p>Salome gives you a choice of four different viewers. This wide choice \r
+ of instruments providing both common and unique possibilities aims to \r
+ give the users of SALOME Platform maximum convenience and ease in their \r
+ work.</p>\r
+\r
+<p>Customizing the viewers you can define settings to be used in them by \r
+ default in the <span style="font-weight: bold;"><B>Preferences</B></span> menu.</p>\r
+\r
+<p>Salome Platform also provides you with <span style="font-weight: bold;"><B>Viewer \r
+ Toolbars</B></span>, which make it possible to promptly operate your viewer \r
+ scene. Some of the functions are common for all viewers. </p>\r
+\r
+<ul type="disc" class="whs1">\r
+       \r
+       <li class=kadov-p><p><img src="image77.gif" width="26px" height="25px" border="0" class="img_whs2"> <span style="font-weight: bold;"><B>Dump \r
+ View</B></span> - exports an object from the viewer in bmp, png, jpg or jpeg \r
+ image format. </p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image78.gif" width="27px" height="26px" border="0" class="img_whs3"> <span style="font-weight: bold;"><B>Fit \r
+ all</B></span> - resizes the view to place all represented objects in the \r
+ visible area</p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image79.gif" width="28px" height="26px" border="0" class="img_whs4"> <span style="font-weight: bold;"><B>Panning</B></span> \r
+ - in case if the represented objects are greater that the visible area \r
+ and you don't wish to use <span style="font-weight: bold;"><B>Fit all</B></span> \r
+ functionality, click on this button and you'll be able to drag the scene \r
+ to see its remote parts. </p></li>\r
+</ul>\r
+\r
+<ul type="disc" class="whs1">\r
+       \r
+       <li class=kadov-p><p><img src="image86.gif" width="28px" height="29px" border="0" class="img_whs5"> <span style="font-weight: bold;"><B>Clone \r
+ view</B></span> - opens a new duplicate scene.</p></li>\r
+</ul>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<p><span style="font-weight: bold;"><B>VTK 3d &nbsp;viewer</B></span> \r
+ (Visualization ToolKit Viewer) and <span style="font-weight: bold;"><B>OCC \r
+ 3d viewer</B></span> (Open CasCade Viewer) are both useful for creation of \r
+ geometrical models in the GEOM module, however, there some differences, \r
+ which specialize the use of the modules. </p>\r
+\r
+<p><span style="font-weight: bold;"><B>OCC 3d viewer</B></span> is the default \r
+ viewer for GEOM Module. Only this viewer gives you the possibility to \r
+ select sub-shapes (described in full detail in the help for the GEOM Module). \r
+ Unfortunately, you can't visualize meshes in this viewer, for this, use \r
+ VTK 3d viewer. &nbsp;&nbsp;</p>\r
+\r
+<p><span style="font-weight: bold;"><B>VTK 3d &nbsp;viewer</B></span> \r
+ is the default viewer for SMESH Module. Using this viewer you'll be able \r
+ to visualize and work with meshes. &nbsp;</p>\r
+\r
+<p>Most of functions in Viewer Toolbars of these modules are common for \r
+ both viewers, they are:</p>\r
+\r
+<ul type="disc" class="whs1">\r
+       \r
+       <li class=kadov-p><p><img src="image88.gif" width="27px" height="25px" border="0" class="img_whs6"> <span style="font-weight: bold;"><B>Show/Hide \r
+ Trihedron</B></span> - shows or hides coordinate axes. </p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image89.gif" width="26px" height="26px" border="0" class="img_whs7"> <span style="font-weight: bold;"><B>Rotation</B></span> \r
+ - click this button and rotate the selected object in the viewer using \r
+ the mouse. </p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image90.gif" width="28px" height="28px" border="0" class="img_whs8"> <span style="font-weight: bold;"><B>Front</B></span> \r
+ - shows the front view of the object.</p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image91.gif" width="26px" height="26px" border="0" class="img_whs7"> <span style="font-weight: bold;"><B>Reset</B></span> \r
+ - returns the object in its initial position.</p></li>\r
+</ul>\r
+\r
+<p>One more function is available in <span style="font-weight: bold;"><B>OCC \r
+ 3d viewer</B></span> only. </p>\r
+\r
+<ul type="disc" class="whs1">\r
+       \r
+       <li class=kadov-p><p><img src="image92.gif" width="27px" height="25px" border="0" class="img_whs6"> <span style="font-weight: bold;"><B>Memorize \r
+ view</B></span> - saves the view of the object. </p></li>\r
+</ul>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<p><span style="font-weight: bold;"><B>Plot 2d viewer</B></span> is destined to \r
+ the representation of &nbsp;2d \r
+ plots and graphs obtained via Post-Pro module. </p>\r
+\r
+<p>Its viewer toolbar gives you fast access to the following operations:</p>\r
+\r
+<ul type="disc" class="whs1">\r
+       \r
+       <li class=kadov-p><p><img src="image80.gif" width="27px" height="27px" border="0" class="img_whs9"> Draw Points - represents points \r
+ on the graph.</p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image81.gif" width="29px" height="28px" border="0" class="img_whs10"> &amp; <img src="image82.gif" width="25px" height="27px" border="0" class="img_whs11"> Horizontal \r
+ axis logarithmic &amp; Vertical axis logarithmic - changes the scaling \r
+ on axes to logarithmic. </p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image83.gif" width="28px" height="30px" border="0" class="img_whs12"> Show Legend - reveals all verbal \r
+ and numerical information on the graphs.</p></li>\r
+       \r
+       <li class=kadov-p><p><img src="image84.gif" width="29px" height="28px" border="0" class="img_whs10"> Settings - calls a menu, in which \r
+ you can specify advanced settings for your <span style="font-weight: bold;"><B>Plot \r
+ 2d Viewer</B></span>. Value major/minor it is maximum number of\r
+ major/minor intervals for a specified axis. The real number of intervals\r
+ fits {1,2,5}*10^n with a natural number n and not exceed the maximum\r
+ as specified by the user. &nbsp;</p></li>\r
+</ul>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<p><img src="pics/plot1.png" x-maintain-ratio="TRUE" width="402px" height="396px" border="0" class="img_whs13"></p>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<p><span style="font-weight: bold;"><B>GL Viewer</B></span> is used by exterior \r
+ modules built-in in the <span style="font-weight: bold;"><B>SALOME Platform.</B></span></p>\r
+\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+       writeIntopicBar(0);\r
+//-->\r
+</script>\r
+</body>\r
+</html>\r
diff --git a/src/CAF/CAF_Study.cxx b/src/CAF/CAF_Study.cxx
new file mode 100755 (executable)
index 0000000..176023a
--- /dev/null
@@ -0,0 +1,381 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "CAF_Study.h"
+
+#include "CAF_Tools.h"
+#include "CAF_Operation.h"
+#include "CAF_Application.h"
+
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_Application.h>
+
+#include <qdir.h>
+
+#include <TDF_Delta.hxx>
+#include <TDF_ListIteratorOfDeltaList.hxx>
+
+#include <Standard_ErrorHandler.hxx>
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CAF_Study::CAF_Study(SUIT_Application* theApp)
+: SUIT_Study( theApp ),
+myModifiedCnt( 0 )
+{
+}
+
+CAF_Study::CAF_Study(SUIT_Application* theApp, Handle (TDocStd_Document)& aStdDoc)
+: SUIT_Study( theApp ),
+myStdDoc( aStdDoc ),
+myModifiedCnt( 0 )
+{
+}
+
+CAF_Study::~CAF_Study()
+{
+}
+
+Handle(TDocStd_Document) CAF_Study::stdDoc() const
+{
+  return myStdDoc;
+}
+
+void CAF_Study::setStdDoc( Handle(TDocStd_Document)& aStdDoc )
+{
+  myStdDoc = aStdDoc;
+}
+
+void CAF_Study::createDocument()
+{
+  SUIT_Study::createDocument();
+
+  CAF_Application* app = cafApplication();
+  if ( app && !app->stdApp().IsNull() )
+  {
+    try {
+      TColStd_SequenceOfExtendedString formats;
+           app->stdApp()->Formats( formats );
+      if ( !formats.IsEmpty() )
+        app->stdApp()->NewDocument( formats.First(), myStdDoc );
+    }
+    catch ( Standard_Failure ) {
+    }
+  }
+}
+
+void CAF_Study::closeDocument( bool permanent )
+{
+  Handle(TDocStd_Application) app = stdApp();
+  if ( !app.IsNull() && !stdDoc().IsNull() )
+    app->Close( stdDoc() );
+
+  SUIT_Study::closeDocument( permanent );
+}
+
+bool CAF_Study::openDocument( const QString& fname )
+{
+  Handle(TDocStd_Application) app = stdApp();
+  if ( app.IsNull() )
+    return false;
+
+  bool status = false;
+  try {
+    status = app->Open( CAF_Tools::toExtString( fname ), myStdDoc ) == CDF_RS_OK;
+  }
+  catch ( Standard_Failure ) {
+    status = false;
+  }
+
+  return status && SUIT_Study::openDocument( fname );
+}
+
+bool CAF_Study::saveDocumentAs( const QString& fname )
+{
+  Handle(TDocStd_Application) app = stdApp();
+  if ( app.IsNull() )
+    return false;
+
+  bool save = false;
+  if ( !stdDoc().IsNull() && stdDoc()->IsSaved() )
+  {
+    QString path = QDir::convertSeparators( CAF_Tools::toQString( stdDoc()->GetPath() ) );
+    save = path == QDir::convertSeparators( fname );
+  }
+
+  bool status = false;
+  try {
+    if ( save )
+      status = app->Save( stdDoc() ) == CDF_SS_OK;
+    else
+    {
+      TCollection_ExtendedString format, path( CAF_Tools::toExtString( fname ) );
+      app->Format( path, format );
+
+      if ( format.Length() )
+        stdDoc()->ChangeStorageFormat( format );
+
+      status = app->SaveAs( stdDoc(), path ) == CDF_SS_OK;
+    }
+  }
+  catch ( Standard_Failure ) {
+    status = false;
+  }
+
+  if ( status )
+    status = SUIT_Study::saveDocumentAs( fname );
+
+  if ( status )
+    myModifiedCnt = 0;
+
+  return status;
+}
+
+bool CAF_Study::openTransaction()
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+  bool res = true;
+  try {
+    if ( myStdDoc->HasOpenCommand() )
+      myStdDoc->AbortCommand();
+
+    myStdDoc->OpenCommand();
+  }
+  catch ( Standard_Failure ) {
+    res = false;
+  }
+
+  return res;
+}
+
+bool CAF_Study::abortTransaction()
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+  bool res = true;
+       try {
+    myStdDoc->AbortCommand();
+               update();
+  }
+  catch ( Standard_Failure ) {
+    res = false;
+  }
+  return res;
+}
+
+bool CAF_Study::commitTransaction( const QString& name )
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+  bool res = true;
+       try {
+    myStdDoc->CommitCommand();
+
+    if ( canUndo() )
+    {
+      Handle(TDF_Delta) d = myStdDoc->GetUndos().Last();
+                       if ( !d.IsNull() )
+        d->SetName( CAF_Tools::toExtString( name ) );
+    }
+  }
+  catch ( Standard_Failure ) {
+    res = false;
+  }
+  return res;
+}
+
+bool CAF_Study::hasTransaction() const
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+  return myStdDoc->HasOpenCommand();
+}
+
+/*!
+    Returns whether the document was saved in file. [ public ]
+*/
+bool CAF_Study::isSaved() const
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+  return myStdDoc->IsSaved();
+}
+
+/*!
+    Returns whether the document is modified. [ public ]
+*/
+bool CAF_Study::isModified() const
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+//  return myStdDoc->IsModified();
+  return myModifiedCnt;
+}
+
+/*!
+    Increments modification count. If 'undoable' is 'true', this modification
+    can be rolled back by 'undoModified' otherwise the document will be marked
+    as 'modiifed' until saved. [ protected ]
+*/
+void CAF_Study::doModified( bool undoable )
+{
+       if ( myStdDoc.IsNull() )
+    return;
+
+       myModifiedCnt++;
+
+    /*  Assumed that number of available undos / redos is NOT changed dynamically */
+       if ( !undoable )
+    myModifiedCnt += myStdDoc->GetAvailableUndos();
+}
+
+/*!
+    Decrements modification count. [ protected ]
+*/
+void CAF_Study::undoModified()
+{
+  myModifiedCnt--;
+}
+
+/*!
+    Clears modification count. [ public ]
+*/
+void CAF_Study::clearModified()
+{
+  myModifiedCnt = 0;
+}
+
+/*!
+    Undoes the last command. [ public ]
+*/
+bool CAF_Study::undo()
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+  try {
+    myStdDoc->Undo();
+    undoModified();     /* decrement modification counter */
+  }
+  catch ( Standard_Failure ) {
+               SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
+                             tr( "ERR_DOC_UNDO" ), tr ( "BUT_OK" ) );
+               return false;
+       }
+  return true;
+}
+
+/*!
+    Redoes the last undo. [ public ]
+*/
+bool CAF_Study::redo()
+{
+       if ( myStdDoc.IsNull() )
+    return false;
+
+  try {
+    myStdDoc->Redo();
+    doModified();      /* increment modification counter */
+  }
+  catch ( Standard_Failure ) {
+    SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
+                             tr( "ERR_DOC_REDO" ), tr ( "BUT_OK" ) );
+    return false;
+  }
+  return true;
+}
+
+/*!
+    Check if possible to perform 'undo' command. [ public ]
+*/
+bool CAF_Study::canUndo() const
+{
+  if ( myStdDoc.IsNull() )
+    return false;
+
+  return myStdDoc->GetAvailableUndos() > 0;
+}
+
+/*!
+    Check if possible to perform 'redo' command. [ public ]
+*/
+bool CAF_Study::canRedo() const
+{
+  if ( myStdDoc.IsNull() )
+    return false;
+
+  return myStdDoc->GetAvailableRedos() > 0;
+}
+
+/*!
+    Returns the list of names of 'undo' actions available. [ public ]
+*/
+QStringList CAF_Study::undoNames() const
+{
+  QStringList names;
+  if ( !myStdDoc.IsNull() )
+  {
+    for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetUndos() ); it.More(); it.Next() )
+      names.prepend( CAF_Tools::toQString( it.Value()->Name() ) );
+  }
+  return names;
+}
+
+/*!
+    Returns the list of names of 'redo' actions available. [ public ]
+*/
+QStringList CAF_Study::redoNames() const
+{
+  QStringList names;
+  if ( !myStdDoc.IsNull() )
+  {
+    for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetRedos() ); it.More(); it.Next() )
+      names.append( CAF_Tools::toQString( it.Value()->Name() ) );
+  }
+  return names;
+}
+
+/*!
+    Returns the standard OCAF application from owner application. [ protected ]
+*/
+Handle(TDocStd_Application) CAF_Study::stdApp() const
+{
+  Handle(TDocStd_Application) stdApp;
+  CAF_Application* app = cafApplication();
+  if ( app )
+    stdApp = app->stdApp();
+  return stdApp;
+}
+
+/*!
+    Returns the application casted to type CAF_Application. [ protected ]
+*/
+CAF_Application* CAF_Study::cafApplication() const
+{
+  return ::qt_cast<CAF_Application*>( application() );
+}
diff --git a/src/DDS/DDS.h b/src/DDS/DDS.h
new file mode 100644 (file)
index 0000000..35c38aa
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef DDS_H
+#define DDS_H
+
+#include <TCollection_AsciiString.hxx>
+
+#include <NCollection_DefineDataMap.hxx>
+#include <NCollection_DefineBaseCollection.hxx>
+
+#define UNIT_SYSTEM_SI "SI"
+
+typedef enum { DDS_MT_OK, DDS_MT_WARNING,
+               DDS_MT_ERROR, DDS_MT_ALARM,
+               DDS_MT_INFO, DDS_MT_NONE } DDS_MsgType;
+
+DEFINE_BASECOLLECTION(DDS_BaseColOfAsciiString,TCollection_AsciiString)
+
+#endif
diff --git a/src/DDS/DDS_DicGroup.cxx b/src/DDS/DDS_DicGroup.cxx
new file mode 100644 (file)
index 0000000..ac7f4ad
--- /dev/null
@@ -0,0 +1,130 @@
+#include "DDS_DicGroup.h"
+
+#include "DDS_Dictionary.h"
+
+#include <LDOMString.hxx>
+#include <LDOM_Element.hxx>
+
+#include <UnitsAPI.hxx>
+
+#include <TColStd_SequenceOfAsciiString.hxx>
+
+#include <Standard_Failure.hxx>
+#include <Standard_ErrorHandler.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(DDS_DicGroup, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_DicGroup, MMgt_TShared)
+
+DDS_DicGroup::DDS_DicGroup( const TCollection_AsciiString& name )
+: MMgt_TShared(),
+myName( name ),
+myActiveSystem( UNIT_SYSTEM_SI )
+{
+}
+
+DDS_DicGroup::DDS_DicGroup( const DDS_DicGroup& )
+{
+}
+
+TCollection_AsciiString DDS_DicGroup::GetName() const
+{
+  return myName;
+}
+
+void DDS_DicGroup::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystemSeq ) const
+{
+  theSystemSeq.Clear();
+  for ( UnitSystemMap::Iterator it( myUnitSystem ); it.More(); it.Next() )
+  {
+    if ( it.Key() == TCollection_AsciiString( UNIT_SYSTEM_SI ) )
+      theSystemSeq.Prepend( it.Key() );
+    else
+      theSystemSeq.Append( it.Key() );
+  }
+}
+
+TCollection_ExtendedString DDS_DicGroup::GetUnitSystemLabel( const TCollection_AsciiString& name ) const
+{
+  TCollection_ExtendedString aLabel;
+  if ( myUnitSystem.IsBound( name ) )
+    aLabel = myUnitSystem.Find( name );
+  return aLabel;
+}
+
+TCollection_AsciiString DDS_DicGroup::GetActiveUnitSystem() const
+{
+  return myActiveSystem;
+}
+
+void DDS_DicGroup::SetActiveUnitSystem( const TCollection_AsciiString& theSystem )
+{
+  if ( myUnitSystem.IsBound( theSystem ) )
+    myActiveSystem = theSystem;
+}
+
+void DDS_DicGroup::operator=( const DDS_DicGroup& )
+{
+}
+
+void DDS_DicGroup::FillDataMap( const LDOM_Element& theComponentData, const LDOM_Element& theDocElement )
+{
+  TCollection_AsciiString aCompName = theComponentData.getAttribute( DDS_Dictionary::KeyWord( "COMPONENT_NAME" ) );
+
+  LDOM_Element systems = theComponentData.GetChildByTagName( DDS_Dictionary::KeyWord( "UNIT_SYSTEMS" ) );
+  if ( !systems.isNull() )
+  {
+    LDOM_NodeList systemList = systems.getElementsByTagName( DDS_Dictionary::KeyWord( "UNIT_SYSTEM" ) );
+    for ( Standard_Integer i = 0; i < systemList.getLength(); i++ )
+    {
+      LDOM_Element aSystem = (const LDOM_Element &)systemList.item( i );
+      TCollection_AsciiString aName = aSystem.getAttribute( DDS_Dictionary::KeyWord( "UNIT_SYSTEM_NAME" ) );
+      TCollection_ExtendedString aLabel = aSystem.getAttribute( DDS_Dictionary::KeyWord( "UNIT_SYSTEM_LABEL" ) );
+
+      if ( aName.IsEmpty() )
+        continue;
+
+      if ( !myUnitSystem.IsBound( aName ) )
+        myUnitSystem.Bind( aName, aLabel );
+    }
+  }
+
+  if ( !myUnitSystem.IsBound( UNIT_SYSTEM_SI ) )
+  {
+    printf( "Warning: Mandatory unit system SI not defined in component: \"%s\". Added automaticaly", aCompName.ToCString() );
+    myUnitSystem.Bind( UNIT_SYSTEM_SI, TCollection_ExtendedString( "System international" ) );
+  }
+
+  TColStd_SequenceOfAsciiString unitSystems;
+  GetUnitSystems( unitSystems );
+
+  LDOM_NodeList aData = theComponentData.getElementsByTagName( DDS_Dictionary::KeyWord( "DATUM" ) );
+  if ( !aData.getLength() )
+    return;
+
+  for ( Standard_Integer i = 0; i < aData.getLength(); i++ )
+  {
+    LDOM_Element aQuantity = (const LDOM_Element&)aData.item( i );
+
+    // 1. Attributes (id,label,units?,format?,required?)
+    TCollection_AsciiString anID = aQuantity.getAttribute( DDS_Dictionary::KeyWord( "DATUM_ID" ) );
+    Handle(DDS_DicItem) aDicItem = new DDS_DicItem();
+
+    aDicItem->myComponent = this;
+    aDicItem->FillDataMap( anID, aQuantity, theComponentData, theDocElement, unitSystems );
+    myDataMap.Add( anID, aDicItem );
+  }
+}
+
+/*!
+  Returns DicItem with all attached data
+*/
+
+Handle(DDS_DicItem) DDS_DicGroup::GetDicItem( const TCollection_AsciiString& theID ) const
+{
+  Handle(DDS_DicItem) aDicItem;
+  // get dictionary item by id
+  if ( myDataMap.Contains( theID ) )
+    aDicItem = myDataMap.FindFromKey( theID );
+
+  return aDicItem;
+}
diff --git a/src/DDS/DDS_DicGroup.h b/src/DDS/DDS_DicGroup.h
new file mode 100644 (file)
index 0000000..d1c633f
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef DDS_DICGROUP_H
+#define DDS_DICGROUP_H
+
+#include "DDS.h"
+
+#include "DDS_DicItem.h"
+
+#include <MMgt_TShared.hxx>
+
+#include <TCollection_AsciiString.hxx>
+
+#include <NCollection_List.hxx>
+
+class LDOM_Element;
+class TColStd_SequenceOfAsciiString;
+
+DEFINE_STANDARD_HANDLE(DDS_DicGroup, MMgt_TShared)
+
+class DDS_DicGroup : public MMgt_TShared
+{
+public:
+  DDS_DicGroup( const TCollection_AsciiString& );
+
+  TCollection_AsciiString                    GetName() const;
+
+  Standard_EXPORT Handle(DDS_DicItem)        GetDicItem( const TCollection_AsciiString& ) const;
+
+  Standard_EXPORT void                       GetUnitSystems( TColStd_SequenceOfAsciiString& ) const;
+  Standard_EXPORT TCollection_ExtendedString GetUnitSystemLabel( const TCollection_AsciiString& ) const;
+
+  Standard_EXPORT TCollection_AsciiString    GetActiveUnitSystem() const;
+  Standard_EXPORT void                       SetActiveUnitSystem( const TCollection_AsciiString& );
+
+private:
+  DDS_DicGroup( const DDS_DicGroup& );
+
+  void                                       operator=( const DDS_DicGroup& );
+
+  void                                       FillDataMap( const LDOM_Element&, const LDOM_Element& );
+
+private:
+  typedef NCollection_DataMap<TCollection_AsciiString,
+                              TCollection_ExtendedString> UnitSystemMap;
+
+private:
+  TCollection_AsciiString                    myName;
+  DDS_IndexedDataMapOfDicItems               myDataMap;
+  UnitSystemMap                              myUnitSystem;
+  TCollection_AsciiString                    myActiveSystem;
+
+  friend class DDS_Dictionary;
+
+public:
+  DEFINE_STANDARD_RTTI(DDS_DicGroup)
+};
+
+DEFINE_BASECOLLECTION(DDS_BaseCollectionOfDicGroups, Handle(DDS_DicGroup))
+DEFINE_INDEXEDDATAMAP(DDS_IndexedDataMapOfDicGroups, DDS_BaseCollectionOfDicGroups,
+                      TCollection_AsciiString, Handle(DDS_DicGroup))
+
+#endif
diff --git a/src/DDS/DDS_DicItem.cxx b/src/DDS/DDS_DicItem.cxx
new file mode 100644 (file)
index 0000000..fd59f3c
--- /dev/null
@@ -0,0 +1,924 @@
+#include "DDS_DicItem.h"
+#include "DDS_Dictionary.h"
+
+#include <TColStd_SequenceOfInteger.hxx>
+#include <TColStd_SequenceOfExtendedString.hxx>
+
+#include <LDOM_Text.hxx>
+#include <LDOMString.hxx>
+#include <LDOM_Element.hxx>
+
+#include <UnitsAPI.hxx>
+#include <Units_Dimensions.hxx>
+
+#include <TColStd_MapOfReal.hxx>
+#include <TColStd_SequenceOfAsciiString.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(DDS_DicItem, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_DicItem, MMgt_TShared)
+
+DDS_DicItem::DDS_DicItem()
+: myType( 0 ),
+myDefValue( 0 ),
+myMax( 0 ),
+myMin( 0 ),
+myMinZoom( 0.1 ),
+myMaxZoom( 10 ),
+myZoomOrder( 2 )
+{
+}
+
+DDS_DicItem::DDS_DicItem( const DDS_DicItem& )
+{
+}
+
+void DDS_DicItem::operator=( const DDS_DicItem& )
+{
+}
+
+TCollection_AsciiString DDS_DicItem::GetId() const
+{
+  return myId;
+}
+
+DDS_DicItem::Type DDS_DicItem::GetType() const
+{
+  return (DDS_DicItem::Type)myType;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetLabel() const
+{
+  return myLabel;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetFilter() const
+{
+  return myFilter;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetRequired() const
+{
+  return myRequired;
+}
+
+DDS_MsgType DDS_DicItem::GetWarningLevel() const
+{
+  return (DDS_MsgType)myWarnLevel;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetLongDescription() const
+{
+  return myLongDescr;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetShortDescription() const
+{
+  return myShortDescr;
+}
+
+TCollection_AsciiString DDS_DicItem::GetComponent() const
+{
+  TCollection_AsciiString aCompName;
+  Handle(DDS_DicGroup) aComponent = Handle(DDS_DicGroup)::DownCast(myComponent);
+  if ( !aComponent.IsNull() )
+    aCompName = aComponent->GetName();
+  return aCompName;
+}
+
+TCollection_AsciiString DDS_DicItem::GetUnits() const
+{
+  return GetUnits( GetActiveUnitSystem() );
+}
+
+TCollection_AsciiString DDS_DicItem::GetUnits( const UnitSystem& theSystem ) const
+{
+  TCollection_AsciiString anUnits;
+  UnitData* unitData = GetUnitData( theSystem );
+  if ( unitData )
+    anUnits = unitData->myUnits;
+  return anUnits;
+}
+
+Standard_Real DDS_DicItem::GetMinValue() const
+{
+  return GetMinValue( GetActiveUnitSystem() );
+}
+
+Standard_Real DDS_DicItem::GetMinValue( const UnitSystem& theUnitsSystem ) const
+{
+  return FromSI( myMin, theUnitsSystem );
+}
+
+Standard_Real DDS_DicItem::GetMaxValue() const
+{
+  return GetMaxValue( GetActiveUnitSystem() );
+}
+
+Standard_Real DDS_DicItem::GetMaxValue( const UnitSystem& theUnitsSystem ) const
+{
+  return FromSI( myMax, theUnitsSystem );
+}
+
+Standard_Integer DDS_DicItem::GetPrecision() const
+{
+  return GetPrecision( GetActiveUnitSystem() );
+}
+
+Standard_Integer DDS_DicItem::GetPrecision( const UnitSystem& theSystem ) const
+{
+  Standard_Integer aRes = 0;
+  UnitData* unitData = GetUnitData( theSystem );
+  if ( unitData )
+    aRes = unitData->myPrecision;
+  return aRes;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetDefaultValue() const
+{
+  return GetDefaultValue( GetActiveUnitSystem() );
+}
+
+TCollection_ExtendedString DDS_DicItem::GetDefaultValue( const UnitSystem& theSystem ) const
+{
+  if ( !myDefString.Length() )
+    return myDefString;
+
+  TCollection_ExtendedString aStr;
+
+  switch ( myType )
+  {
+  case Float:
+  case Integer:
+    aStr = FromSI( myDefValue, theSystem );
+    break;
+  case List:
+  case String:
+    aStr = myDefString;
+    break;
+  default:
+    break;
+  }
+  return aStr;
+}
+
+TCollection_AsciiString DDS_DicItem::GetFormat( const Standard_Boolean theCanonical ) const
+{
+  return GetFormat( GetActiveUnitSystem(), theCanonical );
+}
+
+TCollection_AsciiString DDS_DicItem::GetFormat( const UnitSystem& theSystem,
+                                                const Standard_Boolean theCanonical ) const
+{
+  TCollection_AsciiString aFormat;
+  UnitData* unitData = GetUnitData( theSystem );
+  if ( unitData )
+    aFormat = unitData->myFormat;
+
+  if ( theCanonical && aFormat.Length() > 1 )
+  {
+    static TCollection_AsciiString f;
+    f = aFormat;
+    Standard_Boolean isRemoved = false;
+    while ( !isRemoved )
+    {
+      char ch = f.Value( f.Length() - 1 );
+      if ( ( ch != '%' && ch != '.' && !IsDigit( ch ) ) && f.Length() > 1 )
+        f.Remove( f.Length() - 1 );
+      else
+        isRemoved = true;
+    }
+    aFormat = f;
+  }
+
+  return aFormat;
+}
+
+/*!
+  Access valueList:name of the parameter. This string is void if the list is
+  not defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
+*/
+TCollection_ExtendedString DDS_DicItem::GetNameOfValues() const
+{
+  return myListName;
+}
+
+/*!
+  Access valueList of the parameter. This sequence is empty if the list is
+  not defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
+*/
+Standard_Boolean DDS_DicItem::GetListOfValues( Handle(TColStd_HArray1OfExtendedString)& theStrings,
+                                               Handle(TColStd_HArray1OfInteger)& theIntegers ) const
+{
+  theStrings  = myListRef;
+  theIntegers = myListRefID;
+  return !theIntegers.IsNull() && !theStrings.IsNull();
+}
+
+/*!
+  Access valueList of the parameter. This sequence is empty if the list is not
+  defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
+*/
+Standard_Boolean DDS_DicItem::GetListOfValues( Handle(TColStd_HArray1OfExtendedString)& theStrings,
+                                               Handle(TColStd_HArray1OfInteger)& theIntegers,
+                                               Handle(TColStd_HArray1OfExtendedString)& theIcons ) const
+{
+  theStrings  = myListRef;
+  theIntegers = myListRefID;
+  theIcons    = myListRefIcons;
+  return !theIntegers.IsNull() && !theStrings.IsNull() && !theIcons.IsNull();
+}
+
+Standard_Boolean DDS_DicItem::GetSpecialValues( TColStd_MapOfReal& theMap ) const
+{
+  theMap.Clear();
+  if ( !myListRef.IsNull() )
+  {
+    for ( Standard_Integer i = myListRef->Lower(); i <= myListRef->Upper(); i++ )
+    {
+      if ( myListRef->Value( i ).IsAscii() )
+      {
+        TCollection_AsciiString aStr( myListRef->Value( i ) );
+        if ( aStr.IsRealValue() )
+          theMap.Add( aStr.RealValue() );
+      }
+    }
+  }
+
+  return theMap.Extent() > 0;
+}
+
+/*!
+  Returns min value of lateral zooming
+*/
+Standard_Real DDS_DicItem::GetMinZoom() const
+{
+  return myMinZoom;
+}
+
+/*!
+  Returns Max Value of lateral zooming
+*/
+Standard_Real DDS_DicItem::GetMaxZoom() const
+{
+  return myMaxZoom;
+}
+
+/*!
+  Get Order of lateral zooming
+*/
+Standard_Real DDS_DicItem::GetZoomOrder() const
+{
+  return myZoomOrder;
+}
+
+Standard_Real DDS_DicItem::ToSI( const Standard_Real theVal ) const
+{
+  return ToSI( theVal, GetActiveUnitSystem() );
+}
+
+Standard_Real DDS_DicItem::FromSI( const Standard_Real theVal ) const
+{
+  return FromSI( theVal, GetActiveUnitSystem() );
+}
+
+/*!
+  Convert value to default SI units according to current units
+*/
+Standard_Real DDS_DicItem::ToSI( const Standard_Real theVal, const UnitSystem& theUnitsSystem ) const
+{
+  Standard_Real aRes = theVal;
+  UnitData* anUnitData = GetUnitData( theUnitsSystem );
+  if ( anUnitData )
+    aRes = anUnitData->myZero + aRes * anUnitData->myScale;
+  return aRes;
+}
+
+/*!
+  Convert value from default SI units according to current units
+*/
+Standard_Real DDS_DicItem::FromSI( const Standard_Real theVal, const UnitSystem& theUnitsSystem ) const
+{
+  Standard_Real aRes = theVal;
+  UnitData* anUnitData = GetUnitData( theUnitsSystem );
+  if ( anUnitData )
+    aRes = ( aRes - anUnitData->myZero ) / anUnitData->myScale;
+  return aRes;
+}
+
+/*!
+  Parse record in XML file and retrieve information relevant for this data dic item
+*/
+void DDS_DicItem::FillDataMap( TCollection_AsciiString theID, const LDOM_Element& theDatum,
+                               const LDOM_Element& theCompElement, const LDOM_Element& theDocElement,
+                               const TColStd_SequenceOfAsciiString& theSystems )
+{
+  TCollection_AsciiString aLabel    = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_LABEL" ) );
+  TCollection_AsciiString aFormat   = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_FORMAT" ) );
+  TCollection_AsciiString aFilter   = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_FILTER" ) );
+  TCollection_AsciiString aRequired = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_REQUIRED" ) );
+
+  TCollection_AsciiString aBaseKeyWord = DDS_Dictionary::KeyWord( "DATUM_UNITS" );
+
+  for ( Standard_Integer j = 1; j <= theSystems.Length(); j++ )
+  {
+    UnitSystem anUnitSystem = theSystems.Value( j );
+    if ( !anUnitSystem.Length() )
+      continue;
+
+    TCollection_AsciiString aUnitKeyword = anUnitSystem + aBaseKeyWord;
+
+    if ( !myUnitData.IsBound( anUnitSystem ) )
+      myUnitData.Bind( anUnitSystem, UnitData() );
+
+    UnitData& anUnitData = myUnitData.ChangeFind( anUnitSystem );
+    anUnitData.myUnits = theDatum.getAttribute( LDOMString( aUnitKeyword.ToCString() ) );
+  }
+
+  if ( theSystems.Length() && myUnitData.IsBound( theSystems.First() ) &&
+       !myUnitData.Find( theSystems.First() ).myUnits.Length() )
+  {
+    TCollection_AsciiString units = theDatum.getAttribute( LDOMString( aBaseKeyWord.ToCString() ) );
+    if ( units.Length() )
+      myUnitData.ChangeFind( theSystems.First() ).myUnits = units;
+  }
+
+  TCollection_AsciiString units;
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator iter( myUnitData ); iter.More() && units.IsEmpty(); iter.Next() )
+    units = iter.Value().myUnits;
+
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator itr( myUnitData ); itr.More(); itr.Next() )
+  {
+    UnitData& dataUnits = itr.ChangeValue();
+    if ( dataUnits.myUnits.IsEmpty() )
+      dataUnits.myUnits = units;
+  }
+  
+  // 2. Elements ( domain, description )
+  Standard_Real aRealMinV = 0;
+  Standard_Real aRealMaxV = 0;
+  Standard_Real aRealDefV = 0;
+
+  TCollection_AsciiString aType;
+
+  DDS_MsgType aWrongValue = DDS_MT_NONE;
+  DDS_DicItem::Type aEnumType = DDS_DicItem::Unknown;
+
+  TCollection_AsciiString aMinV;
+  TCollection_AsciiString aMaxV;
+  TCollection_AsciiString aDefV;
+  TCollection_AsciiString aListName;
+
+  TCollection_AsciiString aLongD;
+  TCollection_AsciiString aShortD;
+
+  TColStd_SequenceOfInteger aSeqOfValueID;
+  TColStd_SequenceOfExtendedString aSeqOfValue;
+  TColStd_SequenceOfExtendedString aSeqOfValueIconName;
+
+  // Presentation
+  Standard_Real aMinZoom   = 0;
+  Standard_Real aMaxZoom   = 0;
+  Standard_Real aZoomOrder = 0;
+
+  // Datum::Reports tags (if any)
+  LDOM_Element aWLev = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "WARNING_LEVEL" ) );
+  if ( !aWLev.isNull() )
+  {
+    TCollection_AsciiString aWrongValWL = aWLev.getAttribute( DDS_Dictionary::KeyWord( "WRONG_VALUE" ) );
+    if ( aWrongValWL.IsEqual( "Info" ) )
+      aWrongValue = DDS_MT_INFO;
+    else if ( aWrongValWL.IsEqual( "Warning" ) )
+      aWrongValue = DDS_MT_WARNING;
+    else if ( aWrongValWL.IsEqual( "Alarm" ) )
+      aWrongValue = DDS_MT_ALARM;
+    else if ( aWrongValWL.IsEqual( "Error" ) )
+      aWrongValue = DDS_MT_ERROR;
+  }
+
+  // Datum::Presentation
+  LDOM_Element aPrs = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "PRS" ) );
+  if ( !aPrs.isNull() )
+  {
+    LDOM_Element aLateralZoom = aPrs.GetChildByTagName( DDS_Dictionary::KeyWord( "LATERAL_ZOOM" ) );
+    if ( !aLateralZoom.isNull() )
+    {
+      TCollection_AsciiString aMinZoomStr   = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_MINV" ) );
+      TCollection_AsciiString aMaxZoomStr   = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_MAXV" ) );
+      TCollection_AsciiString aZoomOrderStr = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_ORDER" ) );
+      
+      aMinZoomStr.RemoveAll( ' ' );
+      if ( aMinZoomStr.IsRealValue() )
+        aMinZoom = aMinZoomStr.RealValue();
+
+      aMaxZoomStr.RemoveAll( ' ' );
+      if ( aMaxZoomStr.IsRealValue() )
+        aMaxZoom = aMaxZoomStr.RealValue();
+
+      aZoomOrderStr.RemoveAll( ' ' );
+      if ( aZoomOrderStr.IsRealValue() )
+        aZoomOrder = aZoomOrderStr.RealValue();
+    }
+  }
+
+  // Quantity::Domain record as the only child of that tag name
+  LDOM_Element aDomain = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "DY_DOMAIN" ) );
+  if ( !aDomain.isNull() )
+  {
+    LDOM_Element aValueDescr = aDomain.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_DESCR" ) );
+    if ( !aValueDescr.isNull() )
+    {
+      // read: valueDescr? (type?,min?,max?,default?)
+      aType = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_TYPE" ) );
+      if ( aType.IsEqual( "String" ) )
+        aEnumType = String;
+      else if ( aType.IsEqual( "Float" ) )
+        aEnumType = Float;
+      else if ( aType.IsEqual( "Integer" ) )
+        aEnumType = Integer;
+
+      aMinV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_MINV" ) );
+      aMinV.RemoveAll( ' ' );
+      if ( aMinV.IsRealValue() )
+        aRealMinV = aMinV.RealValue();
+      aMaxV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_MAXV" ) );
+      aMaxV.RemoveAll( ' ' );
+      if ( aMaxV.IsRealValue() )
+        aRealMaxV = aMaxV.RealValue();
+      aDefV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_DEFV" ) );
+      aDefV.RemoveAll( ' ' );
+      if ( aDefV.IsRealValue() )
+        aRealDefV = aDefV.RealValue();
+
+      TCollection_AsciiString aSpecVal = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_SPEC" ) );
+      Split( aSpecVal, myListRef );
+    }
+    else
+    {
+      //  read: listRef? (list?)
+      LDOM_Element aListRef = aDomain.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST_REF" ) );
+      if ( !aListRef.isNull() )
+      {
+        aType = "List";
+        aEnumType = List;                       
+        LDOMString aListId = aListRef.getAttribute( DDS_Dictionary::KeyWord( "VLR_LIST" ) );
+        aDefV = aListRef.getAttribute( DDS_Dictionary::KeyWord( "VD_DEFV" ) );
+        aDefV.RemoveAll( ' ' );
+        LDOM_Element foundListItem;
+        for ( LDOM_Element aListItem = theCompElement.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST" ) );
+              aListItem != NULL && foundListItem == NULL; aListItem = aListItem.GetSiblingByTagName() )
+        {
+          if ( aListItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_ID" ) ).equals( aListId ) )
+            foundListItem = aListItem;
+
+        }
+        for ( LDOM_Element aLstItem = theDocElement.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST" ) );
+              aLstItem != NULL && foundListItem == NULL; aLstItem = aLstItem.GetSiblingByTagName() )
+        {
+          if ( aLstItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_ID" ) ).equals( aListId ) )
+            foundListItem = aLstItem;
+        }
+
+        if ( foundListItem != NULL )
+        {
+          //  The appropriate list of values is found: store the list name
+          aListName = foundListItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_NAME" ) );
+          //  Iteration through the list of values
+          LDOM_Element aListItemValue = foundListItem.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUE" ) );
+          while ( aListItemValue != NULL )
+          {
+            // read value ID
+            TCollection_AsciiString aListValueID = aListItemValue.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUEID" ) );
+            if ( aListValueID.IsIntegerValue() )
+            {
+              //  Read the text in the element "value"
+              LDOM_Text aListItemTxt = (const LDOM_Text&)aListItemValue.getFirstChild();
+              if ( !aListItemTxt.isNull() )
+              {
+                // adding ID and text value to sequence
+                aSeqOfValueID.Append( aListValueID.IntegerValue() );
+                aSeqOfValue.Append( aListItemTxt.getData() );
+                // adding icon file name (optional) to sequence
+                TCollection_ExtendedString aListValueIcon = aListItemValue.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUEICON" ) );
+                aSeqOfValueIconName.Append( aListValueIcon );
+              }
+              aListItemValue = aListItemValue.GetSiblingByTagName();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Quantity::Description record as the only child of that tag name
+  LDOM_Element aDescr = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "DESCR" ) );
+  if ( !aDescr.isNull() )
+  {
+    // short description (#PCDATA)*
+    LDOM_Element aShDescr = aDescr.GetChildByTagName( DDS_Dictionary::KeyWord( "SHORT_D" ) );
+    if ( !aShDescr.isNull() )
+    {
+      // text is always a sub-node of element, containing it
+      LDOM_Text aShDescrTxt = (const LDOM_Text&)aShDescr.getFirstChild();
+      if ( !aShDescrTxt.isNull() )
+        aShortD = aShDescrTxt.getData();
+    }
+
+    // long description (#PCDATA)*
+    LDOM_Element aLDescr = aDescr.GetChildByTagName( DDS_Dictionary::KeyWord( "LONG_D" ) );
+    if ( !aLDescr.isNull() )
+    {
+      // text is always a sub-node of element, containing it
+      LDOM_Text aLDescrTxt = (const LDOM_Text&)aLDescr.getFirstChild();
+      if ( !aLDescrTxt.isNull() )
+        aLongD = aLDescrTxt.getData();
+    }
+  }
+
+  NCollection_DataMap<UnitSystem, Handle(Units_Dimensions)> aDimMap;
+
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
+  {
+    UnitData& anUnitData = it.ChangeValue();
+
+    // check units
+    anUnitData.myZero  = 0.;
+    anUnitData.myScale = 1.;
+    try {
+      Standard_CString aUnitDataStr;
+      aUnitDataStr = (Standard_CString)anUnitData.myUnits.ToCString();
+      if ( anUnitData.myUnits.ToCString()[0] && strcmp( anUnitData.myUnits.ToCString(), "%" ) )
+      {
+        Handle(Units_Dimensions) aDim;
+        anUnitData.myZero  = UnitsAPI::AnyToSI( 0.0, aUnitDataStr, aDim );
+        anUnitData.myScale = UnitsAPI::AnyToSI( 1.0, aUnitDataStr, aDim ) - anUnitData.myZero;
+        UnitsAPI::AnyFromSI( 1.0, aUnitDataStr );
+        if ( !aDimMap.IsBound( it.Key() ) )
+          aDimMap.Bind( it.Key(), aDim );
+      }
+      else if ( anUnitData.myUnits.ToCString()[0] ) // treat '%' as unit with scale 100
+        anUnitData.myScale = 0.01;
+    }
+         catch( Standard_Failure ) {
+      anUnitData.myUnits.Clear();
+    }
+
+    Handle(Units_Dimensions) aPrev;
+    Standard_Boolean aStatus = Standard_True;
+    for ( NCollection_DataMap<UnitSystem, Handle(Units_Dimensions)>::Iterator itr( aDimMap );
+          itr.More() && aStatus; itr.Next() )
+    {
+      if ( itr.Value().IsNull() )
+        continue;
+
+      if ( aPrev.IsNull() )
+        aPrev = itr.Value();
+
+      aStatus = aPrev->IsEqual( itr.Value() );
+    }
+
+    if ( !aStatus )
+      printf( "Error in DataDictionary: Different dimensions for %s item", theID.ToCString() );
+  }
+
+  myId                = theID;
+  myType              = aEnumType;
+  myWarnLevel         = aWrongValue;
+  myLabel             = aLabel.ToCString();
+  myFilter            = aFilter.ToCString();
+  myLongDescr         = aLongD.ToCString();
+  myShortDescr        = aShortD.ToCString();
+  myMin               = aRealMinV;
+  myMax               = aRealMaxV;
+  myDefValue          = aRealDefV;
+  myDefString         = aDefV.ToCString();
+  myRequired          = aRequired.ToCString();
+  myListName          = aListName.ToCString();
+  myMinZoom           = aMinZoom;
+  myMaxZoom           = aMaxZoom;
+  myZoomOrder         = aZoomOrder;
+
+  // prepare formats
+  PrepareFormats( aFormat );
+
+  const Standard_Integer aLength = aSeqOfValue.Length();
+  if ( aLength > 0 )
+  {
+    myListRef      = new TColStd_HArray1OfExtendedString( 1, aLength );
+    myListRefID    = new TColStd_HArray1OfInteger( 1, aLength );
+    myListRefIcons = new TColStd_HArray1OfExtendedString( 1, aLength );
+    for ( Standard_Integer i = aLength; i > 0; i-- )
+    {
+      myListRef->ChangeValue( i ) = aSeqOfValue.Value( i );
+      myListRefID->ChangeValue( i ) = aSeqOfValueID.Value( i );
+      myListRefIcons->ChangeValue( i ) = aSeqOfValueIconName.Value( i );
+    }
+  }
+
+  if ( myType == List && myDefString == "" && !myListRef.IsNull() && myListRef->Length() > 0 )
+    myDefString = myListRef->Value( myListRef->Lower() );
+}
+
+/*!
+  Returns default formats for each unit systems
+*/
+void DDS_DicItem::GetDefaultFormat()
+{
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
+  {
+    UnitData& anUnitData = it.ChangeValue();
+
+    switch ( myType )
+    {
+    case Integer:
+      anUnitData.myFormat = "%d";
+      break;
+    case Float:
+      anUnitData.myFormat = "%g";
+      break;
+    case String:
+    default:
+      anUnitData.myFormat.Clear();
+      break;;
+    }
+  }
+}
+
+/*!
+  Returns format for the string
+*/
+void DDS_DicItem::GetStringFormat( const TCollection_AsciiString& theFlags,
+                                   const TCollection_AsciiString& theWidth,
+                                   const TCollection_AsciiString& thePrecision,
+                                   const TCollection_AsciiString& theTypePrefix,
+                                   TCollection_AsciiString& theFormat )
+{
+  theFormat = "%";
+  theFormat += theFlags;
+  theFormat += theWidth;
+
+  if ( !thePrecision.IsEmpty() ) 
+  {
+    theFormat += ".";
+    theFormat += thePrecision;
+  }
+
+  theFormat += theTypePrefix;
+  theFormat += "s";
+}
+
+/*!
+  Returns format for the integer
+*/
+void DDS_DicItem::GetIntegerFormat( const TCollection_AsciiString& theFlags,
+                                    const TCollection_AsciiString& theWidth,
+                                    const TCollection_AsciiString& thePrecision,
+                                    const TCollection_AsciiString& theTypePrefix,
+                                    const Standard_Character theType,
+                                    TCollection_AsciiString& theFormat )
+{
+  Standard_Integer aPrecision = 0;
+  if ( !thePrecision.IsEmpty() )
+    aPrecision = thePrecision.IntegerValue();
+  Standard_Integer aWidth = 0;
+
+  if ( !theWidth.IsEmpty() )
+    aWidth = theWidth.IntegerValue();
+
+  if ( !thePrecision.IsEmpty() && aPrecision < 0 )
+  {
+    // possible value 0.1 will be 10.0
+    aWidth -= aPrecision;
+    aPrecision = 0;
+  }
+
+  if ( !thePrecision.IsEmpty() && aPrecision > ( aWidth - 2 ) )
+    aWidth = aPrecision + 2;
+
+  theFormat = "%";
+
+  theFormat += theFlags;
+  if ( !theWidth.IsEmpty() )
+    theFormat += aWidth;
+
+  theFormat += theTypePrefix;
+  theFormat += theType;
+}
+
+/*!
+  Returns format for the float
+*/
+void DDS_DicItem::GetFloatFormat( const TCollection_AsciiString& theFlags,
+                                  const TCollection_AsciiString& theWidth,
+                                  const TCollection_AsciiString& thePrecision,
+                                  const TCollection_AsciiString& theTypePrefix,
+                                  const Standard_Character theType,
+                                  TCollection_AsciiString& theFormat )
+{
+  Standard_Integer aPrecision = 0;
+  if ( !thePrecision.IsEmpty() )
+    aPrecision = thePrecision.IntegerValue();
+  Standard_Integer aWidth = 0;
+
+  if (!theWidth.IsEmpty() )
+    aWidth = theWidth.IntegerValue();
+
+  if (!thePrecision.IsEmpty() && aPrecision < 0 )
+  {
+    // possible value 0.1 will be 10.0
+    aWidth -= aPrecision;
+    aPrecision = 0;
+  }
+
+  if ( !thePrecision.IsEmpty() && aPrecision > ( aWidth - 2 ) )
+  {
+    aWidth = aPrecision + 2;
+  }
+
+  theFormat = "%";
+  theFormat += theFlags;
+
+  if ( !theWidth.IsEmpty() ) 
+    theFormat += aWidth;
+
+  if ( !thePrecision.IsEmpty() ) 
+  {
+    theFormat += ".";
+    theFormat += aPrecision;
+  }
+
+  theFormat += theTypePrefix;
+  theFormat += theType;
+}
+
+/*!
+  Prepares three formants for each unit systems
+*/
+void DDS_DicItem::PrepareFormats( const TCollection_AsciiString&  theFormat )
+{
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
+  {
+    UnitData& anUnitData = it.ChangeValue();
+
+    anUnitData.myFormat = theFormat;
+    anUnitData.myPrecision = 0;
+  }
+
+  TCollection_AsciiString aPrecisionStr;
+  if ( theFormat.IsEmpty() && myType == List )
+    return;
+
+  // checking % presenting
+  if ( *theFormat.ToCString() != '%' )
+  {
+    GetDefaultFormat();
+    return;
+  }
+
+  TCollection_AsciiString aStr = ( theFormat.ToCString() + 1 );
+  Standard_Character aType = aStr.Value( aStr.Length() );
+
+  if ( ( aType != 's' && myType == String ) ||
+       ( aType != 'd' && myType == Integer ) ||
+       ( aType != 'f' && aType != 'g' && aType != 'e' && aType != 'G' && aType != 'E' && myType == Float ) )
+  {
+    GetDefaultFormat();
+    return;
+  }
+
+  // removing type character
+  aStr.Trunc( aStr.Length() - 1 );
+
+  TCollection_AsciiString aFlags;
+  while ( !aStr.IsEmpty() && aStr.Value( 1 ) != '.' && ( aStr.Value( 1 ) < '0' || aStr.Value( 1 ) > '9' ) )
+  {
+    aFlags = aFlags + aStr.Value( 1 );
+    aStr.Remove( 1 );
+  }
+
+  Standard_Integer aPos = 1;
+  while ( aPos <= aStr.Length() && ( aStr.Value( aPos ) == '.' ||
+          ( aStr.Value( aPos ) >= '0' && aStr.Value( aPos ) <= '9' ) ) )
+    aPos++;
+
+  TCollection_AsciiString aTypePrefix;
+  if ( aPos <= aStr.Length() )
+  {
+    aTypePrefix = aStr.SubString( aPos, aStr.Length() );
+    aStr.Trunc( aPos - 1 );
+  }
+
+  Standard_Integer aBasePrecision = 0;
+
+  // taking width and precision
+  TCollection_AsciiString aPrecision;
+
+  aPos = aStr.Search( "." );
+  if ( aPos >= 0 ) 
+  {
+    // aPrecision is defined
+    aPrecision = aStr.Split( aPos );
+    aStr.Remove( aStr.Length() );
+    if ( !aPrecision.IsEmpty() )
+    {
+      if ( !aPrecision.IsIntegerValue() ) 
+      { 
+        GetDefaultFormat();
+        return;
+      }
+      else
+      {
+        aPrecisionStr  = aPrecision;
+        aBasePrecision = aPrecision.IntegerValue();
+      }
+    }
+  }
+
+  if ( !aStr.IsEmpty() && !aStr.IsIntegerValue() )
+  {
+    GetDefaultFormat();
+    return;
+  }
+
+  NCollection_DataMap<UnitSystem, UnitData>::Iterator itr;
+
+  switch ( myType )
+  {
+  case String:
+    for ( itr.Initialize( myUnitData ); itr.More(); itr.Next() )
+    {
+      if ( aType != 'f' && aType != 'g' && aType != 'e' && aType != 'G' && aType != 'E' )
+        GetStringFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, itr.ChangeValue().myFormat );
+    }
+    break;
+  case Float:
+  case Integer:
+    for ( itr.Initialize( myUnitData ); itr.More(); itr.Next() )
+    {
+      UnitData& anUnitData = itr.ChangeValue();
+      Standard_Integer aAmendment =
+        (Standard_Integer)log10( 10.0 / DDS_Dictionary::FromSI( 10.0, anUnitData.myUnits.ToCString() ) );
+      anUnitData.myPrecision = aBasePrecision + aAmendment;
+      aPrecisionStr = TCollection_AsciiString( anUnitData.myPrecision );
+
+      // create a formats
+      if ( myType == Integer )
+        GetIntegerFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, aType, anUnitData.myFormat );
+      else
+        GetFloatFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, aType, anUnitData.myFormat );
+    }
+    break;
+  default:;
+    GetDefaultFormat();
+    break;
+  }
+}
+
+void DDS_DicItem::Split( const TCollection_AsciiString& theStr, Handle(TColStd_HArray1OfExtendedString)& aRes )
+{
+  aRes.Nullify();
+
+  if ( theStr.Length() > 0 )
+  {
+    TCollection_AsciiString aStr = theStr;
+    TColStd_SequenceOfAsciiString aSeq;
+    Standard_Integer anIndex = aStr.SearchFromEnd( (Standard_CString)" " );
+    while( anIndex > 1 )
+    {
+      TCollection_AsciiString tmpStr = aStr.Split( anIndex - 1 );
+      tmpStr.RemoveAll( ( Standard_Character )' ' );
+      if ( tmpStr.Length() > 0 )
+        aSeq.Append( tmpStr );
+      anIndex = aStr.SearchFromEnd( (Standard_CString)" " );
+    }
+
+    aStr.RemoveAll( ( Standard_Character )' ' );
+    if ( aStr.Length() > 0 )
+      aSeq.Append( aStr );
+
+    if ( aSeq.Length() > 0 )
+    {
+      aRes = new TColStd_HArray1OfExtendedString( 1, aSeq.Length() );
+      for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
+        aRes->ChangeValue( i ) = aSeq( i );
+    }
+  }
+}
+
+DDS_DicItem::UnitData* DDS_DicItem::GetUnitData( const UnitSystem& sys ) const
+{
+  UnitData* unit = 0;
+
+  if ( myUnitData.IsBound( sys ) )
+    unit = (UnitData*)&myUnitData.Find( sys );
+
+  return unit;
+}
+
+DDS_DicItem::UnitSystem DDS_DicItem::GetActiveUnitSystem() const
+{
+  UnitSystem aSystem;
+  Handle(DDS_DicGroup) aComponent = Handle(DDS_DicGroup)::DownCast(myComponent);
+  if ( !aComponent.IsNull() )
+    aSystem = aComponent->GetActiveUnitSystem();
+  return aSystem;
+}
diff --git a/src/DDS/DDS_DicItem.h b/src/DDS/DDS_DicItem.h
new file mode 100644 (file)
index 0000000..8711494
--- /dev/null
@@ -0,0 +1,235 @@
+#ifndef DDS_DICITEM_H
+#define DDS_DICITEM_H
+
+#include "DDS.h"
+
+#include <MMgt_TShared.hxx>
+
+#include <TCollection_AsciiString.hxx>
+
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_HArray1OfExtendedString.hxx>
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_DefineIndexedDataMap.hxx>
+
+class LDOM_Element;
+class DDS_Dictionary;
+class TColStd_MapOfReal;
+class TColStd_SequenceOfInteger;
+class TColStd_SequenceOfAsciiString;
+class TColStd_SequenceOfExtendedString;
+
+//  Class, containing all information about one parameter:
+//  unique    : id
+//  obligative: label, type, short description, required
+//  optional  : format, units,
+//              min value, max value, default value.
+
+class DDS_DicItem : public MMgt_TShared
+{
+public:
+  enum Type { String, Float, Integer, List, Unknown };
+
+  // This struct is intended for map of Format, Units, Precision and Scale
+  struct UnitData
+  {
+    Standard_Real           myZero;
+    Standard_Real           myScale;
+    TCollection_AsciiString myUnits;
+    TCollection_AsciiString myFormat;
+    Standard_Integer        myPrecision;
+  };
+
+  typedef TCollection_AsciiString UnitSystem;
+
+public:
+  DDS_DicItem();
+
+  Standard_EXPORT TCollection_AsciiString    GetId() const;
+  // to access Type of the parameter
+
+  Standard_EXPORT DDS_DicItem::Type          GetType() const;
+  // to access Type of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetLabel() const;
+  // to access Label (name) of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetFilter() const;
+  // to access filter (regexp) for the parameter values
+
+  Standard_EXPORT TCollection_ExtendedString GetRequired() const;
+  // to access Required of the parameter
+
+  Standard_EXPORT DDS_MsgType                GetWarningLevel() const;
+  // to access wrong value warning level of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetLongDescription() const;
+  // to access Long Description of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetShortDescription() const;
+  // to access Short Description of the parameter
+
+  Standard_EXPORT TCollection_AsciiString    GetComponent() const;
+
+  Standard_EXPORT TCollection_AsciiString    GetUnits() const;
+  Standard_EXPORT TCollection_AsciiString    GetUnits( const UnitSystem& ) const;
+  // returns units for indicated unit systems
+
+  Standard_EXPORT TCollection_ExtendedString GetDefaultValue() const;
+  Standard_EXPORT TCollection_ExtendedString GetDefaultValue( const UnitSystem& ) const;
+  // to access Default Value of the parameter
+
+  Standard_EXPORT Standard_Real              GetMinValue() const;
+  Standard_EXPORT Standard_Real              GetMinValue( const UnitSystem& ) const;
+  // get Min Value of the parameter, either in specified unit system or in internal units (basic SI)
+
+  Standard_EXPORT Standard_Real              GetMaxValue() const;
+  Standard_EXPORT Standard_Real              GetMaxValue( const UnitSystem& ) const;
+  // get Max Value of the parameter, either in specified unit system or in internal units (basic SI)
+
+  Standard_EXPORT Standard_Integer           GetPrecision() const;
+  Standard_EXPORT Standard_Integer           GetPrecision( const UnitSystem& ) const;
+  // returns precision for indicated unit systems
+
+  Standard_EXPORT TCollection_AsciiString    GetFormat( const Standard_Boolean = Standard_True ) const;
+  Standard_EXPORT TCollection_AsciiString    GetFormat( const UnitSystem&,
+                                                        const Standard_Boolean = Standard_True ) const;
+  // returns format for indicated unit systems
+
+  Standard_EXPORT TCollection_ExtendedString GetNameOfValues() const;
+  // to access valueList:name of the parameter.
+  // This string is void if the list is not defined - then use other properties:
+  //    Type, DefaultValue, MaxValue, MinValue
+
+  Standard_EXPORT Standard_Boolean           GetListOfValues( Handle(TColStd_HArray1OfExtendedString)&,
+                                                              Handle(TColStd_HArray1OfInteger)& ) const;
+  // to access valueList of the parameter
+  // This sequence is empty if the list not defined - then use other properties:
+  //    Type, DefaultValue, MaxValue, MinValue
+
+  Standard_EXPORT Standard_Boolean           GetListOfValues( Handle(TColStd_HArray1OfExtendedString)&,
+                                                              Handle(TColStd_HArray1OfInteger)&,
+                                                              Handle(TColStd_HArray1OfExtendedString)& ) const;
+  // to access valueList of the parameter
+  // This sequence is empty if the list not defined - then use other properties:
+  //    Type, DefaultValue, MaxValue, MinValue
+
+  Standard_EXPORT Standard_Boolean           GetSpecialValues( TColStd_MapOfReal& ) const;
+  // get values from specVal
+
+  Standard_EXPORT Standard_Real              GetMinZoom() const;
+  // get Min Value of lateral zooming
+
+  Standard_EXPORT Standard_Real              GetMaxZoom() const;
+  // get Max Value of lateral zooming
+
+  Standard_EXPORT Standard_Real              GetZoomOrder() const;
+  // get Order of lateral zooming
+
+  Standard_EXPORT Standard_Real ToSI( const Standard_Real ) const;
+  Standard_EXPORT Standard_Real FromSI( const Standard_Real ) const;
+
+  Standard_EXPORT Standard_Real ToSI( const Standard_Real, const UnitSystem& ) const;
+  Standard_EXPORT Standard_Real FromSI( const Standard_Real, const UnitSystem& ) const;
+  // convert value to and from default SI units according to current units
+
+private:
+  DDS_DicItem( const DDS_DicItem& );
+  // Copy constructor
+
+  void                                       operator=( const DDS_DicItem& );
+  // Assignment operator
+
+  void                                       FillDataMap( TCollection_AsciiString, const LDOM_Element&,
+                                                          const LDOM_Element&, const LDOM_Element&,
+                                                          const TColStd_SequenceOfAsciiString& );
+  // prepares formants for each unit systems
+
+
+  void                                       PrepareFormats( const TCollection_AsciiString& );
+  // prepares three formats for each unit systems
+
+  void                                       GetDefaultFormat();
+  // returns three default formants for each unit systems
+
+  UnitSystem                                 GetActiveUnitSystem() const;
+
+  void                                       GetStringFormat( const TCollection_AsciiString&,
+                                                              const TCollection_AsciiString&,
+                                                              const TCollection_AsciiString&,
+                                                              const TCollection_AsciiString&,
+                                                              TCollection_AsciiString& );
+  // returns format for the string
+
+  void                                       GetIntegerFormat( const TCollection_AsciiString&,
+                                                               const TCollection_AsciiString&,
+                                                               const TCollection_AsciiString&,
+                                                               const TCollection_AsciiString&,
+                                                               const Standard_Character,
+                                                               TCollection_AsciiString& );
+  // returns format for the integer
+
+  void                                       GetFloatFormat( const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString&,
+                                                             const Standard_Character,
+                                                             TCollection_AsciiString& );
+  // returns format for the float
+
+  void                                       Split( const TCollection_AsciiString&,
+                                                    Handle(TColStd_HArray1OfExtendedString)& );
+
+  UnitData*                                  GetUnitData( const UnitSystem& ) const;
+
+private:
+  TCollection_AsciiString                    myId;
+  TCollection_ExtendedString                 myLabel;
+  TCollection_ExtendedString                 myFilter;
+  TCollection_ExtendedString                 myRequired;
+
+  Standard_Integer                           myType;
+  Standard_Integer                           myWarnLevel;
+
+  TCollection_ExtendedString                 myLongDescr;
+  TCollection_ExtendedString                 myShortDescr;
+
+  Standard_Real                              myMax;
+  Standard_Real                              myMin;
+  Standard_Real                              myDefValue;
+  TCollection_ExtendedString                 myDefString;
+
+  // valueList
+  TCollection_ExtendedString                 myListName;
+
+  Handle(TColStd_HArray1OfExtendedString)    myListRef;
+  Handle(TColStd_HArray1OfInteger)           myListRefID;
+  Handle(TColStd_HArray1OfExtendedString)    myListRefIcons;
+
+  // presentation
+  Standard_Real                              myMinZoom;
+  Standard_Real                              myMaxZoom;
+  Standard_Real                              myZoomOrder;
+
+  Handle(Standard_Transient)                 myComponent;
+
+  // unitData
+  NCollection_DataMap<UnitSystem, UnitData>  myUnitData;
+
+  friend class DDS_DicGroup;
+
+public:
+  // Declaration of CASCADE RTTI
+  DEFINE_STANDARD_RTTI(DDS_DicItem)
+};
+
+// Definition of HANDLE object using Standard_DefineHandle.hxx
+DEFINE_STANDARD_HANDLE(DDS_DicItem, MMgt_TShared)
+
+// Container class XMLTools_IndexedDataMapOfDicItems (map of handles)
+DEFINE_BASECOLLECTION(DDS_BaseCollectionOfDicItems, Handle(DDS_DicItem))
+DEFINE_INDEXEDDATAMAP(DDS_IndexedDataMapOfDicItems, DDS_BaseCollectionOfDicItems,
+                      TCollection_AsciiString, Handle(DDS_DicItem))
+
+#endif
diff --git a/src/DDS/DDS_Dictionary.cxx b/src/DDS/DDS_Dictionary.cxx
new file mode 100644 (file)
index 0000000..3656a39
--- /dev/null
@@ -0,0 +1,232 @@
+#include "DDS_Dictionary.h"
+
+#include "DDS_KeyWords.h"
+
+#include <LDOMString.hxx>
+#include <LDOMParser.hxx>
+
+#include <UnitsAPI.hxx>
+
+#include <TColStd_SequenceOfInteger.hxx>
+#include <TColStd_SequenceOfAsciiString.hxx>
+#include <TColStd_SequenceOfExtendedString.hxx>
+
+#include <NCollection_Map.hxx>
+
+#include <Standard_Failure.hxx>
+#include <Standard_ErrorHandler.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(DDS_Dictionary, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_Dictionary, MMgt_TShared)
+
+DDS_Dictionary::DDS_Dictionary()
+: MMgt_TShared()
+{
+}
+
+DDS_Dictionary::DDS_Dictionary( const DDS_Dictionary& )
+{
+}
+
+void DDS_Dictionary::operator=( const DDS_Dictionary& )
+{
+}
+
+void DDS_Dictionary::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystems ) const
+{
+  theSystems.Clear();
+
+  NCollection_Map<TCollection_AsciiString> aMap;
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent(); i++ )
+  {
+    TColStd_SequenceOfAsciiString theSeq;
+    myGroupMap.FindFromIndex( i )->GetUnitSystems( theSeq );
+    for ( Standard_Integer s = 1; s <= theSeq.Length(); s++ )
+    {
+      if ( aMap.Contains( theSeq.Value( s ) ) )
+        continue;
+
+      theSystems.Append( theSeq.Value( s ) );
+      aMap.Add( theSeq.Value( s ) );
+    }
+  }
+
+}
+
+void DDS_Dictionary::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystems,
+                                     const TCollection_AsciiString& theComponent ) const
+{
+  theSystems.Clear();
+  if ( myGroupMap.Contains( theComponent ) )
+    myGroupMap.FindFromKey( theComponent )->GetUnitSystems( theSystems );
+}
+
+TCollection_ExtendedString DDS_Dictionary::GetUnitSystemLabel( const TCollection_AsciiString& theSystem ) const
+{
+  TCollection_ExtendedString aLabel;
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent() && !aLabel.Length(); i++ )
+    aLabel = myGroupMap.FindFromIndex( i )->GetUnitSystemLabel( theSystem );
+  return aLabel;
+}
+
+TCollection_ExtendedString DDS_Dictionary::GetUnitSystemLabel( const TCollection_AsciiString& theSystem,
+                                                               const TCollection_AsciiString& theComponent ) const
+{
+  TCollection_ExtendedString aLabel;
+  if ( myGroupMap.Contains( theComponent ) )
+    aLabel = myGroupMap.FindFromKey( theComponent )->GetUnitSystemLabel( theSystem );
+  return aLabel;
+}
+
+TCollection_AsciiString DDS_Dictionary::GetActiveUnitSystem() const
+{
+  TCollection_AsciiString aSystem;
+  if ( myGroupMap.Extent() )
+    aSystem = myGroupMap.FindFromIndex( 1 )->GetActiveUnitSystem();
+  return aSystem;
+}
+
+TCollection_AsciiString DDS_Dictionary::GetActiveUnitSystem( const TCollection_AsciiString& theComponent ) const
+{
+  TCollection_AsciiString aSystem;
+  if ( myGroupMap.Contains( theComponent ) )
+    aSystem = myGroupMap.FindFromKey( theComponent )->GetActiveUnitSystem();
+  return aSystem;
+}
+
+void DDS_Dictionary::SetActiveUnitSystem( const TCollection_AsciiString& theSystem )
+{
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent(); i++ )
+    myGroupMap.FindFromIndex( i )->SetActiveUnitSystem( theSystem );
+}
+
+void DDS_Dictionary::SetActiveUnitSystem( const TCollection_AsciiString& theSystem,
+                                          const TCollection_AsciiString& theComponent )
+{
+  if ( myGroupMap.Contains( theComponent ) )
+    myGroupMap.FindFromKey( theComponent )->SetActiveUnitSystem( theSystem );
+}
+
+/*!
+  Returns the instance of dictionary. Create instance if it is NULL.
+*/
+Handle(DDS_Dictionary) DDS_Dictionary::Get()
+{
+  static Handle(DDS_Dictionary) sDictionary;
+
+  if ( sDictionary.IsNull() )
+    sDictionary = new DDS_Dictionary();
+
+  return sDictionary;
+}
+
+Standard_Boolean DDS_Dictionary::Load( const TCollection_AsciiString theFileName )
+{
+  static NCollection_Map<TCollection_AsciiString> _LoadMap;
+
+  if ( _LoadMap.Contains( theFileName ) )
+    return Standard_True;
+
+  Handle(DDS_Dictionary) aDic = Get();
+  if ( aDic.IsNull() )
+    return Standard_False;
+
+  LDOMParser aParser;
+  if ( aParser.parse( theFileName.ToCString() ) )
+    return Standard_False;
+
+  LDOM_Document aDoc = aParser.getDocument();
+  LDOM_Element aDocElement = aDoc.getDocumentElement();
+  for ( LDOM_Element aComponentElem = aDocElement.GetChildByTagName( KeyWord( "COMPONENT" ) );
+        !aComponentElem.isNull(); aComponentElem = aComponentElem.GetSiblingByTagName() )
+    aDic->FillDataMap( aComponentElem, aDocElement );
+
+  _LoadMap.Add( theFileName );
+
+  return Standard_True;
+}
+
+LDOMString DDS_Dictionary::KeyWord( const TCollection_AsciiString& key )
+{
+  LDOMString keyWord;
+  Handle(DDS_KeyWords) aKeyWords = DDS_KeyWords::Get();
+  if ( !aKeyWords.IsNull() )
+  {
+    TCollection_AsciiString aStr = aKeyWords->GetKeyWord( key );
+    if ( aStr.Length() )
+      keyWord = LDOMString( aStr.ToCString() );
+  }
+  return keyWord;
+}
+
+/*!
+  Returns DicItem from specified group with all attached data
+*/
+
+Handle(DDS_DicItem) DDS_Dictionary::GetDicItem( const TCollection_AsciiString& theID,
+                                                const TCollection_AsciiString& theGroup ) const
+{
+  Handle(DDS_DicItem) aDicItem;
+  Handle(DDS_DicGroup) aDicGroup;
+  if ( myGroupMap.Contains( theGroup ) )
+    aDicGroup = myGroupMap.FindFromKey( theGroup );
+  if ( !aDicGroup.IsNull() )
+    aDicItem = aDicGroup->GetDicItem( theID );
+  return aDicItem;
+}
+
+/*!
+  Returns DicItem with all attached data
+*/
+
+Handle(DDS_DicItem) DDS_Dictionary::GetDicItem( const TCollection_AsciiString& theID ) const
+{
+  Handle(DDS_DicItem) aDicItem;
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent() && aDicItem.IsNull(); i++ )
+    aDicItem = myGroupMap.FindFromIndex( i )->GetDicItem( theID );
+  return aDicItem;
+}
+
+void DDS_Dictionary::FillDataMap( const LDOM_Element& theComponentData, const LDOM_Element& theDocElement )
+{
+  TCollection_AsciiString aCompName = theComponentData.getAttribute( KeyWord( "COMPONENT_NAME" ) );
+  if ( !myGroupMap.Contains( aCompName ) )
+    myGroupMap.Add( aCompName, new DDS_DicGroup( aCompName ) );
+  Handle(DDS_DicGroup) aDicGroup = myGroupMap.FindFromKey( aCompName );
+  aDicGroup->FillDataMap( theComponentData, theDocElement );
+  myGroupMap.Add( aCompName, aDicGroup );
+}
+
+Standard_Real DDS_Dictionary::ToSI( const Standard_Real theValue, const Standard_CString theUnits )
+{
+  Standard_Real aRetValue = theValue;
+  if ( theUnits && *theUnits && strcmp( theUnits, "%" ) )
+  {
+    try {
+      aRetValue = UnitsAPI::AnyToSI( theValue, theUnits );
+    }
+    catch( Standard_Failure ) {
+    }
+  }
+  else if ( theUnits && *theUnits )
+    aRetValue = theValue / 100.0;
+
+  return aRetValue;
+}
+
+Standard_Real DDS_Dictionary::FromSI( const Standard_Real theValue, const Standard_CString theUnits )
+{
+  Standard_Real aRetValue = theValue;
+  if ( theUnits && *theUnits && strcmp( theUnits, "%" ) )
+  {
+    try {
+      aRetValue = UnitsAPI::AnyFromSI( theValue, theUnits );
+    }
+    catch( Standard_Failure ) {
+    }
+  }
+  else if ( theUnits && *theUnits )
+    aRetValue = theValue * 100.0;
+
+  return aRetValue;
+}
diff --git a/src/DDS/DDS_Dictionary.h b/src/DDS/DDS_Dictionary.h
new file mode 100644 (file)
index 0000000..d58a15f
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef DDS_DICTIONARY_H
+#define DDS_DICTIONARY_H
+
+#include "DDS_DicGroup.h"
+
+#include <LDOMString.hxx>
+
+#include <MMgt_TShared.hxx>
+
+class LDOM_Element;
+class TCollection_AsciiString;
+
+DEFINE_STANDARD_HANDLE(DDS_Dictionary, MMgt_TShared)
+
+//  Class to provide information about used parameters,
+//  reading them from 'xml' file
+class DDS_Dictionary : public MMgt_TShared
+{
+public:
+  Standard_EXPORT static Handle(DDS_Dictionary)  Get();
+
+  // Return instance of data dictionary. Create instance if it is NULL.
+
+  Standard_EXPORT Handle(DDS_DicItem)            GetDicItem( const TCollection_AsciiString& ) const;
+  Standard_EXPORT Handle(DDS_DicItem)            GetDicItem( const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString& ) const;
+
+  Standard_EXPORT void                           GetUnitSystems( TColStd_SequenceOfAsciiString& ) const;
+  Standard_EXPORT void                           GetUnitSystems( TColStd_SequenceOfAsciiString&,
+                                                                 const TCollection_AsciiString& ) const;
+  Standard_EXPORT TCollection_ExtendedString     GetUnitSystemLabel( const TCollection_AsciiString& ) const;
+  Standard_EXPORT TCollection_ExtendedString     GetUnitSystemLabel( const TCollection_AsciiString&,
+                                                                     const TCollection_AsciiString& ) const;
+  Standard_EXPORT TCollection_AsciiString        GetActiveUnitSystem() const;
+  Standard_EXPORT TCollection_AsciiString        GetActiveUnitSystem( const TCollection_AsciiString& ) const;
+  Standard_EXPORT void                           SetActiveUnitSystem( const TCollection_AsciiString& );
+  Standard_EXPORT void                           SetActiveUnitSystem( const TCollection_AsciiString&,
+                                                                      const TCollection_AsciiString& );
+
+
+  static Standard_EXPORT Standard_Boolean        Load( const TCollection_AsciiString );
+
+  static Standard_EXPORT Standard_Real           ToSI( const Standard_Real, const Standard_CString );
+  static Standard_EXPORT Standard_Real           FromSI( const Standard_Real, const Standard_CString );
+
+  static Standard_EXPORT LDOMString              KeyWord( const TCollection_AsciiString& );
+
+private:
+  DDS_Dictionary();
+  DDS_Dictionary( const DDS_Dictionary& );
+
+  void                                           operator=( const DDS_Dictionary& );
+
+  // prepares formants for each unit systems
+  void                                           FillDataMap( const LDOM_Element&, const LDOM_Element& );
+
+private:
+  DDS_IndexedDataMapOfDicGroups                  myGroupMap;
+
+public:
+  DEFINE_STANDARD_RTTI(DDS_Dictionary)
+};
+
+#endif
diff --git a/src/DDS/DDS_KeyWords.cxx b/src/DDS/DDS_KeyWords.cxx
new file mode 100644 (file)
index 0000000..2f53d2a
--- /dev/null
@@ -0,0 +1,83 @@
+#include "DDS_KeyWords.h"
+
+IMPLEMENT_STANDARD_HANDLE(DDS_KeyWords, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_KeyWords, MMgt_TShared)
+
+DDS_KeyWords::DDS_KeyWords()
+: MMgt_TShared()
+{
+  SetKeyWord( "D_URI",                "dictionary" );
+
+  SetKeyWord( "COMPONENT",            "component" );
+  SetKeyWord( "COMPONENT_NAME",       "name" );
+
+  SetKeyWord( "UNIT_SYSTEMS",         "unitSystems" );
+  SetKeyWord( "UNIT_SYSTEM",          "system" );
+  SetKeyWord( "UNIT_SYSTEM_NAME",     "name" );
+  SetKeyWord( "UNIT_SYSTEM_LABEL",    "label" );
+
+  SetKeyWord( "DATUM",                "datum" );
+  SetKeyWord( "DATUM_ID",             "id" );
+  SetKeyWord( "DATUM_LABEL",          "label" );
+  SetKeyWord( "DATUM_UNITS",          "units" );
+  SetKeyWord( "DATUM_FORMAT",         "format" );
+  SetKeyWord( "DATUM_FILTER",         "filter" );
+  SetKeyWord( "DATUM_REQUIRED",       "required" );
+
+  SetKeyWord( "VALUE_LIST",           "valueList" );
+  SetKeyWord( "VALUE_LIST_ID",        "listid" );
+  SetKeyWord( "VALUE_LIST_NAME",      "name" );
+  SetKeyWord( "VALUE_LIST_TYPE",      "type" );
+  SetKeyWord( "VALUE_LIST_VALUE",     "value" );
+  SetKeyWord( "VALUE_LIST_VALUEID",   "id" );
+  SetKeyWord( "VALUE_LIST_VALUEICON", "icon" );
+
+  SetKeyWord( "DY_DOMAIN",            "domain" );
+  SetKeyWord( "WARNING_LEVEL",        "warningLevel" );
+  SetKeyWord( "WRONG_VALUE",          "wrongValue" );
+  SetKeyWord( "VALUE_DESCR",          "valueDescr" );
+  SetKeyWord( "VALUE_LIST_REF",       "listRef" );
+
+  SetKeyWord( "DESCR",                "description" );
+  SetKeyWord( "LONG_D",               "longDescr" );
+  SetKeyWord( "SHORT_D",              "shortDescr" );
+
+  SetKeyWord( "VD_TYPE",              "type" );
+  SetKeyWord( "VD_DEFV",              "default" );
+  SetKeyWord( "VD_MAXV",              "max" );
+  SetKeyWord( "VD_MINV",              "min" );
+  SetKeyWord( "VD_SPEC",              "specVal" );
+  SetKeyWord( "VLR_LIST",             "list" );
+  SetKeyWord( "PRS",                  "presentation" );
+  SetKeyWord( "LATERAL_ZOOM",         "lateralZoom" );
+  SetKeyWord( "LZ_MINV",              "min" );
+  SetKeyWord( "LZ_MAXV",              "max" );
+  SetKeyWord( "LZ_ORDER",             "order" );
+}
+
+Handle(DDS_KeyWords) DDS_KeyWords::Get()
+{
+  static Handle(DDS_KeyWords) keyWords;
+
+  if ( keyWords.IsNull() )
+    keyWords = new DDS_KeyWords();
+
+  return keyWords;
+}
+
+TCollection_AsciiString DDS_KeyWords::GetKeyWord( const TCollection_AsciiString& key ) const
+{
+  TCollection_AsciiString keyWord;
+  if ( myKeyWord.IsBound( key ) )
+    keyWord = myKeyWord.Find( key );
+  return keyWord;
+}
+
+void DDS_KeyWords::SetKeyWord( const TCollection_AsciiString& key,
+                               const TCollection_AsciiString& keyWord )
+{
+  if ( myKeyWord.IsBound( key ) )
+    myKeyWord.UnBind( key );
+
+  myKeyWord.Bind( key, keyWord );
+}
diff --git a/src/DDS/DDS_KeyWords.h b/src/DDS/DDS_KeyWords.h
new file mode 100644 (file)
index 0000000..2c1faf9
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef DDS_KEYWORDS_H
+#define DDS_KEYWORDS_H
+
+#include "DDS.h"
+
+#include <MMgt_TShared.hxx>
+
+#include <NCollection_DataMap.hxx>
+
+DEFINE_STANDARD_HANDLE(DDS_KeyWords, MMgt_TShared)
+
+class TCollection_AsciiString;
+
+class DDS_KeyWords: public MMgt_TShared
+{
+public:
+  Standard_EXPORT static Handle(DDS_KeyWords) Get();
+
+  Standard_EXPORT TCollection_AsciiString     GetKeyWord( const TCollection_AsciiString& ) const;
+  Standard_EXPORT void                        SetKeyWord( const TCollection_AsciiString&,
+                                                          const TCollection_AsciiString& );
+
+private:
+  DDS_KeyWords();
+
+private:
+  typedef NCollection_DataMap<TCollection_AsciiString,
+                              TCollection_AsciiString> KeyWordMap;
+
+private:
+  KeyWordMap                                  myKeyWord;
+
+public:
+  DEFINE_STANDARD_RTTI(DDS_KeyWords)
+};
+
+#endif
diff --git a/src/DDS/Makefile.in b/src/DDS/Makefile.in
new file mode 100755 (executable)
index 0000000..a3b9eb8
--- /dev/null
@@ -0,0 +1,34 @@
+#  File   : Makefile.in
+#  Author : Alexander SOLOVYOV (OCN)
+#  Module : DDS
+#  $Header: /home/server/cvs/GUI/GUI_SRC/src/DDS/Makefile.in
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+@COMMENCE@
+
+# header files 
+EXPORT_HEADERS= DDS.h \
+       DDS_DicGroup.h \
+       DDS_DicItem.h \
+       DDS_Dictionary.h \
+       DDS_KeyWords.h
+                    
+# Libraries targets
+LIB = libDDS.la
+
+LIB_SRC= DDS_DicGroup.cxx \
+       DDS_DicItem.cxx \
+       DDS_Dictionary.cxx \
+       DDS_KeyWords.cxx
+
+CPPFLAGS+= $(OCC_INCLUDES)
+
+LDFLAGS+= $(CAS_KERNEL) $(CAS_OCAF)
+
+@CONCLUDE@
+
+
diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx
new file mode 100644 (file)
index 0000000..50f5fe5
--- /dev/null
@@ -0,0 +1,1955 @@
+// File:      LightApp_Application.cxx
+// Created:   6/20/2005 18:39:45 PM
+// Author:    Natalia Donis
+// Copyright (C) CEA 2005
+
+#include "PythonConsole_PyInterp.h" // WARNING! This include must be the first!
+
+#include "LightApp_Application.h"
+#include "LightApp_WidgetContainer.h"
+#include "LightApp_Module.h"
+#include "LightApp_DataModel.h"
+#include "LightApp_Study.h"
+#include "LightApp_Preferences.h"
+#include "LightApp_PreferencesDlg.h"
+#include "LightApp_ModuleDlg.h"
+#include "LightApp_AboutDlg.h"
+
+#include "LightApp_OBFilter.h"
+
+#include "LightApp_GLSelector.h"
+#include "LightApp_OBSelector.h"
+#include "LightApp_OCCSelector.h"
+#include "LightApp_VTKSelector.h"
+#include "LightApp_SelectionMgr.h"
+
+#include <CAM_Module.h>
+#include <CAM_DataModel.h>
+#include <CAM_Study.h>
+#include <STD_TabDesktop.h>
+
+#include <SUIT_Session.h>
+#include <SUIT_Study.h>
+#include <SUIT_FileDlg.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Tools.h>
+#include <SUIT_Accel.h>
+
+#include <QtxMRUAction.h>
+#include <QtxDockAction.h>
+#include <QtxToolBar.h>
+
+#include <LogWindow.h>
+#include <OB_Browser.h>
+#include <OB_ListView.h>
+#include <PythonConsole_PyConsole.h>
+
+#include <GLViewer_Viewer.h>
+#include <GLViewer_ViewManager.h>
+
+#include <Plot2d_ViewManager.h>
+#include <Plot2d_ViewModel.h>
+#include <SPlot2d_ViewModel.h>
+
+#include <OCCViewer_ViewManager.h>
+#include <SOCC_ViewModel.h>
+
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewManager.h>
+#include <VTKViewer_ViewModel.h>
+
+#include <SUPERVGraph_ViewModel.h>
+#include <SUPERVGraph_ViewFrame.h>
+#include <SUPERVGraph_ViewManager.h>
+
+#include <QtxWorkstack.h>
+
+#include <qdir.h>
+#include <qimage.h>
+#include <qstring.h>
+#include <qwidget.h>
+#include <qstringlist.h>
+#include <qfile.h>
+#include <qapplication.h>
+#include <qmap.h>
+#include <qstatusbar.h>
+#include <qthread.h>
+#include <qobjectlist.h>
+#include <qcombobox.h>
+#include <qinputdialog.h>
+#include <qmessagebox.h>
+
+#define FIRST_HELP_ID 1000000
+
+#include "SALOME_InteractiveObject.hxx"
+#include "SALOME_ListIO.hxx"
+
+static const char* imageEmptyIcon[] = {
+"20 20 1 1",
+".     c None",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"....................",
+"...................."};
+
+/*!Create new instance of LightApp_Application.*/
+extern "C" LIGHTAPP_EXPORT SUIT_Application* createApplication()
+{
+  return new LightApp_Application();
+}
+
+LightApp_Preferences* LightApp_Application::_prefs_ = 0;
+
+/*
+  Class       : LightApp_Application
+  Description : Application containing LightApp module
+*/
+
+/*!Constructor.*/
+LightApp_Application::LightApp_Application()
+: CAM_Application( false ),
+myPrefs( 0 )
+{
+  STD_TabDesktop* desk = new STD_TabDesktop();
+
+  setDesktop( desk );
+
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  QPixmap aLogo = aResMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
+
+  desktop()->setIcon( aLogo );
+  desktop()->setDockableMenuBar( true );
+  desktop()->setDockableStatusBar( false );
+
+  // base logo (salome itself)
+  desktop()->addLogo( "_app_base",  aResMgr->loadPixmap( "LightApp", tr( "APP_BASE_LOGO" ), false ) );
+  // extra logo (salome-based application)
+  desktop()->addLogo( "_app_extra", aResMgr->loadPixmap( "LightApp", tr( "APP_EXTRA_LOGO" ), false ) );
+
+  clearViewManagers();
+
+  mySelMgr = new LightApp_SelectionMgr( this );
+
+  myAccel = new SUIT_Accel( desktop() );
+  myAccel->setActionKey( SUIT_Accel::PanLeft,     CTRL+Key_Left,     OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::PanRight,    CTRL+Key_Right,    OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::PanUp,       CTRL+Key_Up,       OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::PanDown,     CTRL+Key_Down,     OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::ZoomIn,      CTRL+Key_Plus,     OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::ZoomOut,     CTRL+Key_Minus,    OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::ZoomFit,     CTRL+Key_Asterisk, OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateLeft,  ALT+Key_Left,      OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right,     OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateUp,    ALT+Key_Up,        OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateDown,  ALT+Key_Down,      OCCViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::PanLeft,     CTRL+Key_Left,     VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::PanRight,    CTRL+Key_Right,    VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::PanUp,       CTRL+Key_Up,       VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::PanDown,     CTRL+Key_Down,     VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::ZoomIn,      CTRL+Key_Plus,     VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::ZoomOut,     CTRL+Key_Minus,    VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::ZoomFit,     CTRL+Key_Asterisk, VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateLeft,  ALT+Key_Left,      VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right,     VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateUp,    ALT+Key_Up,        VTKViewer_Viewer::Type() );
+  myAccel->setActionKey( SUIT_Accel::RotateDown,  ALT+Key_Down,      VTKViewer_Viewer::Type() );
+
+  connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) );
+}
+
+/*!Destructor.
+ *\li Save window geometry.
+ *\li Save desktop geometry.
+ *\li Save resource maneger.
+ *\li Delete selection manager.
+ */
+LightApp_Application::~LightApp_Application()
+{
+  saveWindowsGeometry();
+
+  if ( resourceMgr() )
+  {
+    if ( desktop() )
+      desktop()->saveGeometry( resourceMgr(), "desktop" );
+    resourceMgr()->save();
+  }
+  delete mySelMgr;
+}
+
+/*!Start application.*/
+void LightApp_Application::start()
+{
+  if ( desktop() )
+    desktop()->loadGeometry( resourceMgr(), "desktop" );
+
+  CAM_Application::start();
+
+  QAction* a = action( ViewWindowsId );
+  if ( a && a->inherits( "QtxDockAction" ) )
+    ((QtxDockAction*)a)->setAutoPlace( true );
+
+  updateWindows();
+  updateViewManagers();
+
+  putInfo( "" );
+  desktop()->statusBar()->message( "" );
+}
+
+/*!Gets application name.*/
+QString LightApp_Application::applicationName() const
+{
+  return tr( "APP_NAME" );
+}
+
+/*!Gets application version.*/
+QString LightApp_Application::applicationVersion() const
+{
+  static QString _app_version;
+
+  if ( _app_version.isEmpty() )
+  {
+    QString resVersion = tr( "APP_VERSION" );
+    if ( resVersion != "APP_VERSION" )
+    {
+      _app_version = resVersion;
+    }
+    else
+    {
+      QString path( ::getenv( "GUI_ROOT_DIR" ) );
+      if ( !path.isEmpty() )
+        path += QDir::separator();
+      path += QString( "bin/salome/VERSION" );
+
+      QFile vf( path );
+      if ( vf.open( IO_ReadOnly ) )
+      {
+        QString line;
+       vf.readLine( line, 1024 );
+       vf.close();
+
+       if ( !line.isEmpty() )
+        {
+         while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
+           line.remove( line.length() - 1, 1 );
+
+         int idx = line.findRev( ":" );
+         if ( idx != -1 )
+           _app_version = line.mid( idx + 1 ).stripWhiteSpace();
+        }
+      }
+    }
+  }
+  return _app_version;  
+}
+
+/*!Load module by \a name.*/
+CAM_Module* LightApp_Application::loadModule( const QString& name )
+{
+  CAM_Module* mod = CAM_Application::loadModule( name );
+  if ( mod )
+  {
+    connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) );
+    connect( this, SIGNAL( studySaved() ),  mod, SLOT( onModelSaved() ) );
+    connect( this, SIGNAL( studyClosed() ), mod, SLOT( onModelClosed() ) );
+  }
+  return mod;
+}
+
+/*!Activate module by \a modName*/
+bool LightApp_Application::activateModule( const QString& modName )
+{
+  QString actName;
+  CAM_Module* prevMod = activeModule();
+
+  if ( prevMod )
+    actName = prevMod->moduleName();
+
+  if ( actName == modName )
+    return true;
+
+  putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) );  
+
+  saveWindowsGeometry();
+
+  bool status = CAM_Application::activateModule( modName );
+
+  updateModuleActions();
+
+  putInfo( "" );  
+
+  if ( !status )
+    return false;
+
+  updateWindows();
+  updateViewManagers();
+
+  return true;
+}
+
+bool LightApp_Application::useStudy(const QString& theName)
+{
+  createEmptyStudy();
+  LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
+  bool res = false;
+  if (aStudy)
+    res = aStudy->loadDocument( theName );
+  updateDesktopTitle();
+  updateCommandsStatus();
+  return res;
+}
+
+/*!Gets selection manager.*/
+LightApp_SelectionMgr* LightApp_Application::selectionMgr() const
+{
+  return mySelMgr;
+}
+
+/*!Create actions:*/
+void LightApp_Application::createActions()
+{
+  STD_Application::createActions();
+
+  SUIT_Desktop* desk = desktop();
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+
+  //! Preferences
+  createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIconSet(),
+               tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ),
+               CTRL+Key_F, desk, false, this, SLOT( onPreferences() ) );
+
+  //! Help for modules
+  int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
+  int helpModuleMenu = createMenu( tr( "MEN_DESK_MODULE_HELP" ), helpMenu, -1, 0 );
+  createMenu( separator(), helpMenu, -1, 1 );
+
+  QStringList aModuleList;
+  modules( aModuleList, false );
+
+  int id = LightApp_Application::UserID + FIRST_HELP_ID;
+  // help for KERNEL and GUI
+  QCString dir;
+  QString aFileName;
+  QString root;
+  QAction* a;
+  if (dir = getenv("GUI_ROOT_DIR")) {
+    aFileName = "GUI_index_v3.1.0.html";
+    root = Qtx::addSlash( Qtx::addSlash(dir) +  Qtx::addSlash("doc") +  Qtx::addSlash("salome") );
+    if ( QFileInfo( root + aFileName ).exists() ) {
+      a = createAction( id, tr( QString("Kernel & GUI Help") ), QIconSet(),
+                       tr( QString("Kernel && GUI Help") ),
+                       tr( QString("Kernel & GUI Help") ),
+                       0, desk, false, this, SLOT( onHelpContentsModule() ) );
+      a->setName( QString("GUI") );
+      createMenu( a, helpModuleMenu, -1 );
+      id++;
+    }
+  }
+  // help for other existing modules
+  QStringList::Iterator it;
+  for ( it = aModuleList.begin(); it != aModuleList.end(); ++it )
+  {
+    if ( (*it).isEmpty() )
+      continue;
+
+    QString modName = moduleName( *it );
+    aFileName = modName + "_index_v3.1.0.html";
+    
+    if (dir = getenv( modName + "_ROOT_DIR")) {
+      root = Qtx::addSlash( Qtx::addSlash(dir) +  Qtx::addSlash("doc") +  Qtx::addSlash("salome") );
+      if ( QFileInfo( root + aFileName ).exists() ) {
+
+       QAction* a = createAction( id, tr( moduleTitle(modName) + QString(" Help") ), QIconSet(),
+                                  tr( moduleTitle(modName) + QString(" Help") ),
+                                  tr( moduleTitle(modName) + QString(" Help") ),
+                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
+       a->setName( modName );
+       createMenu( a, helpModuleMenu, -1 );
+       id++;
+      }
+    }
+  }
+
+  //! MRU
+  QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), desk );
+  connect( mru, SIGNAL( activated( QString ) ), this, SLOT( onMRUActivated( QString ) ) );
+  registerAction( MRUId, mru );
+
+  // default icon for neutral point ('SALOME' module)
+  QPixmap defIcon = resMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
+  if ( defIcon.isNull() )
+    defIcon = QPixmap( imageEmptyIcon );
+
+  //! default icon for any module
+  QPixmap modIcon = resMgr->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), false );
+  if ( modIcon.isNull() )
+    modIcon = QPixmap( imageEmptyIcon );
+
+  QToolBar* modTBar = new QtxToolBar( true, desk );
+  modTBar->setLabel( tr( "INF_TOOLBAR_MODULES" ) );
+
+  QActionGroup* modGroup = new QActionGroup( this );
+  modGroup->setExclusive( true );
+  modGroup->setUsesDropDown( true );
+
+  a = createAction( -1, tr( "APP_NAME" ), defIcon, tr( "APP_NAME" ),
+                    tr( "PRP_APP_MODULE" ), 0, desk, true );
+  modGroup->add( a );
+  myActions.insert( QString(), a );
+
+  QMap<QString, QString> iconMap;
+  moduleIconNames( iconMap );
+
+  const int iconSize = 20;
+
+  modGroup->addTo( modTBar );
+  QObjectList *l = modTBar->queryList( "QComboBox" );
+  QObjectListIt oit( *l );
+  while ( QObject* obj = oit.current() ) {
+    QComboBox* cb = (QComboBox*)obj;
+    if ( cb ) cb->setFocusPolicy( QWidget::NoFocus );
+    ++oit;
+  }
+  delete l;
+  
+   modTBar->addSeparator();
+
+  QStringList modList;
+  modules( modList, false );
+
+  for ( it = modList.begin(); it != modList.end(); ++it )
+  {
+    if ( (*it).isEmpty() )
+      continue;
+
+    QString iconName;
+    if ( iconMap.contains( *it ) )
+      iconName = iconMap[*it];
+
+    QString modName = moduleName( *it );
+
+    QPixmap icon = resMgr->loadPixmap( modName, iconName, false );
+    if ( icon.isNull() )
+      icon = modIcon;
+
+    icon.convertFromImage( icon.convertToImage().smoothScale( iconSize, iconSize, QImage::ScaleMin ) );
+
+    QAction* a = createAction( -1, *it, icon, *it, tr( "PRP_MODULE" ).arg( *it ), 0, desk, true );
+    a->addTo( modTBar );
+    modGroup->add( a );
+
+    myActions.insert( *it, a );
+  }
+
+  SUIT_Tools::simplifySeparators( modTBar );
+
+  // New window
+  int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, 100 );
+  int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 );
+  createMenu( separator(), windowMenu, -1, 1 );
+
+  QMap<int, int> accelMap;
+  accelMap[NewGLViewId]  = ALT+Key_G;
+  accelMap[NewPlot2dId]  = ALT+Key_P;
+  accelMap[NewOCCViewId] = ALT+Key_O;
+  accelMap[NewVTKViewId] = ALT+Key_K;
+
+  for ( id = NewGLViewId; id <= NewVTKViewId; id++ )
+  {
+    QAction* a = createAction( id, tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ), QIconSet(),
+                              tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
+                              tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
+                              accelMap.contains( id ) ? accelMap[id] : 0, desk, false, this, SLOT( onNewWindow() ) );
+    createMenu( a, newWinMenu, -1 );
+  }
+
+  createAction( RenameId, tr( "TOT_RENAME" ), QIconSet(), tr( "MEN_DESK_RENAME" ), tr( "PRP_RENAME" ),
+               SHIFT+Key_R, desk, false, this, SLOT( onRenameWindow() ) );
+  createMenu( RenameId, windowMenu, -1 );
+
+  connect( modGroup, SIGNAL( selected( QAction* ) ), this, SLOT( onModuleActivation( QAction* ) ) );
+
+  int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
+  createMenu( PreferencesId, fileMenu, 15, -1 );
+  createMenu( separator(), fileMenu, -1, 15, -1 );
+
+  /*
+  createMenu( separator(), fileMenu, -1, 100, -1 );
+  createMenu( MRUId, fileMenu, 100, -1 );
+  createMenu( separator(), fileMenu, -1, 100, -1 );
+  */
+}
+
+/*!On module activation action.*/
+void LightApp_Application::onModuleActivation( QAction* a )
+{
+  if ( !a )
+    return;
+
+  QString modName = a->menuText();
+  if ( modName == tr( "APP_NAME" ) )
+    modName = QString::null;
+
+  // Force user to create/open a study before module activation
+  QMap<QString, QString> iconMap;
+  moduleIconNames( iconMap );
+  QPixmap icon = resourceMgr()->loadPixmap( moduleName( modName ), iconMap[ modName ], false );
+  if ( icon.isNull() )
+    icon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module
+
+  bool cancelled = false;
+  while ( !modName.isEmpty() && !activeStudy() && !cancelled ){
+    LightApp_ModuleDlg aDlg( desktop(), modName, icon );
+    int res = aDlg.exec();
+
+    switch ( res ){
+    case 1:
+      onNewDoc();
+      break;
+    case 2:
+      onOpenDoc();
+      break;
+    case 3:
+      //onLoadStudy();
+      //break;
+    case 0:
+    default:
+      putInfo( tr("INF_CANCELLED") );
+      myActions[QString()]->setOn( true );
+      cancelled = true;
+    }
+  }
+
+  if ( !cancelled )
+    activateModule( modName );
+}
+
+/*!Default module activation.*/
+QString LightApp_Application::defaultModule() const
+{
+  QStringList aModuleNames;
+  modules( aModuleNames, false ); // obtain a complete list of module names for the current configuration
+  //! If there's the one and only module --> activate it automatically
+  //! TODO: Possible improvement - default module can be taken from preferences
+  return aModuleNames.count() > 1 ? "" : ( aModuleNames.count() ? aModuleNames.first() : "" );
+}
+
+/*!On new window slot.*/
+void LightApp_Application::onNewWindow()
+{
+  const QObject* obj = sender();
+  if ( !obj || !obj->inherits( "QAction" ) )
+    return;
+
+  QString type;
+  int id = actionId( (QAction*)obj );
+  switch ( id )
+  {
+  case NewGLViewId:
+    type = GLViewer_Viewer::Type();
+    break;
+  case NewPlot2dId:
+    type = Plot2d_Viewer::Type();
+    break;
+  case NewOCCViewId:
+    type = OCCViewer_Viewer::Type();
+    break;
+  case NewVTKViewId:
+    type = VTKViewer_Viewer::Type();
+    break;
+  }
+
+  if ( !type.isEmpty() )
+    createViewManager( type );
+}
+
+//=======================================================================
+//  name    : onNewDoc
+/*! Purpose : SLOT. Create new document*/
+//=======================================================================
+void LightApp_Application::onNewDoc()
+{
+  SUIT_Study* study = activeStudy();
+
+  saveWindowsGeometry();
+
+  CAM_Application::onNewDoc();
+
+  if ( !study ) // new study will be create in THIS application
+  {
+    updateWindows();
+    updateViewManagers();
+  }
+}
+
+//=======================================================================
+// name    : onOpenDoc
+/*! Purpose : SLOT. Open new document*/
+//=======================================================================
+void LightApp_Application::onOpenDoc()
+{
+  SUIT_Study* study = activeStudy();
+  saveWindowsGeometry();
+
+  CAM_Application::onOpenDoc();
+
+  if ( !study ) // new study will be create in THIS application
+  {
+    updateWindows();
+    updateViewManagers();
+  }
+}
+
+#include "SUIT_MessageBox.h"
+/*! Purpose : SLOT. Open new document with \a aName.*/
+bool LightApp_Application::onOpenDoc( const QString& aName )
+{
+  bool isAlreadyOpen = false;
+
+  // Look among opened studies
+  if (activeStudy()) { // at least one study is opened
+    SUIT_Session* aSession = SUIT_Session::session();
+    QPtrList<SUIT_Application> aAppList = aSession->applications();
+    QPtrListIterator<SUIT_Application> it (aAppList);
+    SUIT_Application* aApp = 0;
+    // iterate on all applications
+    for (; (aApp = it.current()) && !isAlreadyOpen; ++it) {
+      if (aApp->activeStudy()->studyName() == aName) {
+        isAlreadyOpen = true; // Already opened, ask user what to do
+
+        // The document ... is already open.
+        // Do you want to reload it?
+        int aAnswer = SUIT_MessageBox::warn2(desktop(), tr("WRN_WARNING"),
+                                             tr("QUE_DOC_ALREADYOPEN").arg(aName),
+                                             tr("BUT_YES"), tr("BUT_NO"), 1, 2, 2);
+        if (aAnswer == 1) { // reload
+          if (activeStudy()->studyName() == aName && aAppList.count() > 1) {
+            // Opened in THIS (active) application.
+            STD_Application* app1 = (STD_Application*)aAppList.at(0);
+            STD_Application* app2 = (STD_Application*)aAppList.at(1);
+            if (!app1 || !app2) {
+              // Error
+              return false;
+            }
+            if (app1->activeStudy()->studyName() == aName) {
+              // app1 is this application, we need another one
+              app1 = app2;
+            }
+            // Close document of this application. This application will be destroyed.
+            onCloseDoc(/*ask = */false);
+            // Open the file with another application, as this one will be destroyed.
+            return app1->onOpenDoc(aName);
+          } else {
+            // Opened in another application.
+            STD_Application* app = (STD_Application*)aApp;
+            if (app)
+              app->onCloseDoc(/*ask = */false);
+          }
+        } else { // do not reload
+          // OK, the study will not be reloaded, but we call
+          // CAM_Application::onOpenDoc( aName ) all the same.
+          // It will activate a desktop of the study <aName>.
+        }
+      }
+    }
+  }
+
+  bool res = CAM_Application::onOpenDoc( aName );
+
+  QAction* a = action( MRUId );
+  if ( a && a->inherits( "QtxMRUAction" ) )
+  {
+    QtxMRUAction* mru = (QtxMRUAction*)a;
+    if ( res )
+      mru->insert( aName );
+    else
+      mru->remove( aName );
+  }
+  return res;
+}
+
+//=======================================================================
+// name    : onHelpAbout
+/*! Purpose : SLOT. Display "About" message box*/
+//=======================================================================
+void LightApp_Application::onHelpAbout()
+{
+  LightApp_AboutDlg* dlg = new LightApp_AboutDlg( applicationName(), applicationVersion(), desktop() );
+  dlg->exec();
+  delete dlg;
+}
+
+/*!SLOT. Load document with \a aName.*/
+bool LightApp_Application::onLoadDoc( const QString& aName )
+{
+  bool res = CAM_Application::onLoadDoc( aName );
+
+  /*jfa tmp:QAction* a = action( MRUId );
+  if ( a && a->inherits( "QtxMRUAction" ) )
+  {
+    QtxMRUAction* mru = (QtxMRUAction*)a;
+    if ( res )
+      mru->insert( aName );
+    else
+      mru->remove( aName );
+  }*/
+  return res;
+}
+
+/*!Private SLOT. Selection.*/
+void LightApp_Application::onSelection()
+{
+  onSelectionChanged();
+
+  if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
+    ((LightApp_Module*)activeModule())->selectionChanged();
+}
+
+/*!Set active study.
+ *\param study - SUIT_Study.
+ */
+void LightApp_Application::setActiveStudy( SUIT_Study* study )
+{
+  CAM_Application::setActiveStudy( study );
+
+  activateWindows();
+}
+
+//=======================================================================
+// name    : updateCommandsStatus
+/*! Purpose : Enable/Disable menu items and toolbar buttons. Rebuild menu*/
+//=======================================================================
+void LightApp_Application::updateCommandsStatus()
+{
+  CAM_Application::updateCommandsStatus();
+
+  for ( int id = NewGLViewId; id <= NewVTKViewId; id++ )
+  {
+    QAction* a = action( id );
+    if ( a )
+      a->setEnabled( activeStudy() );
+  }
+}
+
+// Helps to execute command
+class RunBrowser: public QThread {
+public:
+
+  RunBrowser(QString theApp, QString theParams, QString theHelpFile, QString theContext=NULL):
+    myApp(theApp), myParams(theParams), 
+#ifdef WIN32
+      myHelpFile("file://" + theHelpFile + theContext), 
+#else
+      myHelpFile("file:" + theHelpFile + theContext),
+#endif
+      myStatus(0) {};
+
+  virtual void run()
+  {
+    QString aCommand;
+
+    if ( !myApp.isEmpty())
+      {
+       aCommand.sprintf("%s %s %s",myApp.latin1(),myParams.latin1(),myHelpFile.latin1());
+       myStatus = system(aCommand);
+       if(myStatus != 0)
+         {
+           QCustomEvent* ce2000 = new QCustomEvent (2000);
+           postEvent (qApp, ce2000);
+         }
+      }
+      if( myStatus != 0)
+      {
+        qApp->lock();
+        SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
+                               QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").arg(myApp).arg(myHelpFile),
+                               QObject::tr("BUT_OK"));
+        qApp->unlock();
+      }
+  }
+
+private:
+  QString myApp;
+  QString myParams;
+  QString myHelpFile;
+  int myStatus;
+
+};
+
+//=======================================================================
+// name    : onHelpContentsModule
+/*! Purpose : SLOT. Display help contents for choosen module*/
+//=======================================================================
+void LightApp_Application::onHelpContentsModule()
+{
+  const QAction* obj = (QAction*) sender();
+
+  QString aComponentName = obj->name();
+  QString aFileName = aComponentName + "_index_v3.1.0.html";
+
+  QCString dir = getenv( aComponentName + "_ROOT_DIR");
+  QString homeDir = Qtx::addSlash( Qtx::addSlash(dir) +  Qtx::addSlash("doc") +  Qtx::addSlash("salome") );
+
+  QString helpFile = QFileInfo( homeDir + aFileName ).absFilePath();
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+  QString anApp = resMgr->stringValue("ExternalBrowser", "application");
+  QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
+
+  if (!anApp.isEmpty()) {
+    RunBrowser* rs = new RunBrowser(anApp, aParams, helpFile);
+    rs->start();
+  }
+  else {
+    SUIT_MessageBox::warn1(desktop(), tr("WRN_WARNING"),
+                           tr("DEFINE_EXTERNAL_BROWSER"),
+                           tr("BUT_OK"));
+  }
+}
+
+/*!Sets enable or disable some actions on selection changed.*/
+void LightApp_Application::onSelectionChanged()
+{
+}
+
+/*!Return window.
+ *\param flag - key for window
+ *\param studyId - study id
+ * Flag used how identificator of window in windows list.
+ */
+QWidget* LightApp_Application::window( const int flag, const int studyId ) const
+{
+  QWidget* wid = 0;
+
+ int sId = studyId;
+  if ( sId < 0 )
+  {
+    if ( !activeStudy() )
+      return 0;
+    else
+      sId = activeStudy()->id();
+  }
+
+  if ( myWindows.contains( flag ) )
+    wid = myWindows[flag]->widget( sId );
+
+  return wid;
+}
+
+/*!Adds window to application.
+ *\param wid - QWidget
+ *\param flag - key wor window
+ *\param studyId - study id
+ * Flag used how identificator of window in windows list.
+ */
+void LightApp_Application::addWindow( QWidget* wid, const int flag, const int studyId )
+{
+  if ( !wid )
+    return;
+
+  int sId = studyId;
+  if ( sId < 0 )
+  {
+    if ( !activeStudy() )
+      return;
+    else
+      sId = activeStudy()->id();
+  }
+
+  if ( !myWindows.contains( flag ) )
+  {
+    QMap<int, int> winMap;
+    currentWindows( winMap );
+
+    LightApp_WidgetContainer* newWC = new LightApp_WidgetContainer( flag, desktop() );
+    connect( newWC, SIGNAL(  destroyed ( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
+    myWindows.insert( flag, newWC );
+    if ( winMap.contains( flag ) )
+      desktop()->moveDockWindow( myWindows[flag], (Dock)winMap[flag] );
+
+    myWindows[flag]->setResizeEnabled( true );
+    myWindows[flag]->setCloseMode( QDockWindow::Always );
+    myWindows[flag]->setName( QString( "dock_window_%1" ).arg( flag ) );
+    myWindows[flag]->setFixedExtentWidth( wid->width() );
+    myWindows[flag]->setFixedExtentHeight( wid->height() );
+  }
+
+  QFont f;
+  if( wid->inherits( "PythonConsole" ) )
+  {
+    if( resourceMgr()->hasValue( "PyConsole", "font" ) )
+      f = resourceMgr()->fontValue( "PyConsole", "font" );
+    else
+    {
+      f = ( ( PythonConsole* )wid )->font();
+      resourceMgr()->setValue( "PyConsole", "font", f );
+    }
+  }
+  else
+    f = wid->font();
+
+  myWindows[flag]->insert( sId, wid );
+  wid->setFont(f);
+
+  setWindowShown( flag, !myWindows[flag]->isEmpty() );
+}
+
+/*!Remove window from application.
+ *\param flag - key wor window
+ *\param studyId - study id
+ * Flag used how identificator of window in windows list.
+ */
+void LightApp_Application::removeWindow( const int flag, const int studyId )
+{
+  if ( !myWindows.contains( flag ) )
+    return;
+
+  int sId = studyId;
+  if ( sId < 0 )
+  {
+    if ( !activeStudy() )
+      return;
+    else
+      sId = activeStudy()->id();
+  }
+
+  QWidget* wid = myWindows[flag]->widget( sId );
+  myWindows[flag]->remove( sId );
+  delete wid;
+
+  setWindowShown( flag, !myWindows[flag]->isEmpty() );
+}
+
+/*!Gets window.
+ *\param flag - key wor window
+ *\param studyId - study id
+ * Flag used how identificator of window in windows list.
+ */
+QWidget* LightApp_Application::getWindow( const int flag, const int studyId )
+{
+  QWidget* wid = window( flag, studyId );
+  if ( !wid )
+    addWindow( wid = createWindow( flag ), flag, studyId );
+
+  return wid;
+}
+
+/*!Check is window visible?(with identificator \a type)*/
+bool LightApp_Application::isWindowVisible( const int type ) const
+{
+  bool res = false;
+  if ( myWindows.contains( type ) )
+  {
+    SUIT_Desktop* desk = ((LightApp_Application*)this)->desktop();
+    res = desk && desk->appropriate( myWindows[type] );
+  }
+  return res;
+}
+
+/*!Sets window show or hide.
+ *\param type - window identificator.
+ *\param on   - true/false (window show/hide)
+ */
+void LightApp_Application::setWindowShown( const int type, const bool on )
+{
+  if ( !desktop() || !myWindows.contains( type ) )
+    return;
+
+  QDockWindow* dw = myWindows[type];
+  desktop()->setAppropriate( dw, on );
+  on ? dw->show() : dw->hide();
+}
+
+/*!Gets "ObjectBrowser".*/
+OB_Browser* LightApp_Application::objectBrowser()
+{
+  OB_Browser* ob = 0;
+  QWidget* wid = window( WT_ObjectBrowser );
+  if ( wid && wid->inherits( "OB_Browser" ) )
+    ob = (OB_Browser*)wid;
+  return ob;
+}
+
+/*!Gets "LogWindow".*/
+LogWindow* LightApp_Application::logWindow()
+{
+  LogWindow* lw = 0;
+  QWidget* wid = getWindow( WT_LogWindow );
+  if ( wid->inherits( "LogWindow" ) )
+    lw = (LogWindow*)wid;
+  return lw;
+}
+
+/*!Get "PythonConsole"*/
+PythonConsole* LightApp_Application::pythonConsole()
+{
+  PythonConsole* console = 0;
+  QWidget* wid = getWindow( WT_PyConsole );
+  if ( wid->inherits( "PythonConsole" ) )
+    console = (PythonConsole*)wid;
+  return console;
+}
+
+/*!Update obect browser*/
+void LightApp_Application::updateObjectBrowser( const bool updateModels )
+{
+  // update existing data models
+  if ( updateModels ) 
+  {
+    LightApp_Study* study = dynamic_cast<LightApp_Study*>(activeStudy());
+    if ( study ) {
+      CAM_Study::ModelList dm_list;
+      study->dataModels( dm_list );
+      for ( CAM_Study::ModelListIterator it( dm_list ); it.current(); ++it ) {
+        CAM_DataModel* camDM = it.current();
+        if ( camDM && camDM->inherits( "LightApp_DataModel" ) )
+          ((LightApp_DataModel*)camDM)->update();
+      }
+    }
+  }
+  if ( objectBrowser() )
+  {
+    objectBrowser()->updateGeometry();
+    objectBrowser()->updateTree( 0, false );
+  }
+}
+
+/*!Gets preferences.*/
+LightApp_Preferences* LightApp_Application::preferences() const
+{
+  return preferences( false );
+}
+
+/*!Gets view manager*/
+SUIT_ViewManager* LightApp_Application::getViewManager( const QString& vmType, const bool create )
+{
+  SUIT_ViewManager* aVM = viewManager( vmType );
+  SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
+
+  if ( anActiveVM && anActiveVM->getType() == vmType )
+    aVM = anActiveVM;
+
+  if ( aVM && create )
+  {
+    if ( !aVM->getActiveView() )
+      aVM->createView();
+    else
+      aVM->getActiveView()->setFocus();
+  }
+  else if ( create )
+    aVM = createViewManager( vmType );
+
+  return aVM;
+}
+
+/*!Create view manager.*/
+SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType )
+{
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+
+  SUIT_ViewManager* viewMgr = 0;
+  if( vmType == GLViewer_Viewer::Type() )
+  {
+    viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
+    new LightApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
+  }
+  else if( vmType == Plot2d_Viewer::Type() )
+  {
+    viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
+    SPlot2d_Viewer* vm = new SPlot2d_Viewer();
+    viewMgr->setViewModel( vm  );// custom view model, which extends SALOME_View interface 
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( viewMgr->getActiveView() );
+    if( wnd )
+    {
+      Plot2d_ViewFrame* frame = wnd->getViewFrame();
+      frame->setBackgroundColor( resMgr->colorValue( "Plot2d", "Background", frame->backgroundColor() ) );
+    }
+  }
+  else if( vmType == SUPERVGraph_Viewer::Type() )
+  {
+    viewMgr = new SUPERVGraph_ViewManager( activeStudy(), desktop() );
+    SUPERVGraph_Viewer* vm = new SUPERVGraph_Viewer();
+    SUPERVGraph_ViewFrame* view = dynamic_cast<SUPERVGraph_ViewFrame*>( vm->getViewManager()->getActiveView() );
+    if( view )
+      view->setBackgroundColor( resMgr->colorValue( "SUPERVGraph", "Background", view->backgroundColor() ) );
+  }
+  else if( vmType == OCCViewer_Viewer::Type() )
+  {
+    viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
+    SOCC_Viewer* vm = new SOCC_Viewer();
+    vm->setBackgroundColor( resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) );
+    vm->setTrihedronSize( resMgr->integerValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ) );
+    int u( 1 ), v( 1 );
+    vm->isos( u, v );
+    u = resMgr->integerValue( "OCCViewer", "iso_number_u", u );
+    v = resMgr->integerValue( "OCCViewer", "iso_number_v", v );
+    vm->setIsos( u, v );
+    viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
+    new LightApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
+  }
+  else if ( vmType == SVTK_Viewer::Type() )
+  {
+    viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
+    SVTK_Viewer* vm = dynamic_cast<SVTK_Viewer*>( viewMgr->getViewModel() );
+    if( vm )
+    {
+      vm->setBackgroundColor( resMgr->colorValue( "VTKViewer", "background", vm->backgroundColor() ) );
+      vm->setTrihedronSize( resMgr->integerValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ) );
+      new LightApp_VTKSelector( vm, mySelMgr );
+    }
+  }
+
+  if ( !viewMgr )
+    return 0;
+
+  addViewManager( viewMgr );
+  SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
+
+  if ( viewWin && desktop() )
+    viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
+
+  connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
+           this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
+
+  return viewMgr;
+}
+
+//=======================================================================
+// name    : onCloseView
+/*! Purpose : SLOT. Remove view manager from application*/
+//=======================================================================
+void LightApp_Application::onCloseView( SUIT_ViewManager* theVM )
+{
+  removeViewManager( theVM );
+}
+
+/*!Protected SLOT. On study created.*/
+void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
+{
+  SUIT_DataObject* aRoot = 0;
+  if ( theStudy && theStudy->root() )
+  {
+    aRoot = theStudy->root();
+    //aRoot->setName( tr( "DATA_MODELS" ) );
+  }
+  getWindow( WT_ObjectBrowser );
+  if ( objectBrowser() != 0 )
+    objectBrowser()->setRootObject( aRoot );
+
+  activateModule( defaultModule() );
+
+  activateWindows();
+}
+
+/*!Protected SLOT. On study opened.*/
+void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
+{
+  SUIT_DataObject* aRoot = 0;
+  if ( theStudy && theStudy->root() )
+  {
+    aRoot = theStudy->root();
+    //aRoot->dump();
+  }
+  getWindow( WT_ObjectBrowser );
+  if ( objectBrowser() != 0 ) {
+    objectBrowser()->setRootObject( aRoot );
+  }
+
+  activateModule( defaultModule() );
+
+  activateWindows();
+
+  emit studyOpened();
+}
+
+/*!Protected SLOT. On study saved.*/
+void LightApp_Application::onStudySaved( SUIT_Study* )
+{
+  emit studySaved();
+}
+
+/*!Protected SLOT. On study closed.*/
+void LightApp_Application::onStudyClosed( SUIT_Study* )
+{
+  emit studyClosed();
+
+  // Bug 10396: clear selection
+  mySelMgr->clearSelected();
+
+  activateModule( "" );
+
+  saveWindowsGeometry();
+}
+
+/*!Protected SLOT.On desktop activated.*/
+void LightApp_Application::onDesktopActivated()
+{
+  CAM_Application::onDesktopActivated();
+  LightApp_Module* aModule = dynamic_cast<LightApp_Module*>(activeModule());
+  if(aModule)
+    aModule->studyActivated();
+}
+
+/*!Gets file filter.
+ *\retval QString "(*.bin)"
+ */
+QString LightApp_Application::getFileFilter() const
+{
+  return "(*.bin)";
+}
+
+/*! Gets file name*/
+QString LightApp_Application::getFileName( bool open, const QString& initial, const QString& filters, 
+                                           const QString& caption, QWidget* parent )
+{
+  if ( !parent )
+    parent = desktop();
+  QStringList fls = QStringList::split( ";;", filters, false );
+  return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
+}
+
+/*! Gets directory*/
+QString LightApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
+{
+  if ( !parent )
+    parent = desktop();
+  return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
+}
+
+/*! Get open file names*/
+QStringList LightApp_Application::getOpenFileNames( const QString& initial, const QString& filters, 
+                                                    const QString& caption, QWidget* parent )
+{
+  if ( !parent )
+    parent = desktop();
+  QStringList fls = QStringList::split( ";;", filters, false );
+  return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
+}
+
+/*!Private SLOT. Update object browser.*/
+void LightApp_Application::onRefresh()
+{
+  updateObjectBrowser( true );
+}
+
+/*!Private SLOT. On preferences.*/
+void LightApp_Application::onPreferences()
+{
+  QApplication::setOverrideCursor( Qt::waitCursor );
+
+  LightApp_PreferencesDlg* prefDlg = new LightApp_PreferencesDlg( preferences( true ), desktop());
+
+  QApplication::restoreOverrideCursor();
+
+  if ( !prefDlg )
+    return;
+
+  if ( ( prefDlg->exec() == QDialog::Accepted || prefDlg->isSaved() ) &&  resourceMgr() ) {
+    if ( desktop() )
+      desktop()->saveGeometry( resourceMgr(), "desktop" );
+    resourceMgr()->save();
+  }
+
+  delete prefDlg;
+}
+
+/*!Protected SLOT. On preferences changed.*/
+void LightApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
+{
+  LightApp_Module* sMod = 0;
+  CAM_Module* mod = module( modName );
+  if ( mod && mod->inherits( "LightApp_Module" ) )
+    sMod = (LightApp_Module*)mod;
+
+  if ( sMod )
+    sMod->preferencesChanged( section, param );
+  else
+    preferencesChanged( section, param );
+}
+
+/*!Private SLOT. On open document with name \a aName.*/
+void LightApp_Application::onMRUActivated( QString aName )
+{
+  onOpenDoc( aName );
+}
+
+/*!Remove all windows from study.*/
+void LightApp_Application::beforeCloseDoc( SUIT_Study* s )
+{
+  CAM_Application::beforeCloseDoc( s );
+
+  for ( WindowMap::ConstIterator itr = myWindows.begin(); s && itr != myWindows.end(); ++itr )
+    removeWindow( itr.key(), s->id() );
+}
+
+/*!Update actions.*/
+void LightApp_Application::updateActions()
+{
+  updateCommandsStatus();
+}
+
+//=======================================================================
+// name    : createNewStudy
+/*! Purpose : Create new study*/
+//=======================================================================
+SUIT_Study* LightApp_Application::createNewStudy()
+{
+  LightApp_Study* aStudy = new LightApp_Study( this );
+
+  // Set up processing of major study-related events
+  connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
+  connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
+  connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
+  connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
+
+  return aStudy;
+}
+
+/*!Create window.*/
+QWidget* LightApp_Application::createWindow( const int flag )
+{
+  QWidget* wid = 0;
+  if ( flag == WT_ObjectBrowser )
+  {
+    OB_Browser* ob = new OB_Browser( desktop() );
+    ob->setAutoUpdate( true );
+    ob->setAutoOpenLevel( 1 );
+    ob->setCaption( tr( "OBJECT_BROWSER" ) );
+
+    OB_ListView* ob_list = dynamic_cast<OB_ListView*>( const_cast<QListView*>( ob->listView() ) );
+    if( ob_list )
+      ob_list->setColumnMaxWidth( 0, desktop()->width()/4 );
+
+    ob->setFilter( new LightApp_OBFilter( selectionMgr() ) );
+    ob->setNameTitle( tr( "OBJ_BROWSER_NAME" ) );
+
+    // Create OBSelector
+    new LightApp_OBSelector( ob, mySelMgr );
+
+    wid = ob;
+
+    ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
+  }
+  else  if ( flag == WT_PyConsole )
+  {
+    PythonConsole* pyCons = new PythonConsole( desktop() );
+    pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
+    wid = pyCons;
+    //    pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
+  }
+  else if ( flag == WT_LogWindow )
+  {
+    LogWindow* logWin = new LogWindow( desktop() );
+    logWin->setCaption( tr( "LOG_WINDOW" ) );
+    wid = logWin;
+    logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
+  }
+  return wid;
+}
+
+/*!Default windows(Object Browser, Python Console).
+ * Adds to map \a aMap.
+ */
+void LightApp_Application::defaultWindows( QMap<int, int>& aMap ) const
+{  
+  aMap.insert( WT_ObjectBrowser, Qt::DockLeft );
+  aMap.insert( WT_PyConsole, Qt::DockBottom );
+  //  aMap.insert( WT_LogWindow, Qt::DockBottom );
+}
+
+/*!Default view manager.*/
+void LightApp_Application::defaultViewManagers( QStringList& ) const
+{
+  /*!Do nothing.*/
+}
+
+/*!Gets preferences.
+ * Create preferences, if \a crt = true.
+ */
+LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const
+{
+  if ( myPrefs )
+    return myPrefs;
+
+  LightApp_Application* that = (LightApp_Application*)this;
+
+  bool toCreate = !_prefs_ && crt;
+  if( toCreate )
+  {
+    _prefs_ = new LightApp_Preferences( resourceMgr() );
+    that->createPreferences( _prefs_ );
+  }
+
+  that->myPrefs = _prefs_;
+
+  QPtrList<SUIT_Application> appList = SUIT_Session::session()->applications();
+  for ( QPtrListIterator<SUIT_Application> appIt ( appList ); appIt.current(); ++appIt )
+  {
+    if ( !appIt.current()->inherits( "LightApp_Application" ) )
+      continue;
+
+    LightApp_Application* app = (LightApp_Application*)appIt.current();
+
+    QStringList modNameList;
+    app->modules( modNameList, false );
+    for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
+    {
+      int id = _prefs_->addPreference( *it );
+      _prefs_->setItemProperty( id, "info", tr( "PREFERENCES_NOT_LOADED" ).arg( *it ) );
+    }
+
+    ModuleList modList;
+    app->modules( modList );
+    for ( ModuleListIterator itr( modList ); itr.current(); ++itr )
+    {
+      LightApp_Module* mod = 0;
+      if ( itr.current()->inherits( "LightApp_Module" ) )
+       mod = (LightApp_Module*)itr.current();
+
+      if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
+      {
+       int modCat = _prefs_->addPreference( mod->moduleName() );
+       _prefs_->setItemProperty( modCat, "info", QString::null );
+       if( toCreate )
+         mod->createPreferences();
+      }
+    }
+  }
+
+  connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
+           this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) );
+
+  return myPrefs;
+}
+
+/*!Add new module to application.*/
+void LightApp_Application::moduleAdded( CAM_Module* mod )
+{
+  CAM_Application::moduleAdded( mod );
+
+  LightApp_Module* lightMod = 0;
+  if ( mod && mod->inherits( "LightApp_Module" ) )
+    lightMod = (LightApp_Module*)mod;
+
+  if ( myPrefs && lightMod && !myPrefs->hasModule( lightMod->moduleName() ))
+  {
+    int modCat = myPrefs->addPreference( mod->moduleName() );
+    myPrefs->setItemProperty( modCat, "info", QString::null );
+    lightMod->createPreferences();
+  }
+}
+
+/*!Create preferences.*/
+void LightApp_Application::createPreferences( LightApp_Preferences* pref )
+{
+  if ( !pref )
+    return;
+
+  int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
+
+  int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
+  int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab );
+  pref->setItemProperty( studyGroup, "columns", 1 );
+
+  pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "multi_file" );
+  pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" );
+  int undoPref = pref->addPreference( tr( "PREF_UNDO_LEVEL" ), studyGroup, LightApp_Preferences::IntSpin, "Study", "undo_level" );
+  pref->setItemProperty( undoPref, "min", 1 );
+  pref->setItemProperty( undoPref, "max", 100 );
+  pref->addPreference( tr( "PREF_STORE_POS" ), studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" );
+
+  int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab );
+  pref->setItemProperty( extgroup, "columns", 1 );
+  int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, LightApp_Preferences::File, "ExternalBrowser", "application" );
+  pref->setItemProperty( apppref, "existing", true );
+  pref->setItemProperty( apppref, "flags", QFileInfo::ExeUser );
+  pref->setItemProperty( apppref, "readOnly", false );
+
+  pref->addPreference( tr( "PREF_PARAM" ), extgroup, LightApp_Preferences::String, "ExternalBrowser", "parameters" );
+
+  int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab );
+  pref->setItemProperty( pythonConsoleGroup, "columns", 1 );
+  pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, LightApp_Preferences::Font, "PyConsole", "font" );
+
+  int viewTab = pref->addPreference( tr( "PREF_TAB_VIEWERS" ), salomeCat );
+
+  int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), viewTab );
+
+  int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), viewTab );
+
+  int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), viewTab );
+
+  int supervGroup = pref->addPreference( tr( "PREF_GROUP_SUPERV" ), viewTab );
+
+  pref->setItemProperty( occGroup, "columns", 1 );
+  pref->setItemProperty( vtkGroup, "columns", 1 );
+  pref->setItemProperty( plot2dGroup, "columns", 1 );
+
+  int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occGroup,
+                                  LightApp_Preferences::IntSpin, "OCCViewer", "trihedron_size" );
+  pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup,
+                      LightApp_Preferences::Color, "OCCViewer", "background" );
+
+  pref->setItemProperty( occTS, "min", 1 );
+  pref->setItemProperty( occTS, "max", 150 );
+
+  int isoU = pref->addPreference( tr( "PREF_ISOS_U" ), occGroup,
+                                 LightApp_Preferences::IntSpin, "OCCViewer", "iso_number_u" );
+  int isoV = pref->addPreference( tr( "PREF_ISOS_V" ), occGroup,
+                                 LightApp_Preferences::IntSpin, "OCCViewer", "iso_number_v" );
+
+  pref->setItemProperty( isoU, "min", 0 );
+  pref->setItemProperty( isoU, "max", 100000 );
+
+  pref->setItemProperty( isoV, "min", 0 );
+  pref->setItemProperty( isoV, "max", 100000 );
+
+  int vtkTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), vtkGroup,
+                                  LightApp_Preferences::IntSpin, "VTKViewer", "trihedron_size" );
+  pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), vtkGroup, LightApp_Preferences::Bool, "VTKViewer", "relative_size" );
+  pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGroup,
+                      LightApp_Preferences::Color, "VTKViewer", "background" );
+
+  pref->setItemProperty( vtkTS, "min", 1 );
+  pref->setItemProperty( vtkTS, "max", 150 );
+
+  pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dGroup,
+                      LightApp_Preferences::Bool, "Plot2d", "ShowLegend" );
+
+  int legendPosition = pref->addPreference( tr( "PREF_LEGEND_POSITION" ), plot2dGroup,
+                                           LightApp_Preferences::Selector, "Plot2d", "LegendPos" );
+  QStringList aLegendPosList;
+  aLegendPosList.append( tr("PREF_LEFT") );
+  aLegendPosList.append( tr("PREF_RIGHT") );
+  aLegendPosList.append( tr("PREF_TOP") );
+  aLegendPosList.append( tr("PREF_BOTTOM") );
+
+  QValueList<QVariant> anIndexesList;
+  anIndexesList.append(0);
+  anIndexesList.append(1);
+  anIndexesList.append(2);
+  anIndexesList.append(3);
+
+  pref->setItemProperty( legendPosition, "strings", aLegendPosList );
+  pref->setItemProperty( legendPosition, "indexes", anIndexesList );
+
+  int curveType = pref->addPreference( tr( "PREF_CURVE_TYPE" ), plot2dGroup,
+                                      LightApp_Preferences::Selector, "Plot2d", "CurveType" );
+  QStringList aCurveTypesList;
+  aCurveTypesList.append( tr("PREF_POINTS") );
+  aCurveTypesList.append( tr("PREF_LINES") );
+  aCurveTypesList.append( tr("PREF_SPLINE") );
+
+  anIndexesList.clear();
+  anIndexesList.append(0);
+  anIndexesList.append(1);
+  anIndexesList.append(2);
+  
+  pref->setItemProperty( curveType, "strings", aCurveTypesList );
+  pref->setItemProperty( curveType, "indexes", anIndexesList );
+
+  int markerSize = pref->addPreference( tr( "PREF_MARKER_SIZE" ), plot2dGroup,
+                                       LightApp_Preferences::IntSpin, "Plot2d", "MarkerSize" );
+
+  pref->setItemProperty( markerSize, "min", 0 );
+  pref->setItemProperty( markerSize, "max", 100 );
+  
+  QStringList aScaleModesList;
+  aScaleModesList.append( tr("PREF_LINEAR") );
+  aScaleModesList.append( tr("PREF_LOGARITHMIC") );
+  
+  anIndexesList.clear();
+  anIndexesList.append(0);
+  anIndexesList.append(1);
+
+  int horScale = pref->addPreference( tr( "PREF_HOR_AXIS_SCALE" ), plot2dGroup,
+                                     LightApp_Preferences::Selector, "Plot2d", "HorScaleMode" );
+
+  pref->setItemProperty( horScale, "strings", aScaleModesList );
+  pref->setItemProperty( horScale, "indexes", anIndexesList );
+
+  int verScale = pref->addPreference( tr( "PREF_VERT_AXIS_SCALE" ), plot2dGroup,
+                                     LightApp_Preferences::Selector, "Plot2d", "VerScaleMode" );
+
+  pref->setItemProperty( verScale, "strings", aScaleModesList );
+  pref->setItemProperty( verScale, "indexes", anIndexesList );
+
+  pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), plot2dGroup,
+                      LightApp_Preferences::Color, "Plot2d", "Background" );
+
+  int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
+  int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
+  pref->setItemProperty( dirGroup, "columns", 1 );
+  pref->addPreference( tr( "" ), dirGroup,
+                      LightApp_Preferences::DirList, "FileDlg", "QuickDirList" );
+
+  pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), supervGroup,
+                      LightApp_Preferences::Color, "SUPERVGraph", "Background" );
+  pref->addPreference( tr( "PREF_SUPERV_TITLE_COLOR" ), supervGroup,
+                      LightApp_Preferences::Color, "SUPERVGraph", "Title" );
+//  pref->addPreference( tr( "PREF_SUPERV_CTRL_COLOR" ), supervGroup,
+//                    LightApp_Preferences::Color, "SUPERVGraph", "Ctrl" );
+
+  int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
+  int objSetGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SETTINGS" ), obTab );
+  pref->addPreference( tr( "PREF_AUTO_SIZE_FIRST" ), objSetGroup, LightApp_Preferences::Bool,
+                      "ObjectBrowser", "auto_size_first" );
+  pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, LightApp_Preferences::Bool,
+                      "ObjectBrowser", "auto_size" );
+}
+
+/*!Changed preferences */
+void LightApp_Application::preferencesChanged( const QString& sec, const QString& param )
+{
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+  if ( !resMgr )
+    return;
+
+  if ( sec == QString( "OCCViewer" ) && param == QString( "trihedron_size" ) )
+  {
+    int sz = resMgr->integerValue( sec, param, -1 );
+    QPtrList<SUIT_ViewManager> lst;
+    viewManagers( OCCViewer_Viewer::Type(), lst );
+    for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
+    {
+      SUIT_ViewModel* vm = it.current()->getViewModel();
+      if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
+       continue;
+
+      OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
+      occVM->setTrihedronSize( sz );
+      occVM->getAISContext()->UpdateCurrentViewer();
+    }
+  }
+
+  if ( sec == QString( "VTKViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" )) )
+  {
+    int sz = resMgr->integerValue( "VTKViewer", "trihedron_size", -1 );
+    QPtrList<SUIT_ViewManager> lst;
+    viewManagers( SVTK_Viewer::Type(), lst );
+    for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
+    {
+      SUIT_ViewModel* vm = it.current()->getViewModel();
+      if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
+       continue;
+
+      SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
+      if( vtkVM )
+      {
+       vtkVM->setTrihedronSize( sz );
+       vtkVM->Repaint();
+      }
+    }
+  }
+
+  if ( sec == QString( "OCCViewer" ) && ( param == QString( "iso_number_u" ) || param == QString( "iso_number_v" ) ) )
+  {
+    QPtrList<SUIT_ViewManager> lst;
+    viewManagers( OCCViewer_Viewer::Type(), lst );
+    int u = resMgr->integerValue( sec, "iso_number_u" );
+    int v = resMgr->integerValue( sec, "iso_number_v" );
+    for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
+    {
+      OCCViewer_ViewManager* mgr = dynamic_cast<OCCViewer_ViewManager*>( it.current() );
+      if( mgr && mgr->getOCCViewer() )
+       mgr->getOCCViewer()->setIsos( u, v );
+    }
+  }
+
+  if( sec=="ObjectBrowser" )
+  {
+    if( param=="auto_size" || param=="auto_size_first" )
+    {
+      OB_Browser* ob = objectBrowser();
+      if( !ob )
+       return;
+
+      bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false ),
+           autoSizeFirst = resMgr->booleanValue( "ObjectBrowser", "auto_size_first", true );
+      ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
+      ob->listView()->setColumnWidthMode( 0, autoSizeFirst ? QListView::Maximum : QListView::Manual );
+      updateObjectBrowser( false );
+    }
+  }
+
+  if( sec=="Study" )
+  { 
+    if( param=="store_positions" )
+      updateWindows();
+  }
+
+  if( sec=="PyConsole" )
+  {
+    if( param=="font" )
+      if( pythonConsole() )
+       pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) );
+  }
+}
+
+/*!Update desktop title.*/
+void LightApp_Application::updateDesktopTitle() {
+  QString aTitle = applicationName();
+  QString aVer = applicationVersion();
+  if ( !aVer.isEmpty() )
+    aTitle += QString( " " ) + aVer;
+
+  desktop()->setCaption( aTitle );
+}
+
+/*!Update windows after close document.*/
+void LightApp_Application::afterCloseDoc()
+{
+  updateWindows();
+
+  CAM_Application::afterCloseDoc();
+}
+
+/*!Update module action.*/
+void LightApp_Application::updateModuleActions()
+{
+  QString modName;
+  if ( activeModule() )
+    modName = activeModule()->moduleName();
+
+  if ( myActions.contains( modName ) )
+    myActions[modName]->setOn( true );
+}
+
+/*!Gets current windows.
+ *\param winMap - output current windows map.
+ */
+void LightApp_Application::currentWindows( QMap<int, int>& winMap ) const
+{
+  winMap.clear();
+  if ( !activeStudy() )
+    return;
+
+  if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
+    ((LightApp_Module*)activeModule())->windows( winMap );
+  else
+    defaultWindows( winMap );
+}
+
+/*!Gets current view managers.
+ *\param lst - output current view managers list.
+ */
+void LightApp_Application::currentViewManagers( QStringList& lst ) const
+{
+  lst.clear();
+  if ( !activeStudy() )
+    return;
+
+  if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
+    ((LightApp_Module*)activeModule())->viewManagers( lst );
+  else
+    defaultViewManagers( lst );
+}
+
+/*!Update windows.*/
+void LightApp_Application::updateWindows()
+{
+  QMap<int, int> winMap;
+  currentWindows( winMap );
+
+  for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
+    getWindow( it.key() );
+
+  loadWindowsGeometry();
+
+  for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
+    setWindowShown( itr.key(), !itr.data()->isEmpty() && winMap.contains( itr.key() ) );
+}
+
+/*!Update view managers.*/
+void LightApp_Application::updateViewManagers()
+{
+  QStringList lst;
+  currentViewManagers( lst );
+
+  for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
+    getViewManager( *it, true );
+}
+
+/*!Load windows geometry.*/
+void LightApp_Application::loadWindowsGeometry()
+{
+  bool store = resourceMgr()->booleanValue( "Study", "store_positions", true );
+  if( !store )
+    return;
+
+  QtxDockAction* dockMgr = 0;
+
+  QAction* a = action( ViewWindowsId );
+  if ( a && a->inherits( "QtxDockAction" ) )
+    dockMgr = (QtxDockAction*)a;
+
+  if ( !dockMgr )
+    return;
+
+  QString modName;
+  if ( activeModule() )
+    modName = activeModule()->name("");
+
+  QString section = QString( "windows_geometry" );
+  if ( !modName.isEmpty() )
+    section += QString( "." ) + modName;
+
+  dockMgr->loadGeometry( resourceMgr(), section, false );
+  dockMgr->restoreGeometry();
+}
+
+/*!Save windows geometry.*/
+void LightApp_Application::saveWindowsGeometry()
+{
+  bool store = resourceMgr()->booleanValue( "Study", "store_positions", true );
+  if( !store )
+    return;
+
+  QtxDockAction* dockMgr = 0;
+
+  QAction* a = action( ViewWindowsId );
+  if ( a && a->inherits( "QtxDockAction" ) )
+    dockMgr = (QtxDockAction*)a;
+
+  if ( !dockMgr )
+    return;
+
+  QString modName;
+  if ( activeModule() )
+    modName = activeModule()->name("");
+
+  QString section = QString( "windows_geometry" );
+  if ( !modName.isEmpty() )
+    section += QString( "." ) + modName;
+
+  dockMgr->storeGeometry();
+  dockMgr->saveGeometry( resourceMgr(), section, false );
+}
+
+/*!Activate windows.*/
+void LightApp_Application::activateWindows()
+{
+  if ( activeStudy() )
+  {
+    for ( WindowMap::Iterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
+      itr.data()->activate( activeStudy()->id() );
+  }
+}
+
+/*!Adds icon names for modules.*/
+void LightApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
+{
+  iconMap.clear();
+
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+  if ( !resMgr )
+    return;
+
+  QStringList modList;
+  modules( modList, false );
+
+  for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
+  {
+    QString modName = *it;
+    QString modIntr = moduleName( modName );
+    QString modIcon = resMgr->stringValue( modIntr, "icon", QString::null );
+
+    if ( modIcon.isEmpty() )
+      continue;
+
+    if ( SUIT_Tools::extension( modIcon ).isEmpty() )
+      modIcon += QString( ".png" );
+
+    iconMap.insert( modName, modIcon );
+  }
+}
+
+/*!Insert items in popup, which necessary for current application*/
+void LightApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
+{
+  CAM_Application::contextMenuPopup( type, thePopup, title );
+
+  OB_Browser* ob = objectBrowser();
+  if ( !ob || type != ob->popupClientType() )
+    return;
+
+  thePopup->insertSeparator();
+  thePopup->insertItem( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
+}
+
+/*!Create empty study.*/
+void LightApp_Application::createEmptyStudy()
+{
+  CAM_Application::createEmptyStudy();
+  if ( objectBrowser() )
+    objectBrowser()->updateTree();
+}
+
+/*!Activate module \a mod.*/
+bool LightApp_Application::activateModule( CAM_Module* mod )
+{
+  bool res = CAM_Application::activateModule( mod );
+  if ( objectBrowser() )
+    objectBrowser()->updateTree();
+  return res;
+}
+
+/*!return keyborad accelerators manager object */
+SUIT_Accel* LightApp_Application::accel() const
+{
+  return myAccel;
+}
+
+/*! remove dead widget container from map */
+void LightApp_Application::onWCDestroyed( QObject* ob )
+{
+  // remove destroyed widget container from windows map
+  for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
+  {
+    if ( itr.data() != ob )
+      continue;
+
+    int key = itr.key();
+    myWindows.remove( key );
+    break;
+  }
+}
+
+/*! redefined to remove view manager from memory */
+void LightApp_Application::removeViewManager( SUIT_ViewManager* vm )
+{
+  disconnect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
+           this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
+  STD_Application::removeViewManager( vm );
+  delete vm;
+}
+
+/*! rename active window of desktop */
+void LightApp_Application::onRenameWindow()
+{
+  if( !desktop() )
+    return;
+
+  QWidget* w = desktop()->activeWindow();
+  if( !w )
+    return;
+
+  bool ok;
+  QString name = QInputDialog::getText( tr( "TOT_RENAME" ), tr( "PRP_RENAME" ), QLineEdit::Normal, w->caption(), &ok, w );
+  if( ok && !name.isEmpty() )
+    w->setCaption( name );
+}
diff --git a/src/LightApp/LightApp_DataObject.cxx b/src/LightApp/LightApp_DataObject.cxx
new file mode 100644 (file)
index 0000000..8313859
--- /dev/null
@@ -0,0 +1,189 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "LightApp_DataObject.h"
+
+#include "LightApp_Study.h"
+#include "LightApp_RootObject.h"
+
+#include "CAM_DataModel.h"
+#include "CAM_Module.h"
+
+#include <SUIT_Application.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_DataObjectKey.h>
+
+#include <qobject.h>
+
+/*!
+       Class: LightApp_DataObject::Key
+       Level: Internal
+*/
+class LightApp_DataObject::Key : public SUIT_DataObjectKey
+{
+public:
+  Key( const QString& );
+  virtual ~Key();
+
+  virtual bool isLess( const SUIT_DataObjectKey* ) const;
+  virtual bool isEqual( const SUIT_DataObjectKey* ) const;
+
+private:
+  QString myEntry;
+};
+
+/*!Constructor. Initialize by \a entry.*/
+LightApp_DataObject::Key::Key( const QString& entry )
+: SUIT_DataObjectKey(),
+  myEntry( entry )
+{
+}
+
+/*!Destructor. Do nothing.*/
+LightApp_DataObject::Key::~Key()
+{
+}
+
+/*!Checks: Is current key less than \a other.*/
+bool LightApp_DataObject::Key::isLess( const SUIT_DataObjectKey* other ) const
+{
+  Key* that = (Key*)other;
+  return myEntry < that->myEntry;
+}
+
+/*!Checks: Is current key equal with \a other.*/
+bool LightApp_DataObject::Key::isEqual( const SUIT_DataObjectKey* other ) const
+{
+  Key* that = (Key*)other;
+  return myEntry == that->myEntry;
+}
+
+/*
+       Class: LightApp_DataObject
+       Level: Public
+*/
+/*!Constructor. Initialize by \a parent*/
+LightApp_DataObject::LightApp_DataObject( SUIT_DataObject* parent )
+: CAM_DataObject( parent ), myCompObject( 0 ), myCompDataType( "" )
+{
+}
+
+/*!Destructor. Do nothing.*/
+LightApp_DataObject::~LightApp_DataObject()
+{
+}
+
+/*!Gets object ID.
+ *\retval QString
+ */
+QString LightApp_DataObject::entry() const
+{
+  return QString::null;
+}
+
+/*!Create and return new key object.*/
+SUIT_DataObjectKey* LightApp_DataObject::key() const
+{
+  QString str = entry();
+  return new Key( str );
+}
+
+/*!Gets component object.
+ *\retval SUIT_DataObject.
+ */
+SUIT_DataObject* LightApp_DataObject::componentObject() const
+{
+  if ( !myCompObject ) {
+  SUIT_DataObject* compObj = 0; // for root object
+
+    if ( parent() && parent() == root() ) 
+      compObj = (SUIT_DataObject*)this; // for component-level objects
+    else 
+    {
+      compObj = parent(); // for lower level objects
+      while ( compObj && compObj->parent() != root() )
+        compObj = compObj->parent();
+    }
+    LightApp_DataObject* that = (LightApp_DataObject*)this;
+    that->myCompObject = compObj;
+  }
+  return myCompObject;
+}
+
+/*!Get component type.*/
+QString LightApp_DataObject::componentDataType() const
+{
+  if ( myCompDataType.isEmpty() ) {
+  SUIT_DataObject* aCompObj = componentObject();
+    LightApp_ModuleObject* anObj = dynamic_cast<LightApp_ModuleObject*>( aCompObj );
+    if ( anObj ) {
+      CAM_DataModel* aModel = anObj->dataModel();
+      if ( aModel ) {
+        LightApp_DataObject* that = (LightApp_DataObject*)this;
+        that->myCompDataType = aModel->module()->name();
+      }
+    }
+  }
+  return myCompDataType;
+}
+
+/*
+       Class: LightApp_ModuleObject
+       Level: Public
+*/
+
+/*!Constructor.Initialize by \a parent.*/
+LightApp_ModuleObject::LightApp_ModuleObject( SUIT_DataObject* parent )
+: CAM_RootObject( parent ),
+  CAM_DataObject( parent )
+{
+}
+
+/*!Constructor.Initialize by \a module and parent.*/
+LightApp_ModuleObject::LightApp_ModuleObject( CAM_DataModel* dm, SUIT_DataObject* parent )
+: CAM_RootObject( dm, parent ),
+  CAM_DataObject( parent )
+{
+}
+
+/*!Destructor. Do nothing.*/
+LightApp_ModuleObject::~LightApp_ModuleObject()
+{
+}
+
+/*!Returns module name */
+QString LightApp_ModuleObject::name() const
+{
+  return CAM_RootObject::name();
+}
+
+/*!Insert new child object to the children list at specified position
+ *\add component in Study for this module object if it necessary*/
+void LightApp_ModuleObject::insertChild( SUIT_DataObject* theObj, int thePosition )
+{
+  CAM_RootObject::insertChild(theObj, thePosition);
+
+  CAM_DataModel* aModel = dataModel();
+
+  LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>(parent());
+
+  if (aRoot)
+    aRoot->study()->addComponent(aModel);
+
+
+}
diff --git a/src/LightApp/LightApp_DataObject.h b/src/LightApp/LightApp_DataObject.h
new file mode 100644 (file)
index 0000000..1f194ff
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef LIGHTAPP_DATAOBJECT_H
+#define LIGHTAPP_DATAOBJECT_H
+
+#include "LightApp.h"
+
+#include "CAM_DataObject.h"
+#include "CAM_DataModel.h"
+#include "CAM_RootObject.h"
+
+class LightApp_Study;
+
+/*!Description : Data Object has empty entry so it's children must redefine metod entry() and return some unique string*/
+// to do : decomment virtual inheritance 
+class LIGHTAPP_EXPORT LightApp_DataObject : public virtual CAM_DataObject
+{
+  class Key;
+
+public:
+  enum { CT_Value, CT_Entry, CT_IOR, CT_RefEntry };
+
+public:
+  LightApp_DataObject( SUIT_DataObject* = 0 );
+  virtual ~LightApp_DataObject();
+
+  virtual SUIT_DataObjectKey*     key() const;
+  virtual QString                 entry() const;
+
+  virtual SUIT_DataObject*        componentObject() const;
+  virtual QString                 componentDataType() const;
+
+protected:
+  QString                         myCompDataType;
+  SUIT_DataObject*                myCompObject;
+};
+
+/*!
+ * LightApp_ModuleObject - class for optimized access to DataModel from
+ * CAM_RootObject.h.
+ * In modules which will be redefine LightApp_DataObject, LightApp_ModuleObject must be children from rederined DataObject for having necessary properties and children from LightApp_ModuleObject.
+ */
+
+class LIGHTAPP_EXPORT LightApp_ModuleObject : public CAM_RootObject
+{
+public:
+  LightApp_ModuleObject( SUIT_DataObject* = 0 );
+  LightApp_ModuleObject ( CAM_DataModel*, SUIT_DataObject* = 0 );
+
+  virtual ~LightApp_ModuleObject();
+
+  virtual QString        name() const;
+  virtual void           insertChild( SUIT_DataObject*, int thePosition );
+};
+
+#endif
diff --git a/src/LightApp/LightApp_PreferencesDlg.cxx b/src/LightApp/LightApp_PreferencesDlg.cxx
new file mode 100644 (file)
index 0000000..5d0f1ea
--- /dev/null
@@ -0,0 +1,104 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      LightApp_PreferencesDlg.cxx
+// Author:    Sergey TELKOV
+
+#include "LightApp_PreferencesDlg.h"
+
+#include "LightApp_Preferences.h"
+
+#include <qvbox.h>
+#include <qlayout.h>
+
+/*!
+  Constructor.
+*/
+LightApp_PreferencesDlg::LightApp_PreferencesDlg( LightApp_Preferences* prefs, QWidget* parent )
+: QtxDialog( parent, 0, true, false, OK | Close | Apply ),
+myPrefs( prefs ), mySaved ( false )
+{
+  setCaption( tr( "CAPTION" ) );
+
+  QVBoxLayout* main = new QVBoxLayout( mainFrame(), 5 );
+
+  QVBox* base = new QVBox( mainFrame() );
+  main->addWidget( base );
+
+  myPrefs->reparent( base, QPoint( 0, 0 ), true );
+
+  setFocusProxy( myPrefs );
+
+  setButtonPosition( Right, Close );
+
+  setDialogFlags( AlignOnce );
+
+  connect( this, SIGNAL( dlgHelp() ),  this, SLOT( onHelp() ) );
+  connect( this, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
+}
+
+/*!
+  Destructor.
+*/
+LightApp_PreferencesDlg::~LightApp_PreferencesDlg()
+{
+  if ( !myPrefs )
+    return;
+
+  myPrefs->reparent( 0, QPoint( 0, 0 ), false );
+  myPrefs = 0;
+}
+
+/*!Show dialog.*/
+void LightApp_PreferencesDlg::show()
+{
+  myPrefs->retrieve();
+  myPrefs->toBackup();
+
+  QtxDialog::show();
+}
+
+/*!Store preferences on accept.*/
+void LightApp_PreferencesDlg::accept()
+{
+  QtxDialog::accept();
+
+  myPrefs->store();
+  mySaved = true;
+}
+
+/*!Reject. Restore preferences from backup.*/
+void LightApp_PreferencesDlg::reject()
+{
+  QtxDialog::reject();
+
+  myPrefs->fromBackup();
+}
+
+/*!Do nothing.*/
+void LightApp_PreferencesDlg::onHelp()
+{
+}
+
+/*!Store preferences on apply.*/
+void LightApp_PreferencesDlg::onApply()
+{
+  myPrefs->store();
+  myPrefs->toBackup();
+  mySaved = true;
+}
diff --git a/src/LightApp/LightApp_PreferencesDlg.h b/src/LightApp/LightApp_PreferencesDlg.h
new file mode 100644 (file)
index 0000000..ea7bf55
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      LightApp_PreferencesDlg.h
+// Author:    Sergey TELKOV
+
+#ifndef LIGHTAPP_PREFERENCESDLG_H
+#define LIGHTAPP_PREFERENCESDLG_H
+
+#include <LightApp.h>
+
+#include <QtxDialog.h>
+
+class LightApp_Preferences;
+
+class LIGHTAPP_EXPORT LightApp_PreferencesDlg : public QtxDialog
+{
+  Q_OBJECT
+
+public:
+  LightApp_PreferencesDlg( LightApp_Preferences*, QWidget* = 0 );
+  virtual ~LightApp_PreferencesDlg();
+
+  virtual void          show();
+  virtual void          accept();
+  virtual void          reject();
+
+  bool                  isSaved() { return mySaved; }
+  void                  setSaved( bool saved ) { mySaved = saved; } 
+
+private slots:
+  void                  onHelp();
+  void                  onApply();
+
+private:
+  LightApp_Preferences* myPrefs;
+  bool                  mySaved;
+};
+
+#endif
diff --git a/src/LightApp/LightApp_Selection.cxx b/src/LightApp/LightApp_Selection.cxx
new file mode 100644 (file)
index 0000000..bca35cf
--- /dev/null
@@ -0,0 +1,246 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+
+#include "LightApp_Selection.h"
+#include "LightApp_SelectionMgr.h"
+#include "LightApp_DataOwner.h"
+#include "LightApp_Study.h"
+#include "LightApp_Application.h"
+#include "LightApp_Displayer.h"
+
+#include "SUIT_Session.h"
+#include "SUIT_ViewWindow.h"
+
+/*!
+  Constructor
+*/
+LightApp_Selection::LightApp_Selection()
+: myStudy( 0 )
+{
+}
+
+/*!
+  Destructor.
+*/
+LightApp_Selection::~LightApp_Selection()
+{
+}
+
+/*!
+  Initialization.
+*/
+void LightApp_Selection::init( const QString& client, LightApp_SelectionMgr* mgr)
+{
+  myPopupClient = client;
+  myStudy = 0;
+  
+  if( mgr )
+  {
+    if( mgr->application() )
+      myStudy = dynamic_cast<LightApp_Study*>( mgr->application()->activeStudy() );
+    if( !myStudy )
+      return;
+
+    //1) to take owners from current popup client
+    SUIT_DataOwnerPtrList sel( true ), cur_sel( true );
+    mgr->selected( sel, client );
+
+    //2) to take such owners from other popup clients that it's entry is different with every entry from current list
+    QPtrList<SUIT_Selector> aSelectors;
+    mgr->selectors( aSelectors );
+    for( SUIT_Selector* selector = aSelectors.first(); selector; selector = aSelectors.next() )
+    {
+      qDebug( selector->type() );
+      if( selector->type()!=client )
+      {
+       mgr->selected( cur_sel, selector->type() );
+       SUIT_DataOwnerPtrList::const_iterator aLIt = cur_sel.begin(), aLLast = cur_sel.end();
+       for( ; aLIt!=aLLast; aLIt++ )
+         sel.append( *aLIt ); //check entry and don't append if such entry is in list already
+      }
+    }
+
+    //3) to analyse owner and fill internal data structures
+    SUIT_DataOwnerPtrList::const_iterator anIt = sel.begin(), aLast = sel.end();
+    QMap<QString,int> entries;
+    QString entry;
+    int num=0;
+    for( ; anIt!=aLast; anIt++ )
+    {
+      LightApp_DataOwner* sowner = dynamic_cast<LightApp_DataOwner*>( (*anIt ).get() );
+      if( sowner )
+      {
+       if( entries.contains( sowner->entry() ) )
+         continue;
+
+        entry = myStudy->referencedToEntry( sowner->entry() );
+       entries.insert( entry, 0 );
+        myEntries.insert( num, entry );
+       myIsReferences.insert( num, sowner->entry() == entry );
+        processOwner( sowner );
+       num++;
+      }
+    }
+  }
+}
+
+/*!
+  Gets count of entries.
+*/
+int LightApp_Selection::count() const
+{
+  return myEntries.count();
+}
+
+/*!
+  Gets QtxValue();
+*/
+QtxValue LightApp_Selection::param( const int ind, const QString& p ) const
+{
+  LightApp_Application* app = dynamic_cast<LightApp_Application*>( myStudy ? myStudy->application() : 0 );
+  if( !( ind>=0 && ind<count() ) || !app )
+    return QtxValue();
+
+  if( p=="isVisible" )
+  {
+    QString mod_name = app->moduleTitle( param( ind, "component" ).toString() );
+    LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mod_name, false );
+    // false in last parameter means that now we doesn't load module, if it isn't loaded
+
+    bool vis = false;
+    if( d )
+      vis = d->IsDisplayed( myEntries[ ind ] );
+    else
+    {
+      LightApp_Displayer local_d;
+      vis = local_d.IsDisplayed( myEntries[ ind ] );
+    }
+    return QtxValue( vis, 0 );
+  }
+
+  else if( p=="component" )
+  {
+    return myStudy->componentDataType( myEntries[ ind ] );
+  }
+  
+  else if( p=="isComponent" )
+  {
+    return QtxValue( myStudy->isComponent( myEntries[ ind ] ), 0 );
+  }
+
+  else if( p=="isReference" )
+    return QtxValue( isReference( ind ), false );
+
+  else if( p=="canBeDisplayed" )
+  {
+    QString mod_name = app->moduleTitle( param( ind, "component" ).toString() );
+    LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mod_name, false );
+    // false in last parameter means that now we doesn't load module, if it isn't loaded
+
+    return QtxValue( d ? d->canBeDisplayed( myEntries[ ind ] ) : true, 0 );
+    //now if displayer is null, it means, that according module isn't loaded, so that we allow to all display/erase
+    //operations under object
+  }
+
+  return QtxValue();
+}
+
+/*!
+  Gets global parameters. client, isActiveView, activeView etc.
+*/
+QtxValue LightApp_Selection::globalParam( const QString& p ) const
+{
+  if      ( p == "client" )        return QtxValue( myPopupClient );
+  else if ( p == "activeModule" )
+  {
+    LightApp_Application* app = dynamic_cast<LightApp_Application*>( myStudy->application() );
+    QString mod_name = app ? QString( app->activeModule()->name() ) : QString::null;
+    //cout << "activeModule : " << mod_name.latin1() << endl;
+    if( !mod_name.isEmpty() )
+      return mod_name;
+    else
+      return QtxValue();
+  }
+  else if ( p == "isActiveView" )  return QtxValue( (bool)activeVW() );
+  else if ( p == "activeView" )    return QtxValue( activeViewType() );
+#ifndef WNT
+  else                             return QtxPopupMgr::Selection::globalParam( p );
+#else
+  else                             return Selection::globalParam( p );
+#endif
+}
+
+/*!
+  Do nothing. To be redefined by successors
+*/
+void LightApp_Selection::processOwner( const LightApp_DataOwner* )
+{
+}
+
+/*!
+  Gets entry with index \a index.
+*/
+QString LightApp_Selection::entry( const int index ) const
+{
+  if ( index >= 0 && index < count() )
+    return myEntries[ index ];
+  return QString();
+}
+
+/*!
+  Returns true if i-th selected object was reference to object with entry( i )
+*/
+bool LightApp_Selection::isReference( const int index ) const
+{
+  if( index >= 0 && index < count() )
+    return myIsReferences[ index ];
+  else
+    return false;
+}
+
+/*!
+  Gets type of active view manager.
+*/
+QString LightApp_Selection::activeViewType() const
+{
+  SUIT_ViewWindow* win = activeVW();
+  if ( win ) {
+    SUIT_ViewManager* vm = win->getViewManager();
+    if ( vm )
+      return vm->getType();
+  }
+  return QString::null;
+}
+
+/*!
+  Gets active view window.
+*/
+SUIT_ViewWindow* LightApp_Selection::activeVW() const
+{
+  SUIT_Session* session = SUIT_Session::session();
+  if ( session ) {
+    SUIT_Application* app = session->activeApplication();
+    if ( app ) {
+      SUIT_Desktop* desk = app->desktop();
+      if ( desk ) 
+       return desk->activeWindow();
+    }
+  }
+  return 0;
+}
diff --git a/src/LightApp/LightApp_Selection.h b/src/LightApp/LightApp_Selection.h
new file mode 100644 (file)
index 0000000..79cc0fa
--- /dev/null
@@ -0,0 +1,70 @@
+//  LightApp_Selection
+//
+//  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : LightApp_Selection.h
+//  Author : Alexander SOLOVYOV
+//  Module : GUI
+//  $Header$
+
+#ifndef LIGHTAPP_SELECTION_HeaderFile
+#define LIGHTAPP_SELECTION_HeaderFile
+
+#include "LightApp.h"
+#include <QtxPopupMgr.h>
+
+class LightApp_SelectionMgr;
+class LightApp_DataOwner;
+class LightApp_Study;
+class SUIT_ViewWindow;
+
+
+class LIGHTAPP_EXPORT LightApp_Selection : public QtxPopupMgr::Selection
+{
+public:
+  LightApp_Selection();
+  virtual ~LightApp_Selection();
+
+  virtual void                   init( const QString&, LightApp_SelectionMgr* );
+  virtual void                   processOwner( const LightApp_DataOwner* );
+
+  virtual int                    count() const;
+  virtual QtxValue               param( const int, const QString& ) const;
+  virtual QtxValue               globalParam( const QString& ) const;
+  void                           setModuleName( const QString );
+
+protected:
+  QString                        entry( const int ) const;
+  bool                           isReference( const int ) const;
+  /*!Gets study.*/
+  LightApp_Study*                study() const { return myStudy; }
+  QString                        activeViewType() const;
+  SUIT_ViewWindow*               activeVW() const;
+
+private:
+  QString                        myPopupClient;
+  QMap<int,QString>              myEntries; // entries of selected objects
+  QMap<int,bool>                 myIsReferences; // whether i-th selected object was a reference
+  LightApp_Study*                myStudy;
+};
+
+#endif
diff --git a/src/LightApp/LightApp_ShowHideOp.cxx b/src/LightApp/LightApp_ShowHideOp.cxx
new file mode 100644 (file)
index 0000000..52f1626
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+
+#include "LightApp_ShowHideOp.h"
+#include "LightApp_Application.h"
+#include "LightApp_DataOwner.h"
+#include "LightApp_Module.h"
+#include "LightApp_Study.h"
+#include "LightApp_Displayer.h"
+#include "CAM_Study.h"
+
+#include "LightApp_SelectionMgr.h"
+#include "LightApp_Selection.h"
+
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+LightApp_ShowHideOp::LightApp_ShowHideOp( ActionType type )
+: LightApp_Operation(),
+  myActionType( type )
+{
+}
+
+LightApp_ShowHideOp::~LightApp_ShowHideOp()
+{
+}
+
+void LightApp_ShowHideOp::startOperation()
+{
+  LightApp_Application* app = dynamic_cast<LightApp_Application*>( application() );
+  LightApp_Study* study = app ? dynamic_cast<LightApp_Study*>( app->activeStudy() ) : 0;
+  if( !app || !study )
+  {
+    abort();
+    return;
+  }
+
+  LightApp_SelectionMgr* mgr = app->selectionMgr();
+  LightApp_Selection sel; sel.init( "", mgr );
+  if( sel.count()==0 && myActionType!=ERASE_ALL )
+  {
+    abort();
+    return;
+  }
+
+  QString mod_name;
+  if( sel.count()>0 )
+  {
+    QString aStr =  sel.param( 0, "component" ).toString();
+    mod_name = app->moduleTitle( aStr );
+  }
+  else if( app->activeModule() )
+    mod_name = app->moduleTitle( app->activeModule()->name() );
+
+  LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mod_name, true );
+  if( !d )
+  {
+    abort();
+    return;
+  }
+
+  if( myActionType==DISPLAY_ONLY || myActionType==ERASE_ALL )
+  {
+    //ERASE ALL
+    QStringList comps;
+    study->components( comps );
+    QStringList::const_iterator anIt = comps.begin(), aLast = comps.end();
+    for( ; anIt!=aLast; anIt++ )
+    {
+      LightApp_Displayer* disp = LightApp_Displayer::FindDisplayer( app->moduleTitle( *anIt ), true );
+      if( disp )
+       disp->EraseAll( false, false, 0 );
+    }
+    if( myActionType==ERASE_ALL )
+    {
+      d->UpdateViewer();
+      commit();
+      return;
+    }
+  }
+
+  SALOME_ListIO selObjs;
+  mgr->selectedObjects( selObjs );
+
+  QStringList entries;
+  SALOME_ListIteratorOfListIO anIt( selObjs );
+  for( ; anIt.More(); anIt.Next() )
+  {
+    if( anIt.Value().IsNull() )
+      continue;
+
+    if( study->isComponent( anIt.Value()->getEntry() ) )
+      study->children( anIt.Value()->getEntry(), entries );
+    else
+      entries.append( anIt.Value()->getEntry() );
+  }
+
+  for( QStringList::const_iterator it = entries.begin(), last = entries.end(); it!=last; it++ )
+  {
+    QString e = study->referencedToEntry( *it );
+    if( myActionType==DISPLAY || myActionType==DISPLAY_ONLY )
+      d->Display( e, false, 0 );
+    else if( myActionType==ERASE )
+      d->Erase( e, false, false, 0 );
+  }
+  d->UpdateViewer();
+  commit();
+}
diff --git a/src/LightApp/Makefile.in b/src/LightApp/Makefile.in
new file mode 100755 (executable)
index 0000000..092b071
--- /dev/null
@@ -0,0 +1,113 @@
+#  File   : Makefile.in
+#  Author : OCC team (OCN)
+#  Module : LightApp
+#  $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@srcdir@/resources
+
+
+@COMMENCE@
+
+# header files 
+EXPORT_HEADERS= LightApp.h \
+               LightApp_AboutDlg.h \
+               LightApp_Application.h \
+               LightApp_DataModel.h \
+               LightApp_DataObject.h \
+               LightApp_DataOwner.h \
+               LightApp_DataSubOwner.h \
+               LightApp_Dialog.h \
+               LightApp_Displayer.h \
+               LightApp_Driver.h \
+               LightApp_GLSelector.h \
+               LightApp_Module.h \
+               LightApp_ModuleDlg.h \
+               LightApp_NameDlg.h \
+               LightApp_OBFilter.h \
+               LightApp_OBSelector.h \
+               LightApp_OCCSelector.h \
+               LightApp_Operation.h \
+               LightApp_Selection.h \
+               LightApp_SelectionMgr.h \
+               LightApp_ShowHideOp.h \
+               LightApp_Study.h \
+               LightApp_SwitchOp.h \
+               LightApp_Preferences.h \
+               LightApp_PreferencesDlg.h \
+               LightApp_RootObject.h \
+               LightApp_UpdateFlags.h \
+               LightApp_VTKSelector.h \
+               LightApp_WidgetContainer.h
+
+# .po files to transform in .qm
+PO_FILES = LightApp_images.po \
+          LightApp_msg_en.po
+
+# Libraries targets
+LIB = libLightApp.la
+
+LIB_SRC= LightApp_AboutDlg.cxx \
+        LightApp_Application.cxx \
+        LightApp_DataModel.cxx \
+        LightApp_DataObject.cxx \
+        LightApp_DataOwner.cxx \
+        LightApp_DataSubOwner.cxx \
+        LightApp_Dialog.cxx \
+        LightApp_Displayer.cxx \
+        LightApp_Driver.cxx \
+        LightApp_GLSelector.cxx \
+        LightApp_Module.cxx \
+        LightApp_ModuleDlg.cxx \
+        LightApp_NameDlg.cxx \
+        LightApp_OBFilter.cxx \
+        LightApp_OBSelector.cxx \
+        LightApp_OCCSelector.cxx \
+        LightApp_Operation.cxx \
+        LightApp_Selection.cxx \
+        LightApp_SelectionMgr.cxx \
+        LightApp_ShowHideOp.cxx \
+        LightApp_Study.cxx \
+        LightApp_SwitchOp.cxx \
+        LightApp_Preferences.cxx \
+        LightApp_PreferencesDlg.cxx \
+        LightApp_VTKSelector.cxx \
+        LightApp_WidgetContainer.cxx
+
+LIB_MOC = LightApp_AboutDlg.h \
+         LightApp_Application.h \
+         LightApp_DataModel.h \
+         LightApp_Dialog.h \
+         LightApp_GLSelector.h \
+         LightApp_OBSelector.h \
+         LightApp_OCCSelector.h \
+         LightApp_Operation.h \
+         LightApp_Module.h \
+         LightApp_ModuleDlg.h \
+         LightApp_NameDlg.h \
+         LightApp_SelectionMgr.h \
+         LightApp_ShowHideOp.h \
+         LightApp_Study.h \
+         LightApp_SwitchOp.h \
+         LightApp_Preferences.h \
+         LightApp_PreferencesDlg.h \
+         LightApp_VTKSelector.h \
+         LightApp_WidgetContainer.h
+
+RESOURCES_FILES = icon_about.png \
+                 icon_applogo.png \
+                 icon_default.png \
+                 icon_module.png \
+                 icon_module_big.png \
+                 icon_select.png \
+                 LightApp.ini \
+                 LightApp.xml
+
+CPPFLAGS+=$(PYTHON_INCLUDES) $(QT_INCLUDES) $(QWT_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES)
+
+LDFLAGS+=$(PYTHON_LIBS) $(QT_MT_LIBS)
+LIBS+= -lsuit -lstd -lCAM -lObjBrowser -lLogWindow $(CAS_KERNEL) -lGLViewer -lOCCViewer -lVTKViewer -lSalomeObject -lSOCC -lSVTK -lSPlot2d -lSUPERVGraph -lPyInterp -lPythonConsole
+
+@CONCLUDE@
diff --git a/src/LightApp/resources/LightApp.xml b/src/LightApp/resources/LightApp.xml
new file mode 100644 (file)
index 0000000..2a4932e
--- /dev/null
@@ -0,0 +1,78 @@
+<document>
+  <section name="desktop" >
+    <parameter name="state"  value="max"/>
+    <parameter name="pos_x"  value="100"/>
+    <parameter name="pos_y"  value="050"/>
+    <parameter name="width"  value="640"/>
+    <parameter name="height" value="480"/>
+  </section>
+  <section name="launch">
+    <parameter name="gui"        value="yes"/>
+    <parameter name="splash"     value="yes"/>
+    <parameter name="file"       value="no"/>
+    <parameter name="key"        value="no"/>
+    <parameter name="interp"     value="no"/>
+    <parameter name="modules"    value="LIGHT"/>
+  </section>
+  <section name="language">
+    <parameter name="language"    value="en"/>
+    <parameter name="translators" value="%P_msg_%L.qm|%P_icons.qm|%P_images.qm"/>
+  </section>
+  <section name="resources">
+    <parameter name="SUIT"         value="${SUITRoot}/resources"/>
+    <parameter name="STD"          value="${SUITRoot}/resources"/>
+    <parameter name="Plot2d"       value="${SUITRoot}/resources"/>
+    <parameter name="SPlot2d"      value="${SUITRoot}/resources"/>
+    <parameter name="GLViewer"     value="${SUITRoot}/resources"/>
+    <parameter name="OCCViewer"    value="${SUITRoot}/resources"/>
+    <parameter name="VTKViewer"    value="${SUITRoot}/resources"/>
+    <parameter name="SalomeApp"    value="${SUITRoot}/resources"/>
+    <parameter name="OB"           value="${SUITRoot}/resources"/>
+    <parameter name="CAM"          value="${SUITRoot}/resources"/>
+    <parameter name="LightApp"     value="${SUITRoot}/resources"/>
+    <parameter name="SVTK"         value="${SUITRoot}/resources"/>
+    <parameter name="LIGHT"        value="${LIGHT_ROOT_DIR}/share/salome/resources"/>
+    <parameter name="ToolsGUI"     value="${SUITRoot}/resources"/>
+  </section>
+  <section name="LIGHT">
+    <parameter name="name"       value="Light"/>
+    <parameter name="icon"       value="LIGHT.png"/>
+  </section>
+
+<!-- values below this line are just an example, they are not used  -->
+  <section name="application">
+    <parameter name="QuickDirList" value=""/>
+    <!-- Here go other common user preferences -->
+  </section>
+  <section name="Study">
+    <parameter value="true" name="store_positions" />
+  </section>
+  <section name="OCCViewer" >
+    <parameter value="35, 136, 145" name="background" />
+    <parameter value="1" name="iso_number_u" />
+    <parameter value="1" name="iso_number_v" />
+    <parameter value="100" name="trihedron_size" />
+ </section>
+ <section name="VTKViewer" >
+    <parameter value="0, 0, 0" name="background" />
+    <parameter value="100" name="trihedron_size" />
+ </section>
+ <section name="Plot2d" >
+    <parameter value="255, 255, 255" name="Background" />
+    <parameter value="1" name="CurveType" />
+    <parameter value="0" name="HorScaleMode" />
+    <parameter value="1" name="LegendPos" />
+    <parameter value="9" name="MarkerSize" />
+    <parameter value="true" name="ShowLegend" />
+    <parameter value="0" name="VerScaleMode" />
+  </section>
+  <section name="SUPERVGraph" >
+    <parameter value="144, 208, 211" name="Background" />
+    <parameter value="63, 213, 255" name="Title" />
+  </section>
+  <!-- Here go optional sections for other modules -->
+  <section name="resources">
+    <parameter name="salome" value="${KERNEL_ROOT_DIR}/share/salome/res"/>
+    <!-- Here go resource directories for other modules -->
+  </section>
+</document>
diff --git a/src/LightApp/resources/LightApp_msg_en.po b/src/LightApp/resources/LightApp_msg_en.po
new file mode 100644 (file)
index 0000000..5c32153
--- /dev/null
@@ -0,0 +1,315 @@
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: example-Qt-message-extraction\n"
+"POT-Creation-Date: 1999-02-23 15:38+0200\n"
+"PO-Revision-Date: 1999-02-23 15:38+0200\n"
+"Last-Translator: \n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+
+//=======================================================================================
+
+msgid "APP_NAME"
+msgstr "SALOME"
+
+msgid "ABOUT_CAPTION"
+msgstr "About %1"
+
+msgid "ABOUT_VERSION"
+msgstr "Version %1"
+
+msgid "ABOUT_COPYRIGHT"
+msgstr "Copyright (C) 2003-2005 OPEN CASCADE, EADS/CCR, LIP6,\nCEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS"
+
+msgid "ABOUT_LICENSE"
+msgstr "GNU LGPL"
+
+//=======================================================================================
+
+msgid "LightApp_Application::ACTIVATING_MODULE"
+msgstr "Trying to activate module \"%1\""
+
+msgid "LightApp_Application::TOT_RENAME"
+msgstr "Rename"
+
+msgid "LightApp_Application::MEN_DESK_RENAME"
+msgstr "&Rename"
+
+msgid "LightApp_Application::PRP_RENAME"
+msgstr "Rename active window"
+
+msgid "LightApp_Application::TOT_DESK_PREFERENCES"
+msgstr "Preferences"
+
+msgid "LightApp_Application::MEN_DESK_PREFERENCES"
+msgstr "Pre&ferences..."
+
+msgid "LightApp_Application::TOT_DESK_MRU"
+msgstr "Most recently used"
+
+msgid "LightApp_Application::MEN_DESK_MRU"
+msgstr "Most recently used"
+
+msgid "LightApp_Application::PRP_DESK_PREFERENCES"
+msgstr "Allow to change the preferences"
+
+msgid "LightApp_Application::INF_TOOLBAR_MODULES"
+msgstr "Modules"
+
+msgid "LightApp_Application::PRP_APP_MODULE"
+msgstr "Switch to SALOME platform neutral point"
+
+msgid "LightApp_Application::PRP_MODULE"
+msgstr "Switch to the module \"%1\""
+
+msgid "LightApp_Application::NEW_WINDOW_0"
+msgstr "&GL view"
+
+msgid "LightApp_Application::NEW_WINDOW_1"
+msgstr "&Plot2d view"
+
+msgid "LightApp_Application::NEW_WINDOW_2"
+msgstr "&OCC view"
+
+msgid "LightApp_Application::NEW_WINDOW_3"
+msgstr "VT&K view"
+
+msgid "LightApp_Application::INF_CANCELLED"
+msgstr "Module activation cancelled"
+
+msgid "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"
+msgstr "External browser \"%1\" can not show help page \"%2\""
+
+msgid "LightApp_Application::DEFINE_EXTERNAL_BROWSER"
+msgstr "Define external browser in preferences"
+
+msgid "LightApp_Application::DATA_MODELS"
+msgstr "Data models"
+
+msgid "LightApp_Application::OBJECT_BROWSER"
+msgstr "Object Browser"
+
+msgid "LightApp_Application::OBJ_BROWSER_NAME"
+msgstr "Object"
+
+msgid "LightApp_Application::LOG_WINDOW"
+msgstr "Message Window"
+
+//=======================================================================================
+
+msgid "LightApp_Application::MEN_DESK_MODULE_HELP"
+msgstr "Module help"
+
+//=======================================================================================
+
+msgid "LightApp_Application::PREFERENCES_NOT_LOADED"
+msgstr "Preferences for module \"<b>%1</b>\" will be available when the module will be loaded"
+
+msgid "LightApp_Application::PREF_CATEGORY_SALOME"
+msgstr "SALOME"
+
+msgid "LightApp_Application::PREF_TAB_GENERAL"
+msgstr "General"
+
+msgid "LightApp_Application::PREF_GROUP_STUDY"
+msgstr "Study properties"
+
+msgid "LightApp_Application::PREF_MULTI_FILE"
+msgstr "Multi file save"
+
+msgid "LightApp_Application::PREF_ASCII_FILE"
+msgstr "ASCII save"
+
+msgid "LightApp_Application::PREF_UNDO_LEVEL"
+msgstr "Undo level"
+
+msgid "LightApp_Application::PREF_STORE_POS"
+msgstr "Store positions of windows"
+
+msgid "LightApp_Application::PREF_GROUP_EXT_BROWSER"
+msgstr "External browser"
+
+msgid "LightApp_Application::PREF_APP"
+msgstr "Application"
+
+msgid "LightApp_Application::PREF_PARAM"
+msgstr "Parameters"
+
+msgid "LightApp_Application::PREF_GROUP_PY_CONSOLE"
+msgstr "Python console properties"
+
+msgid "LightApp_Application::PREF_FONT"
+msgstr "Font"
+
+msgid "LightApp_Application::PREF_TAB_OBJBROWSER"
+msgstr "Object browser"
+
+msgid "LightApp_Application::PREF_OBJ_BROWSER_SETTINGS"
+msgstr "Object browser settings"
+
+msgid "LightApp_Application::PREF_GROUP_DEF_COLUMNS"
+msgstr "Default columns"
+
+msgid "LightApp_Application::PREF_TAB_VIEWERS"
+msgstr "Viewers"
+
+msgid "LightApp_Application::PREF_GROUP_OCCVIEWER"
+msgstr "OCC Viewer 3d"
+
+msgid "LightApp_Application::PREF_GROUP_VTKVIEWER"
+msgstr "VTK Viewer 3d"
+
+msgid "LightApp_Application::PREF_VIEWER_BACKGROUND"
+msgstr "Background color"
+
+msgid "LightApp_Application::PREF_TRIHEDRON_SIZE"
+msgstr "Trihedron size"
+
+msgid "LightApp_Application::PREF_RELATIVE_SIZE"
+msgstr "Relative size"
+
+msgid "LightApp_Application::PREF_ISOS_U"
+msgstr "Number of isolines along U"
+msgid "LightApp_Application::PREF_ISOS_V"
+msgstr "Number of isolines along V"
+
+msgid "LightApp_Application::PREF_TRIHEDRON_SHOW"
+msgstr "Show trihedron"
+
+msgid "LightApp_Application::PREF_GROUP_PLOT2DVIEWER"
+msgstr "Plot2d Viewer"
+
+msgid "LightApp_Application::PREF_SHOW_LEGEND"
+msgstr "Show legend"
+
+msgid "LightApp_Application::PREF_LEGEND_POSITION"
+msgstr "Legend position:"
+
+msgid "LightApp_Application::PREF_LEFT"
+msgstr "Left"
+
+msgid "LightApp_Application::PREF_RIGHT"
+msgstr "Right"
+
+msgid "LightApp_Application::PREF_TOP"
+msgstr "Top"
+
+msgid "LightApp_Application::PREF_BOTTOM"
+msgstr "Bottom"
+
+msgid "LightApp_Application::PREF_CURVE_TYPE"
+msgstr "Curve type:"
+
+msgid "LightApp_Application::PREF_POINTS"
+msgstr "Points"
+
+msgid "LightApp_Application::PREF_LINES"
+msgstr "Lines"
+
+msgid "LightApp_Application::PREF_SPLINE"
+msgstr "Spline"
+
+msgid "LightApp_Application::PREF_MARKER_SIZE"
+msgstr "Marker size:"
+
+msgid "LightApp_Application::PREF_LINEAR"
+msgstr "Linear"
+
+msgid "LightApp_Application::PREF_LOGARITHMIC"
+msgstr "Logarithmic"
+
+msgid "LightApp_Application::PREF_HOR_AXIS_SCALE"
+msgstr "Horizontal axis scale:"
+
+msgid "LightApp_Application::PREF_VERT_AXIS_SCALE"
+msgstr "Vertical axis scale:"
+
+msgid "LightApp_Application::PREF_TAB_DIRECTORIES"
+msgstr "Directories"
+
+msgid "LightApp_Application::PREF_GROUP_DIRECTORIES"
+msgstr "Quick directory list"
+
+msgid "LightApp_Application::MEN_REFRESH"
+msgstr "Refresh"
+
+msgid "LightApp_Application::PREF_GROUP_SUPERV"
+msgstr "Graph Supervisor"
+
+msgid "LightApp_Application::PREF_SUPERV_TITLE_COLOR"
+msgstr "Title color"
+
+msgid "LightApp_Application::PREF_SUPERV_CTRL_COLOR"
+msgstr "Ctrl color"
+
+msgid "LightApp_Application::PREF_AUTO_SIZE"
+msgstr "Auto size for other columns"
+
+msgid "LightApp_Application::PREF_AUTO_SIZE_FIRST"
+msgstr "Auto size for first column"
+
+//=======================================================================================
+
+msgid "LightApp_PreferencesDlg::CAPTION"
+msgstr "Preferences"
+
+//=======================================================================================
+
+msgid "LightApp_Module::TOP_DISPLAY"
+msgstr "Display"
+
+msgid "LightApp_Module::MEN_DISPLAY"
+msgstr "Display"
+
+msgid "LightApp_Module::STB_DISPLAY"
+msgstr "Display"
+
+msgid "LightApp_Module::TOP_ERASE"
+msgstr "Erase"
+
+msgid "LightApp_Module::MEN_ERASE"
+msgstr "Erase"
+
+msgid "LightApp_Module::STB_ERASE"
+msgstr "Erase"
+
+msgid "LightApp_Module::TOP_DISPLAY_ONLY"
+msgstr "Display only"
+
+msgid "LightApp_Module::MEN_DISPLAY_ONLY"
+msgstr "Display only"
+
+msgid "LightApp_Module::STB_DISPLAY_ONLY"
+msgstr "Display only"
+
+msgid "LightApp_Module::TOP_ERASE_ALL"
+msgstr "Erase all"
+
+msgid "LightApp_Module::MEN_ERASE_ALL"
+msgstr "Erase all"
+
+msgid "LightApp_Module::STB_ERASE_ALL"
+msgstr "Erase all"
+//=======================================================================================
+
+
+msgid "LightApp_ModuleDlg::CAPTION"
+msgstr "Activate module"
+
+msgid "LightApp_ModuleDlg::NEW"
+msgstr "&New"
+
+msgid "LightApp_ModuleDlg::OPEN"
+msgstr "&Open"
+
+msgid "LightApp_ModuleDlg::LOAD"
+msgstr "&Load"
+
+msgid "LightApp_ModuleDlg::CANCEL"
+msgstr "&Cancel"
+
+msgid "LightApp_ModuleDlg::ActivateComponent_DESCRIPTION"
+msgstr "Create, open or load study."
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100755 (executable)
index 0000000..332907b
--- /dev/null
@@ -0,0 +1,40 @@
+#  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+#
+#
+#
+#  File   : Makefile.in
+#  Author : Patrick GOLDBRONN (CEA)
+#  Module : SALOME
+# $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+
+@COMMENCE@
+
+SUBDIRS = Qtx DDS QDS SUIT STD CAF CAM SUITApp VTKViewer OCCViewer GLViewer \
+          LogWindow Event OBJECT Prs PyInterp PythonConsole ObjBrowser \
+          RegistryDisplay Plot2d TOOLSGUI SOCC SVTK SPlot2d SUPERVGraph \
+         LightApp Session SalomeApp SALOME_SWIG SALOME_PY SALOME_PYQT Style ResExporter
+
+@MODULE@
diff --git a/src/OCCViewer/Makefile.in b/src/OCCViewer/Makefile.in
new file mode 100755 (executable)
index 0000000..6eb3077
--- /dev/null
@@ -0,0 +1,78 @@
+#  File   : Makefile.in
+#  Author : Vladimir Klyachin (OCN)
+#  Module : OCCViewer
+#  $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@srcdir@/resources
+
+
+@COMMENCE@
+
+# header files 
+EXPORT_HEADERS= OCCViewer_AISSelector.h \
+               OCCViewer_ViewManager.h \
+               OCCViewer_ViewModel.h \
+               OCCViewer_ViewPort3d.h \
+               OCCViewer_ViewPort.h \
+               OCCViewer_ViewWindow.h \
+               OCCViewer_VService.h \
+               OCCViewer_CreateRestoreViewDlg.h \
+               OCCViewer.h
+                    
+# .po files to transform in .qm
+PO_FILES = OCCViewer_images.po \
+          OCCViewer_msg_en.po 
+
+# Libraries targets
+LIB = libOCCViewer.la
+LIB_SRC= OCCViewer_AISSelector.cxx \
+        OCCViewer_ViewManager.cxx \
+        OCCViewer_ViewModel.cxx \
+        OCCViewer_ViewPort3d.cxx \
+        OCCViewer_ViewPort.cxx \
+        OCCViewer_ViewWindow.cxx \
+        OCCViewer_VService.cxx \
+        OCCViewer_CreateRestoreViewDlg.cxx \
+        OCCViewer_ClippingDlg.cxx
+
+LIB_MOC = OCCViewer_AISSelector.h \
+          OCCViewer_ViewModel.h \
+         OCCViewer_ViewPort3d.h \
+         OCCViewer_ViewPort.h \
+         OCCViewer_ViewWindow.h \
+         OCCViewer_ViewManager.h \
+         OCCViewer_CreateRestoreViewDlg.h \
+         OCCViewer_ClippingDlg.h
+
+RESOURCES_FILES = \
+view_back.png \
+view_bottom.png \
+view_camera_dump.png \
+view_clone.png \
+view_clipping.png \
+view_clipping_pressed.png \
+view_fitall.png \
+view_fitarea.png \
+view_front.png \
+view_glpan.png \
+view_left.png \
+view_pan.png \
+view_presets.png \
+view_reset.png \
+view_right.png \
+view_rotate.png \
+view_shoot.png \
+view_top.png \
+view_triedre.png \
+view_zoom.png
+
+CPPFLAGS+=$(QT_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES)
+
+LDFLAGS+=$(OGL_LIBS) $(QT_MT_LIBS) $(CAS_KERNEL) $(CAS_VIEWER) -lsuit
+
+@CONCLUDE@
+
+
diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.cxx b/src/OCCViewer/OCCViewer_ClippingDlg.cxx
new file mode 100644 (file)
index 0000000..c17bfd3
--- /dev/null
@@ -0,0 +1,509 @@
+#include "OCCViewer_ClippingDlg.h"
+
+#include <QtxDblSpinBox.h>
+
+#include "SUIT_Session.h"
+#include "SUIT_ViewWindow.h"
+#include "OCCViewer_ViewWindow.h"
+#include "OCCViewer_ViewPort3d.h"
+
+//#include "utilities.h"
+
+#include <V3d_View.hxx>
+#include <V3d.hxx>
+#include <V3d_Plane.hxx>
+#include <Geom_Plane.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <AIS_ListIteratorOfListOfInteractive.hxx>
+#include <AIS_ListOfInteractive.hxx>
+#include <AIS_InteractiveObject.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <IntAna_IntConicQuad.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Pln.hxx>
+
+// QT Includes
+#include <qapplication.h>
+#include <qgroupbox.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+
+//=================================================================================
+// class    : OCCViewer_ClippingDlg()
+// purpose  : 
+//=================================================================================
+OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, QWidget* parent, const char* name, bool modal, WFlags fl )
+  : QDialog( parent, "OCCViewer_ClippingDlg", modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ), myView( view )
+{
+  setCaption( tr( "Clipping" ) );
+  
+  QVBoxLayout* topLayout = new QVBoxLayout( this );
+  topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
+  
+  /***************************************************************/
+  GroupPoint = new QGroupBox( this, "GroupPoint" );
+  GroupPoint->setTitle( tr("Base point") );
+  GroupPoint->setColumnLayout(0, Qt::Vertical );
+  GroupPoint->layout()->setSpacing( 0 );
+  GroupPoint->layout()->setMargin( 0 );
+  QGridLayout* GroupPointLayout = new QGridLayout( GroupPoint->layout() );
+  GroupPointLayout->setAlignment( Qt::AlignTop );
+  GroupPointLayout->setSpacing( 6 );
+  GroupPointLayout->setMargin( 11 );
+  
+  // Controls
+  const double min = -1e+06;
+  const double max =  1e+06;
+  const double step = 5;
+
+  TextLabelX = new QLabel( GroupPoint, "TextLabelX" );
+  TextLabelX->setText( tr("X:") );
+  GroupPointLayout->addWidget( TextLabelX, 0, 0 );
+  
+  SpinBox_X = new QtxDblSpinBox( min, max, step, GroupPoint, "SpinBox_X" );
+  GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
+
+  TextLabelY = new QLabel( GroupPoint, "TextLabelY" );
+  TextLabelY->setText( tr("Y:") );
+  GroupPointLayout->addWidget( TextLabelY, 0, 2 );
+
+  SpinBox_Y = new QtxDblSpinBox( min, max, step, GroupPoint, "SpinBox_Y" );
+  GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
+
+  TextLabelZ = new QLabel( GroupPoint, "TextLabelZ" );
+  TextLabelZ->setText( tr("Z:") );
+  GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
+
+  SpinBox_Z = new QtxDblSpinBox( min, max, step, GroupPoint, "SpinBox_Z" );
+  GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
+
+  resetButton  = new QPushButton( GroupPoint, "resetButton" );
+  resetButton->setText( tr( "Reset"  ) );
+  GroupPointLayout->addWidget( resetButton, 0, 6 );
+
+  /***************************************************************/
+  GroupDirection = new QGroupBox( this, "GroupDirection" );
+  GroupDirection->setTitle( tr("Direction") );
+  GroupDirection->setColumnLayout(0, Qt::Vertical );
+  GroupDirection->layout()->setSpacing( 0 );
+  GroupDirection->layout()->setMargin( 0 );
+  QGridLayout* GroupDirectionLayout = new QGridLayout( GroupDirection->layout() );
+  GroupDirectionLayout->setAlignment( Qt::AlignTop );
+  GroupDirectionLayout->setSpacing( 6 );
+  GroupDirectionLayout->setMargin( 11 );
+  
+  // Controls
+  TextLabelDx = new QLabel( GroupDirection, "TextLabelDx" );
+  TextLabelDx->setText( tr("Dx:") );
+  GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
+  
+  SpinBox_Dx = new QtxDblSpinBox( min, max, step, GroupDirection, "SpinBox_Dx" );
+  GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
+
+  TextLabelDy = new QLabel( GroupDirection, "TextLabelDy" );
+  TextLabelDy->setText( tr("Dy:") );
+  GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
+  
+  SpinBox_Dy = new QtxDblSpinBox( min, max, step, GroupDirection, "SpinBox_Dy" );
+  GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
+
+  TextLabelDz = new QLabel( GroupDirection, "TextLabelDz" );
+  TextLabelDz->setText( tr("Dz:") );
+  GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
+  
+  SpinBox_Dz = new QtxDblSpinBox( min, max, step, GroupDirection, "SpinBox_Dz" );
+  GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
+
+  invertButton  = new QPushButton( GroupDirection, "invertButton" );
+  invertButton->setText( tr( "Invert"  ) );
+  GroupDirectionLayout->addWidget( invertButton, 0, 6 );
+  DirectionCB = new QComboBox( GroupDirection, "DirectionCB" );
+  DirectionCB->insertItem(tr("CUSTOM"));
+  DirectionCB->insertItem(tr("||X-Y"));
+  DirectionCB->insertItem(tr("||Y-Z"));
+  DirectionCB->insertItem(tr("||Z-X"));
+  GroupDirectionLayout->addMultiCellWidget( DirectionCB, 1, 1, 0, 5 );
+  
+  /***************************************************************/
+  
+  PreviewChB = new QCheckBox( tr("Preview") ,this, "PreviewChB" );
+  PreviewChB->setChecked( true );
+  
+  /***************************************************************/
+  QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
+  GroupButtons->setColumnLayout(0, Qt::Vertical );
+  GroupButtons->layout()->setMargin( 0 ); GroupButtons->layout()->setSpacing( 0 ); 
+  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons->layout() );
+  GroupButtonsLayout->setAlignment( Qt::AlignTop );
+  GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
+  
+  buttonApply = new QPushButton( GroupButtons, "buttonApply" );
+  buttonApply->setText( tr( "BUT_APPLY"  ) );
+  buttonApply->setAutoDefault( TRUE ); 
+  buttonApply->setDefault( TRUE );
+  GroupButtonsLayout->addWidget( buttonApply );
+  
+  GroupButtonsLayout->addStretch();
+  
+  buttonClose = new QPushButton( GroupButtons, "buttonClose" );
+  buttonClose->setText( tr( "BUT_CLOSE"  ) );
+  buttonClose->setAutoDefault( TRUE );
+  GroupButtonsLayout->addWidget( buttonClose );
+  /***************************************************************/
+  
+  topLayout->addWidget( GroupPoint );
+  topLayout->addWidget( GroupDirection );
+  
+  topLayout->addWidget( PreviewChB );
+
+  topLayout->addWidget( GroupButtons );
+
+  /* initializations */
+
+  SpinBox_X->setValue( 0.0 );
+  SpinBox_Y->setValue( 0.0 );
+  SpinBox_Z->setValue( 0.0 );
+
+  SpinBox_Dx->setValue( 1.0 );
+  SpinBox_Dy->setValue( 1.0 );
+  SpinBox_Dz->setValue( 1.0 );
+
+  /* signals and slots connections */
+  connect( resetButton,  SIGNAL (clicked() ), this, SLOT( onReset() ) );
+  connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
+
+  connect( SpinBox_X,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Y,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Z,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+   
+  connect( DirectionCB, SIGNAL ( activated ( int ) ), this, SLOT( onModeChanged( int ) ) ) ;
+
+  connect( PreviewChB, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
+  
+  connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
+  connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
+  
+  myBusy = false;
+}
+
+//=================================================================================
+// function : ~ OCCViewer_ClippingDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg()
+{
+  // no need to delete child widgets, Qt does it all for us
+}
+
+
+//=================================================================================
+// function : closeEvent
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
+{
+  erasePreview();
+  QDialog::closeEvent( e );
+}
+
+
+//=================================================================================
+// function : showEvent
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
+{
+  QDialog::showEvent( e );
+  onPreview( PreviewChB->isChecked() );
+}
+
+
+//=================================================================================
+// function : hideEvent
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
+{
+  erasePreview();
+  QDialog::hideEvent( e );
+}
+
+
+//=================================================================================
+// function : ClickOnClose()
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::ClickOnClose()
+{
+  erasePreview();
+  reject();
+}
+
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::ClickOnApply()
+{
+  qApp->processEvents();
+  QApplication::setOverrideCursor( Qt::WaitCursor );
+  qApp->processEvents();
+  
+  myView->setCuttingPlane( true, SpinBox_X->value() , SpinBox_Y->value() , SpinBox_Z->value(),
+                                SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() );
+  
+  QApplication::restoreOverrideCursor(); 
+
+  erasePreview();
+}
+
+
+//=================================================================================
+// function : onReset()
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::onReset()
+{
+  myBusy = true;
+  SpinBox_X->setValue(0);
+  SpinBox_Y->setValue(0);
+  SpinBox_Z->setValue(0);
+  myBusy = false;
+
+  if ( PreviewChB->isChecked() )
+    {
+      erasePreview();
+      displayPreview();
+    }
+}
+
+
+//=================================================================================
+// function : onInvert()
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::onInvert()
+{
+  double Dx = SpinBox_Dx->value();
+  double Dy = SpinBox_Dy->value();
+  double Dz = SpinBox_Dz->value();
+  
+  myBusy = true;
+  SpinBox_Dx->setValue( -Dx );
+  SpinBox_Dy->setValue( -Dy );
+  SpinBox_Dz->setValue( -Dz );
+  myBusy = false;
+
+  if ( PreviewChB->isChecked() )
+    {
+      erasePreview();
+      displayPreview();
+    }
+}
+
+
+//=================================================================================
+// function : onModeChanged()
+// purpose  :
+//=================================================================================
+void OCCViewer_ClippingDlg::onModeChanged( int mode )
+{
+  bool isUserMode = (mode==0);
+  
+  TextLabelX->setEnabled( isUserMode );
+  TextLabelY->setEnabled( isUserMode );
+  TextLabelZ->setEnabled( isUserMode );
+
+  SpinBox_X->setEnabled( isUserMode );
+  SpinBox_Y->setEnabled( isUserMode );
+  SpinBox_Z->setEnabled( isUserMode );
+
+  TextLabelDx->setEnabled( isUserMode );
+  TextLabelDy->setEnabled( isUserMode );
+  TextLabelDz->setEnabled( isUserMode );
+
+  SpinBox_Dx->setEnabled( isUserMode );
+  SpinBox_Dy->setEnabled( isUserMode );
+  SpinBox_Dz->setEnabled( isUserMode );
+  
+  if ( isUserMode )
+    return;
+
+  double aDx = 0, aDy = 0, aDz = 0;
+
+  if ( mode == 1 )
+    {
+      aDz = 1;
+      TextLabelZ->setEnabled( true );
+      SpinBox_Z->setEnabled( true );
+      SpinBox_Z->setFocus();
+    }
+  else if ( mode == 2 )
+    {
+      aDx = 1;
+      TextLabelX->setEnabled( true );
+      SpinBox_X->setEnabled( true );
+      SpinBox_X->setFocus();
+    }
+  else if ( mode == 3 )
+    {
+      aDy = 1;
+      TextLabelY->setEnabled( true );
+      SpinBox_Y->setEnabled( true );
+      SpinBox_Y->setFocus();
+    }
+  
+  myBusy = true;
+  SpinBox_Dx->setValue( aDx );
+  SpinBox_Dy->setValue( aDy );
+  SpinBox_Dz->setValue( aDz );
+  myBusy = false;
+
+  if ( PreviewChB->isChecked() )
+    {
+      erasePreview();
+      displayPreview();
+    }
+}
+
+
+//================================================================
+// Function : displayPreview
+// Purpose  : 
+//================================================================
+void OCCViewer_ClippingDlg::displayPreview()
+{
+  if ( myBusy || !isValid() )
+    return;
+
+  OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
+  if (!anOCCViewer)
+    return;
+  
+  Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
+
+  double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
+  aXMin = aYMin = aZMin = DBL_MAX;
+  aXMax = aYMax = aZMax = -DBL_MAX;
+
+  bool isFound = false;
+  AIS_ListOfInteractive aList;
+  ic->DisplayedObjects( aList );
+  for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
+  {
+    Handle(AIS_InteractiveObject) anObj = it.Value();
+    if ( !anObj.IsNull() && anObj->HasPresentation() &&
+         !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) )
+    {
+      Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
+      if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() )
+      {
+        isFound = true;
+        double xmin, ymin, zmin, xmax, ymax, zmax;
+        aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
+        aXMin = QMIN( aXMin, xmin );  aXMax = QMAX( aXMax, xmax );
+        aYMin = QMIN( aYMin, ymin );  aYMax = QMAX( aYMax, ymax );
+        aZMin = QMIN( aZMin, zmin );  aZMax = QMAX( aZMax, zmax );
+      }
+    }
+  }
+
+  double aSize = 50;
+  
+  gp_Pnt aBasePnt( SpinBox_X->value(),  SpinBox_Y->value(),  SpinBox_Z->value() );
+  gp_Dir aNormal( SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() );
+  gp_Pnt aCenter = aBasePnt;
+  
+  if ( isFound )
+    {
+      // compute clipping plane size
+      aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
+      double aDiag = aCenter.Distance(gp_Pnt(aXMax, aYMax, aZMax ))*2;
+      aSize = aDiag * 1.1;
+
+      // compute clipping plane center ( redefine the base point )
+      IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
+      
+      intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
+      if ( intersector.IsDone() && intersector.NbPoints() == 1 )
+       aBasePnt = intersector.Point( 1 );
+    }
+  
+  myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) );
+  myPreviewPlane->SetSize( aSize, aSize );
+  
+  ic->Display( myPreviewPlane, 1, -1, false );
+  ic->SetWidth( myPreviewPlane, 10, false );
+  ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
+  ic->SetTransparency( myPreviewPlane, 0.5, false );
+  ic->SetColor( myPreviewPlane, Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
+  
+  anOCCViewer->update();
+}
+
+
+//================================================================
+// Function : erasePreview
+// Purpose  : 
+//================================================================
+void OCCViewer_ClippingDlg::erasePreview ()
+{
+  OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
+  if (!anOCCViewer)
+    return;
+  
+  Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
+  
+  if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) )
+    {
+      ic->Erase( myPreviewPlane, false, false );
+      ic->Remove( myPreviewPlane, false );
+      myPreviewPlane.Nullify();
+    }
+  
+  anOCCViewer->update();
+}
+
+
+//================================================================
+// Function : onValueChanged
+// Purpose  : 
+//================================================================
+void OCCViewer_ClippingDlg::onValueChanged()
+{
+  if ( PreviewChB->isChecked() )
+    {
+      erasePreview();
+      displayPreview();
+    }
+}
+
+
+//================================================================
+// Function : onPreview
+// Purpose  : 
+//================================================================
+void OCCViewer_ClippingDlg::onPreview( bool on )
+{
+  erasePreview();
+
+  if ( on ) 
+    displayPreview();
+}
+
+//================================================================
+// Function : onPreview
+// Purpose  : 
+//================================================================
+bool OCCViewer_ClippingDlg::isValid()
+{
+  return ( SpinBox_Dx->value()!=0 || SpinBox_Dy->value()!=0 || SpinBox_Dz->value()!=0 );
+}
diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.h b/src/OCCViewer/OCCViewer_ClippingDlg.h
new file mode 100644 (file)
index 0000000..e46903a
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef OCCVIEWER_CLIPPINGDLG_H
+#define OCCVIEWER_CLIPPINGDLG_H
+
+#include "OCCViewer.h"
+
+#include <qdialog.h>
+
+#include <AIS_Plane.hxx>
+
+class QGroupBox;
+class QLabel;
+class QPushButton;
+class QComboBox;
+class QCheckBox;
+class QtxDblSpinBox;
+
+class OCCViewer_ViewWindow;
+
+
+//=================================================================================
+// class    : OCCViewer_ClippingDlg
+// purpose  :
+//=================================================================================
+class OCCViewer_ClippingDlg : public QDialog
+{
+    Q_OBJECT
+    
+    public:
+    OCCViewer_ClippingDlg(OCCViewer_ViewWindow* , QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0);
+    ~OCCViewer_ClippingDlg();
+    
+private :
+
+    virtual void closeEvent( QCloseEvent* e );
+    virtual void showEvent ( QShowEvent * );
+    virtual void hideEvent ( QHideEvent * );
+    void displayPreview();
+    void erasePreview();
+
+    bool isValid();
+     
+    QGroupBox* GroupPoint;
+    QLabel* TextLabelX;
+    QLabel* TextLabelY;
+    QLabel* TextLabelZ;
+    QtxDblSpinBox* SpinBox_X;
+    QtxDblSpinBox* SpinBox_Y;
+    QtxDblSpinBox* SpinBox_Z;
+    QPushButton* resetButton;
+    
+    QGroupBox* GroupDirection;
+    QLabel* TextLabelDx;
+    QLabel* TextLabelDy;
+    QLabel* TextLabelDz;
+    QtxDblSpinBox* SpinBox_Dx;
+    QtxDblSpinBox* SpinBox_Dy;
+    QtxDblSpinBox* SpinBox_Dz;
+    QPushButton* invertButton;
+    
+    QComboBox* DirectionCB;
+
+    QCheckBox* PreviewChB;
+
+    QPushButton*    buttonApply;
+    QPushButton*    buttonClose;
+    
+    OCCViewer_ViewWindow* myView;
+
+    Handle(AIS_Plane) myPreviewPlane;
+    
+    bool myBusy;
+    
+private slots:
+  void ClickOnApply();
+  void ClickOnClose();
+
+  void onReset();
+  void onInvert();
+  void onModeChanged( int mode );
+  void onValueChanged();
+  void onPreview( bool on );
+};
+
+#endif // OCCVIEWER_CLIPPINGDLG_H
diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx
new file mode 100755 (executable)
index 0000000..216c9ec
--- /dev/null
@@ -0,0 +1,498 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+
+#include "OCCViewer_ViewModel.h"
+#include "OCCViewer_ViewWindow.h"
+#include "OCCViewer_VService.h"
+#include "OCCViewer_ViewPort3d.h"
+
+#include "SUIT_ViewWindow.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_Session.h"
+
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qcolordialog.h>
+#include <qpalette.h>
+#include <qpopupmenu.h>
+
+#include <AIS_Axis.hxx>
+#include <AIS_Drawer.hxx>
+#include <AIS_ListIteratorOfListOfInteractive.hxx>
+
+#include <Geom_Axis2Placement.hxx>
+#include <Prs3d_DatumAspect.hxx>
+#include <Prs3d_LineAspect.hxx>
+
+OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron )
+: SUIT_ViewModel(),
+myBgColor( Qt::black )
+{
+  // init CasCade viewers
+  myV3dViewer = OCCViewer_VService::Viewer3d( "", (short*) "Viewer3d", "", 1000.,
+                                              V3d_XposYnegZpos, true, true );
+
+  myV3dViewer->Init();
+
+  myV3dCollector = OCCViewer_VService::Viewer3d( "", (short*) "Collector3d", "", 1000.,
+                                                 V3d_XposYnegZpos, true, true );
+  myV3dCollector->Init();
+
+  // init selector
+  myAISContext = new AIS_InteractiveContext( myV3dViewer, myV3dCollector);
+
+  myAISContext->SelectionColor( Quantity_NOC_WHITE );
+  
+  // display isoline on planar faces (box for ex.)
+  myAISContext->IsoOnPlane( true );
+
+  clearViewAspects();
+
+  /* create trihedron */
+  if( DisplayTrihedron )
+  {
+    Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(gp::XOY());
+    myTrihedron = new AIS_Trihedron(anAxis);
+    myTrihedron->SetInfiniteState( Standard_True );
+
+    Quantity_Color Col(193/255., 205/255., 193/255., Quantity_TOC_RGB);
+    //myTrihedron->SetColor( Col );
+    myTrihedron->SetArrowColor( Col.Name() );
+    myTrihedron->SetSize(100);
+    Handle(AIS_Drawer) drawer = myTrihedron->Attributes();
+    if (drawer->HasDatumAspect()) {
+        Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect();
+        daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB));
+        daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB));
+        daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB));
+    }
+
+    myAISContext->Display(myTrihedron);
+    myAISContext->Deactivate(myTrihedron);
+  }
+
+  // selection
+  mySelectionEnabled = true;
+  myMultiSelectionEnabled = true;
+}
+
+
+OCCViewer_Viewer::~OCCViewer_Viewer() 
+{
+}
+
+QColor OCCViewer_Viewer::backgroundColor() const
+{
+  return myBgColor;
+}
+
+void OCCViewer_Viewer::setBackgroundColor( const QColor& c )
+{
+  if ( c.isValid() )
+    myBgColor = c;
+}
+
+void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view )
+{
+  if ( view ) {
+    view->initLayout();
+    
+    OCCViewer_ViewPort3d* vp3d = view->getViewPort();
+    if ( vp3d )
+      vp3d->setBackgroundColor( myBgColor );
+  }
+}
+
+
+SUIT_ViewWindow* OCCViewer_Viewer::createView( SUIT_Desktop* theDesktop )
+{
+  OCCViewer_ViewWindow* view = new OCCViewer_ViewWindow(theDesktop, this);
+  initView( view );
+  return view;
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::setViewManager(SUIT_ViewManager* theViewManager)
+{
+  SUIT_ViewModel::setViewManager(theViewManager);
+  if (theViewManager) {
+    connect(theViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
+            this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
+
+    connect(theViewManager, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)), 
+            this, SLOT(onMouseMove(SUIT_ViewWindow*, QMouseEvent*)));
+
+    connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), 
+            this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
+  }
+}
+
+
+//*********************************************************************
+void OCCViewer_Viewer::onMousePress(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
+{
+  myStartPnt.setX(theEvent->x()); myStartPnt.setY(theEvent->y());
+}
+
+
+//*********************************************************************
+void OCCViewer_Viewer::onMouseMove(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
+{
+  if (!mySelectionEnabled) return;
+  if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
+
+  OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
+  if ( isSelectionEnabled() )
+    myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView->getViewPort()->getView());
+}
+
+
+//*********************************************************************
+void OCCViewer_Viewer::onMouseRelease(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
+{
+  if (!mySelectionEnabled) return;
+  if (theEvent->button() != Qt::LeftButton) return;
+  if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
+
+
+  myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y());
+  OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
+  bool aHasShift = (theEvent->state() & Qt::ShiftButton);
+
+  if (myStartPnt == myEndPnt)
+  {
+    if (aHasShift && myMultiSelectionEnabled)
+      myAISContext->ShiftSelect();
+    else
+      myAISContext->Select();
+  }
+  else
+  {
+    if (aHasShift && myMultiSelectionEnabled)
+      myAISContext->ShiftSelect(myStartPnt.x(), myStartPnt.y(),
+                                myEndPnt.x(), myEndPnt.y(),
+                                aView->getViewPort()->getView(), Standard_False );
+    else
+      myAISContext->Select(myStartPnt.x(), myStartPnt.y(),
+                           myEndPnt.x(), myEndPnt.y(),
+                           aView->getViewPort()->getView(), Standard_False );
+
+    int Nb = myAISContext->NbSelected();
+    if( Nb>1 && !myMultiSelectionEnabled )
+    {
+        myAISContext->InitSelected();
+        Handle( SelectMgr_EntityOwner ) anOwner = myAISContext->SelectedOwner();
+        if( !anOwner.IsNull() )
+        {
+            myAISContext->ClearSelected( Standard_False );
+            myAISContext->AddOrRemoveSelected( anOwner, Standard_False );
+        }
+    }
+
+    myAISContext->UpdateCurrentViewer();
+  }
+  emit selectionChanged();
+}
+
+
+//*********************************************************************
+void OCCViewer_Viewer::enableSelection(bool isEnabled)
+{
+  mySelectionEnabled = isEnabled;
+  //!! To be done for view windows
+  if ( !myViewManager )
+    return;
+
+  QPtrVector<SUIT_ViewWindow> wins = myViewManager->getViews();
+  for ( int i = 0; i < wins.count(); i++ )
+  {
+    OCCViewer_ViewWindow* win = ::qt_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
+    if ( win )
+      win->updateEnabledDrawMode();
+  }
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::enableMultiselection(bool isEnable)
+{
+  myMultiSelectionEnabled = isEnable;
+  //!! To be done for view windows
+  if ( !myViewManager )
+    return;
+
+  QPtrVector<SUIT_ViewWindow> wins = myViewManager->getViews();
+  for ( int i = 0; i < wins.count(); i++ )
+  {
+    OCCViewer_ViewWindow* win = ::qt_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
+    if ( win )
+      win->updateEnabledDrawMode();
+  }
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::contextMenuPopup(QPopupMenu* thePopup)
+{
+  thePopup->insertItem( tr( "MEN_DUMP_VIEW" ), this, SLOT( onDumpView() ) );
+  thePopup->insertItem( tr( "MEN_CHANGE_BACKGROUD" ), this, SLOT( onChangeBgColor() ) );
+
+  thePopup->insertSeparator();
+
+  OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
+  if ( aView && !aView->getToolBar()->isVisible() )
+    thePopup->insertItem( tr( "MEN_SHOW_TOOLBAR" ), this, SLOT( onShowToolbar() ) );
+}
+
+void OCCViewer_Viewer::onDumpView()
+{
+  OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
+  if ( aView )
+    aView->onDumpView();
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::onChangeBgColor()
+{
+  OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
+  if( !aView )
+    return;
+  OCCViewer_ViewPort3d* aViewPort3d = aView->getViewPort();
+  if( !aViewPort3d )
+    return;
+  QColor aColorActive = aViewPort3d->backgroundColor();
+
+  QColor selColor = QColorDialog::getColor( aColorActive, aView);
+  if ( selColor.isValid() )
+    aViewPort3d->setBackgroundColor(selColor);
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::onShowToolbar() {
+  OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
+  if ( aView )
+    aView->getToolBar()->show();    
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::update()
+{
+  if (!myV3dViewer.IsNull())
+    myV3dViewer->Update();
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::getSelectedObjects(AIS_ListOfInteractive& theList)
+{
+  theList.Clear();
+  for (myAISContext->InitSelected(); myAISContext->MoreSelected(); myAISContext->NextSelected())
+    theList.Append(myAISContext->SelectedInteractive());
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::setObjectsSelected(const AIS_ListOfInteractive& theList)
+{
+  AIS_ListIteratorOfListOfInteractive aIt;
+  for (aIt.Initialize(theList); aIt.More(); aIt.Next())
+    myAISContext->SetSelected(aIt.Value(), false);
+  myAISContext->UpdateCurrentViewer();
+}
+
+//*********************************************************************
+void OCCViewer_Viewer::performSelectionChanged()
+{
+    emit selectionChanged();
+}
+
+//****************************************************************
+
+void OCCViewer_Viewer::onClearViewAspects()
+{
+    clearViewAspects();
+}
+
+//****************************************************************
+
+void OCCViewer_Viewer::clearViewAspects()
+{
+       myViewAspects.clear();
+}
+
+//****************************************************************
+
+const viewAspectList& OCCViewer_Viewer::getViewAspects()
+{
+       return myViewAspects;
+}
+
+//****************************************************************
+
+void OCCViewer_Viewer::appendViewAspect( const viewAspect& aParams )
+{
+       myViewAspects.append( aParams );
+}
+
+//****************************************************************
+
+void OCCViewer_Viewer::updateViewAspects( const viewAspectList& aViewList )
+{
+       myViewAspects = aViewList;
+}
+
+bool OCCViewer_Viewer::highlight( const Handle(AIS_InteractiveObject)& obj,
+                                  bool hilight, bool update )
+{
+  bool isInLocal = myAISContext->HasOpenedContext();
+  if( !obj.IsNull() )
+    if( !isInLocal )
+    {
+      if ( hilight && !myAISContext->IsSelected( obj ) )
+        myAISContext->AddOrRemoveCurrentObject( obj, false );
+      else if ( !hilight && myAISContext->IsSelected( obj ) )
+        myAISContext->AddOrRemoveCurrentObject( obj, false );
+    }
+
+  if ( update )
+    myV3dViewer->Redraw();
+    
+  return false;
+}
+
+bool OCCViewer_Viewer::unHighlightAll( bool updateviewer )
+{
+  if ( myAISContext->HasOpenedContext() )
+    myAISContext->ClearSelected( updateviewer );
+  else
+    myAISContext->ClearCurrents( updateviewer );
+  return false;
+}
+
+bool OCCViewer_Viewer::isInViewer( const Handle(AIS_InteractiveObject)& obj,
+                                   bool onlyInViewer )
+{
+  AIS_ListOfInteractive List;
+  myAISContext->DisplayedObjects(List);
+
+  if( !onlyInViewer )
+  {
+    AIS_ListOfInteractive List1;
+    myAISContext->ObjectsInCollector(List1);
+    List.Append(List1);
+  }
+
+  AIS_ListIteratorOfListOfInteractive ite(List);
+  for ( ; ite.More(); ite.Next() )
+    if( ite.Value()==obj )
+      return true;
+
+  return false;
+}
+
+bool OCCViewer_Viewer::isVisible( const Handle(AIS_InteractiveObject)& obj )
+{
+  return myAISContext->IsDisplayed( obj );
+}
+
+void OCCViewer_Viewer::setColor( const Handle(AIS_InteractiveObject)& obj,
+                                 const QColor& color,
+                                 bool update )
+{
+  if( !obj.IsNull() )
+  {
+    Quantity_Color CSFColor = Quantity_Color ( color.red() / 255.,
+                                               color.green() / 255.,
+                                               color.blue() / 255.,
+                                               Quantity_TOC_RGB );
+    obj->SetColor( CSFColor );
+  }
+
+  if( update )
+    myV3dViewer->Update();
+}
+
+void OCCViewer_Viewer::switchRepresentation( const Handle(AIS_InteractiveObject)& obj,
+                                             int mode, bool update )
+{
+  myAISContext->SetDisplayMode( obj, (Standard_Integer)mode, true );
+  if( update )
+    myV3dViewer->Update();
+}
+
+void OCCViewer_Viewer::setTransparency( const Handle(AIS_InteractiveObject)& obj,
+                                        float trans, bool update )
+{
+  myAISContext->SetTransparency( obj, trans, false );
+  myAISContext->Redisplay( obj, Standard_False, Standard_True );
+  if( update )
+    myV3dViewer->Update();
+}
+
+//****************************************************************
+void OCCViewer_Viewer::toggleTrihedron()
+{
+  setTrihedronShown( !isTrihedronVisible() );
+}
+
+bool OCCViewer_Viewer::isTrihedronVisible() const
+{
+  return !myTrihedron.IsNull() && !myAISContext.IsNull() && myAISContext->IsDisplayed( myTrihedron );
+}
+
+void OCCViewer_Viewer::setTrihedronShown( const bool on )
+{
+  if ( myTrihedron.IsNull() )
+    return;
+
+  if ( on )
+    myAISContext->Display( myTrihedron );
+  else
+    myAISContext->Erase( myTrihedron );
+}
+
+int OCCViewer_Viewer::trihedronSize() const
+{
+  int sz = 0;
+  if ( !myTrihedron.IsNull() )
+    sz = (int)myTrihedron->Size();
+  return sz;
+}
+
+void OCCViewer_Viewer::setTrihedronSize( const int sz )
+{
+  if ( !myTrihedron.IsNull() )
+    myTrihedron->SetSize( sz );
+}
+
+void OCCViewer_Viewer::setIsos( const int u, const int v )
+{
+  Handle(AIS_InteractiveContext) ic = getAISContext();
+  if ( ic.IsNull() )
+  return;
+
+  ic->SetIsoNumber( u, AIS_TOI_IsoU );
+  ic->SetIsoNumber( v, AIS_TOI_IsoV );
+}
+
+void OCCViewer_Viewer::isos( int& u, int& v ) const
+{
+  Handle(AIS_InteractiveContext) ic = getAISContext();
+  if ( !ic.IsNull() )
+  {
+    u = ic->IsoNumber( AIS_TOI_IsoU );
+    v = ic->IsoNumber( AIS_TOI_IsoV );
+  }
+}
diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx
new file mode 100755 (executable)
index 0000000..4900fd9
--- /dev/null
@@ -0,0 +1,982 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// OCCViewer_ViewWindow.cxx: implementation of the OCCViewer_ViewWindow class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "OCCViewer_ViewWindow.h"
+#include "OCCViewer_ViewModel.h"
+#include "OCCViewer_ViewPort3d.h"
+#include "OCCViewer_CreateRestoreViewDlg.h"
+#include "OCCViewer_ClippingDlg.h"
+
+#include "SUIT_Desktop.h"
+#include "SUIT_Session.h"
+#include "SUIT_ToolButton.h"
+
+#include "SUIT_Tools.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_MessageBox.h"
+
+#include <qptrlist.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qcolor.h>
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qdatetime.h>
+#include <qimage.h>
+
+#include <V3d_Plane.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pln.hxx>
+
+const char* imageZoomCursor[] = { 
+"32 32 3 1",
+". c None",
+"a c #000000",
+"# c #ffffff",
+"................................",
+"................................",
+".#######........................",
+"..aaaaaaa.......................",
+"................................",
+".............#####..............",
+"...........##.aaaa##............",
+"..........#.aa.....a#...........",
+".........#.a.........#..........",
+".........#a..........#a.........",
+"........#.a...........#.........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+".........#...........#.a........",
+".........#a..........#a.........",
+".........##.........#.a.........",
+"........#####.....##.a..........",
+".......###aaa#####.aa...........",
+"......###aa...aaaaa.......#.....",
+".....###aa................#a....",
+"....###aa.................#a....",
+"...###aa...............#######..",
+"....#aa.................aa#aaaa.",
+".....a....................#a....",
+"..........................#a....",
+"...........................a....",
+"................................",
+"................................",
+"................................",
+"................................"};
+
+const char* imageRotateCursor[] = { 
+"32 32 3 1",
+". c None",
+"a c #000000",
+"# c #ffffff",
+"................................",
+"................................",
+"................................",
+"................................",
+"........#.......................",
+".......#.a......................",
+"......#######...................",
+".......#aaaaa#####..............",
+"........#..##.a#aa##........##..",
+".........a#.aa..#..a#.....##.aa.",
+".........#.a.....#...#..##.aa...",
+".........#a.......#..###.aa.....",
+"........#.a.......#a..#aa.......",
+"........#a.........#..#a........",
+"........#a.........#a.#a........",
+"........#a.........#a.#a........",
+"........#a.........#a.#a........",
+".........#.........#a#.a........",
+"........##a........#a#a.........",
+"......##.a#.......#.#.a.........",
+"....##.aa..##.....##.a..........",
+"..##.aa.....a#####.aa...........",
+"...aa.........aaa#a.............",
+"................#.a.............",
+"...............#.a..............",
+"..............#.a...............",
+"...............a................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................"};
+
+const char* imageCrossCursor[] = { 
+  "32 32 3 1",
+  ". c None",
+  "a c #000000",
+  "# c #ffffff",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "...............#................",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  ".......#################........",
+  "........aaaaaaa#aaaaaaaaa.......",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "................a...............",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................"};
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+OCCViewer_ViewWindow::OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel)
+: SUIT_ViewWindow(theDesktop)
+{
+  myModel = theModel;
+  myRestoreFlag = 0;
+  myEnableDrawMode = false;
+  updateEnabledDrawMode();
+  myClippingDlg = 0;
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::initLayout()
+{
+  myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC );
+  myViewPort->setBackgroundColor(black);
+  myViewPort->installEventFilter(this);
+       setCentralWidget(myViewPort);
+  myOperation = NOTHING;
+
+  setTransformRequested ( NOTHING );
+  setTransformInProcess ( false );
+
+  myToolBar = new QToolBar(this);
+  myToolBar->setCloseMode(QDockWindow::Undocked);
+  myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
+
+  createActions();
+  createToolBar();
+}
+
+//****************************************************************
+OCCViewer_ViewWindow::OperationType OCCViewer_ViewWindow::getButtonState(QMouseEvent* theEvent)
+{
+  OperationType aOp = NOTHING;
+  if( (theEvent->state() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::ZOOM]) &&
+      (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::ZOOM]) )
+    aOp = ZOOMVIEW;
+  else if( (theEvent->state() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::PAN]) && 
+           (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::PAN]) )
+    aOp = PANVIEW;
+  else if( (theEvent->state()  == SUIT_ViewModel::myStateMap[SUIT_ViewModel::ROTATE]) &&
+           (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::ROTATE]) )
+    aOp = ROTATE;
+
+  return aOp;
+}
+
+//****************************************************************
+bool OCCViewer_ViewWindow::eventFilter(QObject* watched, QEvent* e)
+{
+  if ( watched == myViewPort ) {
+    int aType = e->type();
+    switch(aType) {
+    case QEvent::MouseButtonPress:
+      vpMousePressEvent((QMouseEvent*) e);
+      return true;
+
+    case QEvent::MouseButtonRelease:
+      vpMouseReleaseEvent((QMouseEvent*) e);
+      return true;
+
+    case QEvent::MouseMove:
+      vpMouseMoveEvent((QMouseEvent*) e);
+      return true;
+
+    case QEvent::MouseButtonDblClick:
+      emit mouseDoubleClicked(this, (QMouseEvent*)e);
+      return true;
+
+    case QEvent::Wheel:
+      {
+        QWheelEvent* aEvent = (QWheelEvent*) e;
+        double aDelta = aEvent->delta();
+        double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
+        myViewPort->getView()->SetZoom(aScale);
+      }
+      return true;
+
+    case QEvent::ContextMenu:
+      {
+        QContextMenuEvent * aEvent = (QContextMenuEvent*)e;
+        if ( aEvent->reason() != QContextMenuEvent::Mouse )
+          emit contextMenuRequested( aEvent );
+      }
+      return true;
+
+    default:
+      break;
+    }
+  }
+  return SUIT_ViewWindow::eventFilter(watched, e);
+}
+
+void OCCViewer_ViewWindow::updateEnabledDrawMode()
+{
+  if ( myModel )
+    myEnableDrawMode = myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
+{
+  myStartX = theEvent->x();
+  myStartY = theEvent->y();
+  switch ( myOperation ) {
+  case WINDOWFIT:
+    if ( theEvent->button() == Qt::LeftButton )
+      emit vpTransformationStarted ( WINDOWFIT );
+    break;    
+   
+  case PANGLOBAL:
+    if ( theEvent->button() == Qt::LeftButton )
+      emit vpTransformationStarted ( PANGLOBAL );
+    break;    
+    
+  case ZOOMVIEW:
+    if ( theEvent->button() == Qt::LeftButton )
+      emit vpTransformationStarted ( ZOOMVIEW );
+    break;
+    
+  case PANVIEW:
+    if ( theEvent->button() == Qt::LeftButton )
+      emit vpTransformationStarted ( PANVIEW );
+    break;
+
+  case ROTATE:
+    if ( theEvent->button() == Qt::LeftButton ) {
+           myViewPort->startRotation(myStartX, myStartY);
+           emit vpTransformationStarted ( ROTATE );
+         }
+    break;
+      
+  default:
+  /*  Try to activate a transformation */
+    switch ( getButtonState(theEvent) ) {
+    case ZOOMVIEW:
+           activateZoom();
+      break;
+    case PANVIEW:
+           activatePanning();
+      break;
+    case ROTATE:
+           activateRotation();
+           myViewPort->startRotation(myStartX, myStartY);
+      break;
+    default:
+      emit mousePressed(this, theEvent);
+      break;
+    }
+    /* notify that we start a transformation */
+    if ( transformRequested() ) 
+           emit vpTransformationStarted ( myOperation );
+  }
+  if ( transformRequested() ) 
+    setTransformInProcess( true );              
+}
+
+
+//****************************************************************
+void OCCViewer_ViewWindow::activateZoom()
+{
+  if ( !transformRequested() && !myCursorIsHand )
+    myCursor = cursor();               /* save old cursor */
+  
+  if ( myOperation != ZOOMVIEW ) {
+    QPixmap zoomPixmap (imageZoomCursor);
+    QCursor zoomCursor (zoomPixmap);
+    setTransformRequested ( ZOOMVIEW );                
+    setCursor( zoomCursor );
+  }
+}
+
+
+//****************************************************************
+/*!
+    Activates 'panning' transformation
+*/
+void OCCViewer_ViewWindow::activatePanning()
+{
+  if ( !transformRequested() && !myCursorIsHand )
+    myCursor = cursor();               // save old cursor 
+  
+  if ( myOperation != PANVIEW ) {
+    QCursor panCursor (Qt::SizeAllCursor);
+    setTransformRequested ( PANVIEW );
+    setCursor( panCursor );
+  }
+}
+
+//****************************************************************
+/*!
+    Activates 'rotation' transformation
+*/
+void OCCViewer_ViewWindow::activateRotation()
+{
+  if ( !transformRequested() && !myCursorIsHand )
+    myCursor = cursor();               // save old cursor 
+  
+  if ( myOperation != ROTATE ) {
+    QPixmap rotatePixmap (imageRotateCursor);
+    QCursor rotCursor (rotatePixmap);
+    setTransformRequested ( ROTATE );
+    setCursor( rotCursor );    
+  }
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::activateGlobalPanning()
+{
+  Handle(V3d_View) aView3d = myViewPort->getView();
+  if ( !aView3d.IsNull() ) {
+    QPixmap globalPanPixmap (imageCrossCursor);
+    QCursor glPanCursor (globalPanPixmap);
+    myCurScale = aView3d->Scale();
+    aView3d->FitAll(0.01, false);
+    myCursor = cursor();               // save old cursor 
+    myViewPort->fitAll(); // fits view before selecting a new scene center 
+    setTransformRequested( PANGLOBAL );
+    setCursor( glPanCursor );
+  }
+}
+
+//****************************************************************
+/*!
+    Activates 'fit' transformation
+*/
+void OCCViewer_ViewWindow::activateWindowFit()
+{
+  if ( !transformRequested() && !myCursorIsHand )
+    myCursor = cursor();               /* save old cursor */
+
+  if ( myOperation != WINDOWFIT ) {
+    QCursor handCursor (Qt::PointingHandCursor);
+    setTransformRequested ( WINDOWFIT );               
+    setCursor ( handCursor );
+    myCursorIsHand = true;
+  }
+}
+
+//****************************************************************
+/*!
+    Sets the active operation 'op'
+*/
+void OCCViewer_ViewWindow::setTransformRequested ( OperationType op )
+{    
+  myOperation = op;
+  myViewPort->setMouseTracking( myOperation == NOTHING );  
+}
+
+
+//****************************************************************/
+void OCCViewer_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
+{
+  myCurrX = theEvent->x();
+  myCurrY = theEvent->y();
+  switch (myOperation) {
+  case ROTATE:
+    myViewPort->rotate(myCurrX, myCurrY);
+    break;
+    
+  case ZOOMVIEW:
+    myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
+    myStartX = myCurrX;
+    myStartY = myCurrY;
+    break;
+    
+  case PANVIEW:
+    myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
+    myStartX = myCurrX;
+    myStartY = myCurrY;
+    break;
+    
+/*    case WINDOWFIT:
+    myDrawRect = true;
+    repaint();
+    break;
+*/      
+  case PANGLOBAL:
+    break;
+    
+  default:
+    int aState = theEvent->state();
+    //int aButton = theEvent->button();
+    if ( aState == Qt::LeftButton ||
+       aState == ( Qt::LeftButton | Qt::ShiftButton) ) {
+      myDrawRect = myEnableDrawMode;
+      if ( myDrawRect ) {
+        drawRect();
+       if ( !myCursorIsHand )  {   // we are going to sketch a rectangle
+          QCursor handCursor (Qt::PointingHandCursor);
+         myCursorIsHand = true;                
+         myCursor = cursor();
+         setCursor( handCursor );
+       }
+      }
+    } 
+    else {
+      emit mouseMoving( this, theEvent ); 
+    }          
+  }
+}
+
+//****************************************************************/
+void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
+{
+  switch ( myOperation ) {
+  case NOTHING:
+    {
+      emit mouseReleased(this, theEvent);
+      if(theEvent->button() == RightButton)
+      {
+        QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
+                                  theEvent->pos(), theEvent->globalPos(),
+                                  theEvent->state() );
+        emit contextMenuRequested( &aEvent );
+      }
+    }
+    break;
+  case ROTATE:
+    myViewPort->endRotation();
+    resetState();
+    break;
+    
+  case PANVIEW:
+  case ZOOMVIEW:
+    resetState();
+    break;
+    
+  case PANGLOBAL:
+    if ( theEvent->button() == Qt::LeftButton ) {
+           myViewPort->setCenter( theEvent->x(), theEvent->y() );
+      myViewPort->getView()->SetScale(myCurScale);
+           resetState();
+         }
+    break;
+      
+  case WINDOWFIT:
+    if ( theEvent->state() == Qt::LeftButton ) {
+           myCurrX = theEvent->x();
+           myCurrY = theEvent->y();
+           QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
+           if ( !rect.isEmpty() ) myViewPort->fitRect(rect);
+           resetState();
+         }
+    break;
+  }
+  
+  // NOTE: viewer 3D detects a rectangle of selection using this event
+  // so we must emit it BEFORE resetting the selection rectangle
+  
+  if ( theEvent->button() == Qt::LeftButton && myDrawRect ) {
+    myDrawRect = false;
+    drawRect();
+    resetState(); 
+    myViewPort->update();
+  }
+}
+
+//****************************************************************
+/*!
+    Sets the viewport to its initial state
+    ( no transformations in process etc. )
+*/
+void OCCViewer_ViewWindow::resetState()
+{
+  myDrawRect = false;
+  
+  /* make rectangle empty (left > right) */
+  myRect.setLeft(2);
+  myRect.setRight(0);
+  
+  if ( transformRequested() || myCursorIsHand ) 
+    setCursor( myCursor );
+  myCursorIsHand = false;
+  
+  if ( transformRequested() ) 
+    emit vpTransformationFinished (myOperation);
+  
+  setTransformInProcess( false );              
+  setTransformRequested( NOTHING );    
+}
+
+
+//****************************************************************/
+void OCCViewer_ViewWindow::drawRect()
+{
+  QPainter aPainter(myViewPort);
+  aPainter.setRasterOp(Qt::XorROP);
+  aPainter.setPen(Qt::white);
+  QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
+  if ( !myRect.isEmpty() )
+         aPainter.drawRect( myRect );
+  aPainter.drawRect(aRect);
+  myRect = aRect;
+}
+
+//****************************************************************/
+void OCCViewer_ViewWindow::createActions()
+{
+  if (!myActionsMap.isEmpty()) return;
+  
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  
+  QtxAction* aAction;
+
+  // Dump view
+  aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_DUMP" ) ),
+                           tr( "MNU_DUMP_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onDumpView()));
+       myActionsMap[ DumpId ] = aAction;
+
+  // FitAll
+  aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITALL" ) ),
+                           tr( "MNU_FITALL" ), 0, this);
+  aAction->setStatusTip(tr("DSC_FITALL"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onFitAll()));
+       myActionsMap[ FitAllId ] = aAction;
+
+  // FitRect
+  aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITAREA" ) ),
+                           tr( "MNU_FITRECT" ), 0, this);
+  aAction->setStatusTip(tr("DSC_FITRECT"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(activateWindowFit()));
+       myActionsMap[ FitRectId ] = aAction;
+
+  // Zoom
+  aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ZOOM" ) ),
+                           tr( "MNU_ZOOM_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(activateZoom()));
+       myActionsMap[ ZoomId ] = aAction;
+
+  // Panning
+  aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_PAN" ) ),
+                           tr( "MNU_PAN_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_PAN_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(activatePanning()));
+       myActionsMap[ PanId ] = aAction;
+
+  // Global Panning
+  aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_GLOBALPAN" ) ),
+                           tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(activateGlobalPanning()));
+       myActionsMap[ GlobalPanId ] = aAction;
+
+  // Rotation
+  aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ),
+                           tr( "MNU_ROTATE_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(activateRotation()));
+       myActionsMap[ RotationId ] = aAction;
+
+  // Projections
+  aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ),
+                           tr( "MNU_FRONT_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onFrontView()));
+       myActionsMap[ FrontId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ),
+                           tr( "MNU_BACK_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_BACK_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onBackView()));
+       myActionsMap[ BackId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ),
+                           tr( "MNU_TOP_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_TOP_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onTopView()));
+       myActionsMap[ TopId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ),
+                           tr( "MNU_BOTTOM_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onBottomView()));
+       myActionsMap[ BottomId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ),
+                           tr( "MNU_LEFT_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onLeftView()));
+       myActionsMap[ LeftId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ),
+                           tr( "MNU_RIGHT_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onRightView()));
+       myActionsMap[ RightId ] = aAction;
+
+  // Reset
+  aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ),
+                           tr( "MNU_RESET_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_RESET_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onResetView()));
+       myActionsMap[ ResetId ] = aAction;
+
+  // Reset
+  aAction = new QtxAction(tr("MNU_CLONE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLONE_VIEW" ) ),
+                           tr( "MNU_CLONE_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_CLONE_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onCloneView()));
+       myActionsMap[ CloneId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_CLIPPING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" ) ),
+                           tr( "MNU_CLIPPING" ), 0, this);
+  aAction->setStatusTip(tr("DSC_CLIPPING"));
+  aAction->setToggleAction( true );
+  connect(aAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool )));
+       myActionsMap[ ClippingId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ),
+                           tr( "MNU_SHOOT_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_SHOOT_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onMemorizeView()));
+       myActionsMap[ MemId ] = aAction;
+
+  aAction = new QtxAction(tr("MNU_PRESETS_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESETS_VIEW" ) ),
+                           tr( "MNU_PRESETS_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_PRESETS_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onRestoreView()));
+       myActionsMap[ RestoreId ] = aAction;
+
+  if (myModel->trihedronActivated()) {
+    aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ),
+                             tr( "MNU_SHOW_TRIHEDRE" ), 0, this);
+    aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE"));
+    connect(aAction, SIGNAL(activated()), this, SLOT(onTrihedronShow()));
+         myActionsMap[ TrihedronShowId ] = aAction;
+  }
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::createToolBar()
+{
+  myActionsMap[DumpId]->addTo(myToolBar);  
+  if ( myModel->trihedronActivated() ) 
+    myActionsMap[TrihedronShowId]->addTo(myToolBar);
+
+  SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar, "scale");
+  aScaleBtn->AddAction(myActionsMap[FitAllId]);
+  aScaleBtn->AddAction(myActionsMap[FitRectId]);
+  aScaleBtn->AddAction(myActionsMap[ZoomId]);
+
+  SUIT_ToolButton* aPanningBtn = new SUIT_ToolButton(myToolBar, "pan");
+  aPanningBtn->AddAction(myActionsMap[PanId]);
+  aPanningBtn->AddAction(myActionsMap[GlobalPanId]);
+
+  myActionsMap[RotationId]->addTo(myToolBar);
+
+  SUIT_ToolButton* aViewsBtn = new SUIT_ToolButton(myToolBar, "projection");
+  aViewsBtn->AddAction(myActionsMap[FrontId]);
+  aViewsBtn->AddAction(myActionsMap[BackId]);
+  aViewsBtn->AddAction(myActionsMap[TopId]);
+  aViewsBtn->AddAction(myActionsMap[BottomId]);
+  aViewsBtn->AddAction(myActionsMap[LeftId]);
+  aViewsBtn->AddAction(myActionsMap[RightId]);
+
+  myActionsMap[ResetId]->addTo(myToolBar);
+
+  SUIT_ToolButton* aMemBtn = new SUIT_ToolButton(myToolBar, "view");
+  aMemBtn->AddAction(myActionsMap[MemId]);
+  aMemBtn->AddAction(myActionsMap[RestoreId]);
+
+  myToolBar->addSeparator();
+  myActionsMap[CloneId]->addTo(myToolBar);
+  
+  myToolBar->addSeparator();
+  myActionsMap[ClippingId]->addTo(myToolBar);
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onViewFitAll()
+{
+  myViewPort->fitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onFrontView()
+{
+  emit vpTransformationStarted ( FRONTVIEW );
+  Handle(V3d_View) aView3d = myViewPort->getView();
+  if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xpos);
+  onViewFitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onBackView()
+{
+  emit vpTransformationStarted ( BACKVIEW );
+  Handle(V3d_View) aView3d = myViewPort->getView();
+  if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xneg);
+  onViewFitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onTopView()
+{
+  emit vpTransformationStarted ( TOPVIEW );
+  Handle(V3d_View) aView3d = myViewPort->getView();
+  if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zpos);
+  onViewFitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onBottomView()
+{
+  emit vpTransformationStarted ( BOTTOMVIEW );
+  Handle(V3d_View) aView3d = myViewPort->getView();
+  if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zneg);
+  onViewFitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onLeftView()
+{
+  emit vpTransformationStarted ( LEFTVIEW );
+  Handle(V3d_View) aView3d = myViewPort->getView();
+  if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Yneg);
+  onViewFitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onRightView()
+{
+  emit vpTransformationStarted ( RIGHTVIEW );
+  Handle(V3d_View) aView3d = myViewPort->getView();
+  if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Ypos);
+  onViewFitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onResetView()
+{
+  emit vpTransformationStarted( RESETVIEW );
+  bool upd = myViewPort->getView()->SetImmediateUpdate( false );
+  myViewPort->getView()->Reset( false );
+  myViewPort->fitAll( false, true, false );
+  myViewPort->getView()->SetImmediateUpdate( upd );
+  myViewPort->getView()->Update();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onFitAll()
+{
+  emit vpTransformationStarted( FITALLVIEW );
+  myViewPort->fitAll();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onCloneView()
+{
+  SUIT_ViewWindow* vw = myManager->createViewWindow();
+  vw->show();
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onClipping( bool on )
+{
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  if ( on )
+    myActionsMap[ ClippingId ]->setIconSet(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING_PRESSED" )));
+  else
+    myActionsMap[ ClippingId ]->setIconSet(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" )));
+  
+  if ( on )
+    {
+      if ( !myClippingDlg )
+       myClippingDlg = new OCCViewer_ClippingDlg( this, myDesktop );
+
+      if ( !myClippingDlg->isShown() )
+       myClippingDlg->show();
+    }
+  else
+    {
+      if ( myClippingDlg->isShown() )
+       myClippingDlg->hide();
+      setCuttingPlane(false);
+    }
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onMemorizeView()
+{
+  double centerX, centerY, projX, projY, projZ, twist;
+  double atX, atY, atZ, eyeX, eyeY, eyeZ;
+
+  Handle(V3d_View) aView3d = myViewPort->getView();
+
+  aView3d->Center( centerX, centerY );
+  aView3d->Proj( projX, projY, projZ );
+  aView3d->At( atX, atY, atZ );
+  aView3d->Eye( eyeX, eyeY, eyeZ );
+  twist = aView3d->Twist();
+
+  viewAspect params;
+  QString aName = QTime::currentTime().toString() + QString::fromLatin1( " h:m:s" );
+
+  params.scale    = aView3d->Scale();
+  params.centerX  = centerX;
+  params.centerY  = centerY;
+  params.projX    = projX;
+  params.projY    = projY;
+  params.projZ    = projZ;
+  params.twist    = twist;
+  params.atX      = atX;
+  params.atY      = atY;
+  params.atZ      = atZ;
+  params.eyeX     = eyeX;
+  params.eyeY     = eyeY;
+  params.eyeZ     = eyeZ;
+  params.name    = aName;
+
+  myModel->appendViewAspect( params );
+
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onRestoreView()
+{
+       OCCViewer_CreateRestoreViewDlg* aDlg = new OCCViewer_CreateRestoreViewDlg( centralWidget(), myModel );
+       connect( aDlg, SIGNAL( dlgOk() ), this, SLOT( setRestoreFlag() ) );
+       aDlg->exec();
+       myModel->updateViewAspects( aDlg->parameters() );
+       if( myRestoreFlag && aDlg->parameters().count() )
+               performRestoring( aDlg->currentItem() );
+}
+
+//****************************************************************
+
+void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem )
+{
+       Handle(V3d_View) aView3d = myViewPort->getView();
+
+       Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False );
+       aView3d->SetScale( anItem.scale );
+       aView3d->SetCenter( anItem.centerX, anItem.centerY );
+       aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ );
+       aView3d->SetTwist( anItem.twist );
+       aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ );
+       aView3d->SetImmediateUpdate( prev );
+       aView3d->SetEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ );
+               
+       myRestoreFlag = 0;
+}
+
+void OCCViewer_ViewWindow::setRestoreFlag()
+{
+       myRestoreFlag = 1;
+}
+
+//****************************************************************
+void OCCViewer_ViewWindow::onTrihedronShow()
+{
+  myModel->toggleTrihedron();
+}
+
+//****************************************************************
+QImage OCCViewer_ViewWindow::dumpView()
+{
+  QPixmap px = QPixmap::grabWindow( myViewPort->winId() );
+  return px.convertToImage();
+}
+                                                                              
+void  OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x,  const double y,  const double z,
+                                                     const double dx, const double dy, const double dz )
+{
+  if ( on ) {
+    Handle(V3d_Viewer) viewer = myViewPort->getViewer();
+    Handle(V3d_View) view = myViewPort->getView();
+    
+    // try to use already existing plane or create a new one
+    Handle(V3d_Plane) clipPlane;
+    view->InitActivePlanes();
+    if ( view->MoreActivePlanes() )
+      clipPlane = view->ActivePlane();
+    else
+      clipPlane = new V3d_Plane( viewer );
+    
+    // set new a,b,c,d values for the plane
+    gp_Pln pln( gp_Pnt( x, y, z ), gp_Dir( dx, dy, dz ) );
+    double a, b, c, d;
+    pln.Coefficients( a, b, c, d );
+    clipPlane->SetPlane( a, b, c, d );
+    
+    Handle(V3d_View) v = myViewPort->getView();
+    v->SetPlaneOn( clipPlane );
+    v->Update();
+    v->Redraw();
+  } 
+  else {
+    Handle(V3d_View) view = myViewPort->getView();
+
+    // try to use already existing plane 
+    Handle(V3d_Plane) clipPlane;
+    view->InitActivePlanes();
+    if ( view->MoreActivePlanes() )
+      clipPlane = view->ActivePlane();
+    
+    Handle(V3d_View) v =  myViewPort->getView();
+    if ( !clipPlane.IsNull() )
+      v->SetPlaneOff( clipPlane );
+    else 
+      v->SetPlaneOff();
+    
+    v->Update();
+    v->Redraw();
+  }
+  Handle(V3d_View) v = myViewPort->getView();
+  v->Update();
+  v->Redraw();
+}
diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h
new file mode 100755 (executable)
index 0000000..b4f2bc8
--- /dev/null
@@ -0,0 +1,156 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef OCCVIEWER_VIEWWINDOW_H
+#define OCCVIEWER_VIEWWINDOW_H
+
+#include "OCCViewer_ViewModel.h"
+
+#include "SUIT_ViewWindow.h"
+
+#include "QtxAction.h"
+
+#include <qcursor.h>
+#include <qvaluelist.h>
+
+class SUIT_Desktop;
+class OCCViewer_ViewPort3d;
+
+class OCCViewer_ClippingDlg;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class OCCVIEWER_EXPORT OCCViewer_ViewWindow : public SUIT_ViewWindow  
+{
+  Q_OBJECT
+
+public:
+  enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE, PANGLOBAL, WINDOWFIT, FITALLVIEW, RESETVIEW,
+                      FRONTVIEW, BACKVIEW, TOPVIEW, BOTTOMVIEW, LEFTVIEW, RIGHTVIEW };
+
+  OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel);
+       virtual ~OCCViewer_ViewWindow() {};
+
+  OCCViewer_ViewPort3d* getViewPort() { return myViewPort; }
+
+  bool eventFilter(QObject* watched, QEvent* e);
+
+  QToolBar* getToolBar() { return myToolBar; }
+
+  void performRestoring( const viewAspect& );
+  
+  virtual void initLayout();
+
+  void updateEnabledDrawMode();
+
+  void setCuttingPlane( bool on, const double x = 0 , const double y = 0 , const double z = 0,
+                                 const double dx = 0, const double dy = 0, const double dz = 1);
+public slots:
+  void onFrontView();
+  void onViewFitAll();
+  void onBackView();
+  void onTopView();
+  void onBottomView();
+  void onLeftView();
+  void onRightView();
+  void onResetView();
+  void onFitAll();
+  void activateZoom();
+  void activateWindowFit();
+  void activateRotation();
+  void activatePanning();
+  void activateGlobalPanning();
+  void onCloneView();
+  void onClipping( bool on );
+  void onMemorizeView();
+  void onRestoreView();
+  void onTrihedronShow();
+  void setRestoreFlag();
+  
+signals:
+  void vpTransformationStarted(OCCViewer_ViewWindow::OperationType type);
+  void vpTransformationFinished(OCCViewer_ViewWindow::OperationType type);
+  void cloneView();
+
+protected:
+  enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, RotationId,
+         FrontId, BackId, TopId, BottomId, LeftId, RightId, ResetId, CloneId, ClippingId, MemId, RestoreId,
+         TrihedronShowId };
+
+  typedef QMap<int, QtxAction*> ActionsMap;
+
+  QImage dumpView();
+
+  /* Transformation selected but not started yet */
+  bool transformRequested() const { return ( myOperation != NOTHING ); }
+  void setTransformRequested ( OperationType op );
+
+  /* Transformation is selected and already started */
+  bool         transformInProcess() const { return myEventStarted; }
+  void         setTransformInProcess( bool bOn ) { myEventStarted = bOn; }
+
+  void vpMousePressEvent(QMouseEvent* theEvent);
+  void vpMouseReleaseEvent(QMouseEvent* theEvent);
+  void vpMouseMoveEvent(QMouseEvent* theEvent);
+
+  void resetState();
+  void drawRect();
+
+  void createActions();
+  void createToolBar();
+  virtual OperationType getButtonState(QMouseEvent* theEvent);
+
+  OperationType         myOperation;
+  OCCViewer_Viewer*     myModel;
+  OCCViewer_ViewPort3d* myViewPort;
+
+  int                                  myRestoreFlag;
+
+  int                                  myStartX;
+  int                                  myStartY;
+  int                                  myCurrX;
+  int                                  myCurrY;
+
+  bool                 myEventStarted;       // set when transformation is in process 
+  bool                 myCursorIsHand;                 
+  bool                 myDrawRect;           // set when a rect is used for selection or magnify 
+  bool                 myEnableDrawMode;
+  bool                 myPaintersRedrawing;  // set to draw with external painters 
+  QRect                        myRect;                         
+  QCursor              myCursor;
+
+  QToolBar*  myToolBar;
+  ActionsMap myActionsMap;
+
+  double myCurScale;
+
+private:
+  OCCViewer_ClippingDlg* myClippingDlg;
+  
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/OCCViewer/resources/OCCViewer_images.po b/src/OCCViewer/resources/OCCViewer_images.po
new file mode 100755 (executable)
index 0000000..4321354
--- /dev/null
@@ -0,0 +1,96 @@
+#  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+#
+#  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+#
+#
+#
+#  File   : SALOMEGUI_icons.po
+#  Module : SALOME
+
+msgid ""
+msgstr ""
+"Project-Id-Version: example-Qt-message-extraction\n"
+"POT-Creation-Date: 1999-02-23 15:38+0200\n"
+"PO-Revision-Date: 1999-02-23 15:38+0200\n"
+"Last-Translator: \n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+msgid "ICON_OCCVIEWER_VIEW_BACK"
+msgstr "view_back.png"
+
+msgid "ICON_OCCVIEWER_VIEW_BOTTOM"
+msgstr "view_bottom.png"
+
+msgid "ICON_OCCVIEWER_VIEW_FITALL"
+msgstr "view_fitall.png"
+
+msgid "ICON_OCCVIEWER_VIEW_FITAREA"
+msgstr "view_fitarea.png"
+
+msgid "ICON_OCCVIEWER_VIEW_FRONT"
+msgstr "view_front.png"
+
+msgid "ICON_OCCVIEWER_VIEW_GLOBALPAN"
+msgstr "view_glpan.png"
+
+msgid "ICON_OCCVIEWER_VIEW_LEFT"
+msgstr "view_left.png"
+
+msgid "ICON_OCCVIEWER_VIEW_PAN"
+msgstr "view_pan.png"
+
+msgid "ICON_OCCVIEWER_VIEW_RESET"
+msgstr "view_reset.png"
+
+msgid "ICON_OCCVIEWER_VIEW_RIGHT"
+msgstr "view_right.png"
+
+msgid "ICON_OCCVIEWER_VIEW_ROTATE"
+msgstr "view_rotate.png"
+
+msgid "ICON_OCCVIEWER_VIEW_TOP"
+msgstr "view_top.png"
+
+msgid "ICON_OCCVIEWER_VIEW_ZOOM"
+msgstr "view_zoom.png"
+
+msgid "ICON_OCCVIEWER_VIEW_TRIHEDRON"
+msgstr "view_triedre.png"
+
+msgid "ICON_OCCVIEWER_VIEW_DUMP"
+msgstr "view_camera_dump.png"
+
+msgid "ICON_OCCVIEWER_CLONE_VIEW"
+msgstr "view_clone.png"
+
+msgid "ICON_OCCVIEWER_CLIPPING"
+msgstr "view_clipping.png"
+
+msgid "ICON_OCCVIEWER_CLIPPING_PRESSED"
+msgstr "view_clipping_pressed.png"
+
+msgid "ICON_OCCVIEWER_SHOOT_VIEW"
+msgstr "view_shoot.png"
+
+msgid "ICON_OCCVIEWER_PRESETS_VIEW"
+msgstr "view_presets.png"
+
+
+
diff --git a/src/OCCViewer/resources/OCCViewer_msg_en.po b/src/OCCViewer/resources/OCCViewer_msg_en.po
new file mode 100755 (executable)
index 0000000..ceab129
--- /dev/null
@@ -0,0 +1,188 @@
+#  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+#
+#  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+#
+#
+#
+#  File   : SALOMEGUI_msg_en.po
+#  Module : SALOME
+
+msgid ""
+msgstr ""
+"Project-Id-Version: example-Qt-message-extraction\n"
+"POT-Creation-Date: 1999-02-23 15:38+0200\n"
+"PO-Revision-Date: 1999-02-23 15:38+0200\n"
+"Last-Translator: \n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+msgid "LBL_TOOLBAR_LABEL"
+msgstr "View Operations"
+
+msgid "DSC_FRONT_VIEW"
+msgstr "Front View"
+
+msgid "MNU_FRONT_VIEW"
+msgstr "Front"
+
+msgid "DSC_BACK_VIEW"
+msgstr "Back View"
+
+msgid "MNU_BACK_VIEW"
+msgstr "Back"
+
+msgid "DSC_TOP_VIEW"
+msgstr "Top View"
+
+msgid "MNU_TOP_VIEW"
+msgstr "Top"
+
+msgid "DSC_BOTTOM_VIEW"
+msgstr "Bottom View"
+
+msgid "MNU_BOTTOM_VIEW"
+msgstr "Bottom"
+
+msgid "DSC_LEFT_VIEW"
+msgstr "Left View"
+
+msgid "MNU_LEFT_VIEW"
+msgstr "Left"
+
+msgid "DSC_RIGHT_VIEW"
+msgstr "Right View"
+
+msgid "MNU_RIGHT_VIEW"
+msgstr "Right"
+
+msgid "DSC_RESET_VIEW"
+msgstr "Reset View Point"
+
+msgid "MNU_RESET_VIEW"
+msgstr "Reset"
+
+msgid "DSC_FITALL"
+msgstr "Fit all objects inside the view frame"
+
+msgid "MNU_FITALL"
+msgstr "Fit All"
+
+msgid "DSC_FITRECT"
+msgstr "Fit area within the view frame"
+
+msgid "MNU_FITRECT"
+msgstr "Fit Area"
+
+msgid "DSC_ZOOM_VIEW"
+msgstr "Zoom the view"
+
+msgid "MNU_ZOOM_VIEW"
+msgstr "Zoom"
+
+msgid "DSC_PAN_VIEW"
+msgstr "Panning the view"
+
+msgid "MNU_PAN_VIEW"
+msgstr "Panning"
+
+msgid "DSC_GLOBALPAN_VIEW"
+msgstr "Selection of a new center of the view"
+
+msgid "MNU_GLOBALPAN_VIEW"
+msgstr "Global Panning"
+
+msgid "DSC_ROTATE_VIEW"
+msgstr "Rotation of the point of view around the scene center"
+
+msgid "MNU_ROTATE_VIEW"
+msgstr "Rotation"
+
+msgid "DSC_CLONE_VIEW"
+msgstr "Create new OCC viewer for the active scene"
+
+msgid "MNU_CLONE_VIEW"
+msgstr "Clone View"
+
+msgid "MNU_DUMP_VIEW"
+msgstr "Dump view"
+
+msgid "DSC_CLIPPING"
+msgstr "Define clipping plane"
+
+msgid "MNU_CLIPPING"
+msgstr "Clipping"
+
+msgid "DSC_DUMP_VIEW"
+msgstr "Saves the active view in the image file"
+
+msgid "MNU_SHOOT_VIEW"
+msgstr "Memorize View"
+
+msgid "DSC_SHOOT_VIEW"
+msgstr "Memorizes the state of the active view and adds it to the list"
+
+msgid "MNU_PRESETS_VIEW"
+msgstr "Restore View"
+
+msgid "DSC_PRESETS_VIEW"
+msgstr "Selection of the memorized state of the active view"
+
+msgid "OCC_IMAGE_FILES"
+msgstr "Images Files (*.bmp *.png *.jpg *.jpeg)"
+
+msgid "INF_APP_DUMP_VIEW"
+msgstr "Dump view"
+
+msgid "INF_APP_SHOOT_VIEW"
+msgstr "Memorize view"
+
+msgid "INF_APP_PRESETS_VIEW"
+msgstr "Restore view"
+
+msgid "ERR_DOC_CANT_SAVE_FILE"
+msgstr "Cannot save file"
+
+msgid "ERROR"
+msgstr "Error"
+
+msgid "BUT_OK"
+msgstr "Ok"
+
+
+msgid "OCCViewer_Viewer::MEN_DUMP_VIEW"
+msgstr "Dump view..."
+
+msgid "OCCViewer_Viewer::MEN_SHOW_TOOLBAR"
+msgstr "Show toolbar"
+
+msgid "OCCViewer_Viewer::MEN_CHANGE_BACKGROUD"
+msgstr "Change background..."
+
+msgid "OCCViewer_ViewManager::OCC_VIEW_TITLE"
+msgstr "OCC scene:%1 - viewer:%2"
+
+
+msgid "OCCViewer_CreateRestoreViewDlg::CAPTION"
+msgstr "Restore view"
+
+msgid "MNU_SHOW_TRIHEDRE"
+msgstr "Show/Hide trihedron"
+
+msgid "DSC_SHOW_TRIHEDRE"
+msgstr "Show/Hide trihedron in the current view"
diff --git a/src/OCCViewer/resources/view_clipping.png b/src/OCCViewer/resources/view_clipping.png
new file mode 100644 (file)
index 0000000..dce8bd5
Binary files /dev/null and b/src/OCCViewer/resources/view_clipping.png differ
diff --git a/src/OCCViewer/resources/view_clipping_pressed.png b/src/OCCViewer/resources/view_clipping_pressed.png
new file mode 100644 (file)
index 0000000..7895f65
Binary files /dev/null and b/src/OCCViewer/resources/view_clipping_pressed.png differ
diff --git a/src/ObjBrowser/OB_ListItem.cxx b/src/ObjBrowser/OB_ListItem.cxx
new file mode 100755 (executable)
index 0000000..b2ced5c
--- /dev/null
@@ -0,0 +1,297 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "OB_ListItem.h"
+
+#include "OB_ListView.h"
+
+#include <SUIT_DataObject.h>
+
+#include <qpainter.h>
+#include <qwmatrix.h>
+
+#include <iostream>
+using namespace std;
+
+/*!
+    Class: ListItem
+    Descr: base template class
+*/
+
+template<class T>
+ListItemF<T>::ListItemF( T& theT, SUIT_DataObject* obj ) :
+myT( theT ),
+myObject( obj )
+{
+}
+
+template<class T>
+void ListItemF<T>::paintC( QPainter* p, QColorGroup& cg, int c, int w, int align )
+{ 
+//  QColorGroup colorGrp( cg );
+  if ( myObject )
+  {
+    if ( myObject->color( SUIT_DataObject::Text ).isValid() )
+      cg.setColor( QColorGroup::Text, myObject->color( SUIT_DataObject::Text ) );
+    if ( myObject->color( SUIT_DataObject::Base ).isValid() )
+      cg.setColor( QColorGroup::Base, myObject->color( SUIT_DataObject::Base ) );
+    if ( myObject->color( SUIT_DataObject::Foreground ).isValid() )
+      cg.setColor( QColorGroup::Foreground, myObject->color( SUIT_DataObject::Foreground ) );
+    if ( myObject->color( SUIT_DataObject::Background ).isValid() )
+      cg.setColor( QColorGroup::Background, myObject->color( SUIT_DataObject::Background ) );
+    if ( myObject->color( SUIT_DataObject::Highlight ).isValid() )
+      cg.setColor( QColorGroup::Highlight, myObject->color( SUIT_DataObject::Highlight ) );
+    if ( myObject->color( SUIT_DataObject::HighlightedText ).isValid() )
+      cg.setColor( QColorGroup::HighlightedText, myObject->color( SUIT_DataObject::HighlightedText ) );
+  }
+
+  
+  p->fillRect( 0, 0, w, myT.height(), cg.brush( QColorGroup::Base ) );
+  //int itemW = myT.width( p->fontMetrics(), myT.listView(), c );
+    
+  //myT.paintCell( p, colorGrp, c, itemW,  align );
+}
+
+template<class T>
+void ListItemF<T>::paintFoc( QPainter* p, QColorGroup& cg, const QRect& r )
+{
+  QRect rect = r;
+  rect.setWidth( myT.width( p->fontMetrics(), myT.listView(), 0 ) );
+  //myT.paintFocus( p, cg, rect );
+}
+
+template<class T>
+void ListItemF<T>::setSel( bool s )
+{
+  QListView* lv = myT.listView();
+  if ( s && lv && lv->inherits( "OB_ListView" ) )
+  {
+    OB_ListView* objlv = (OB_ListView*)lv;
+    s = s && objlv->isOk( &myT );
+  }
+
+  //myT.setSelected( s );
+}
+
+template<class T>
+void ListItemF<T>::update()
+{
+  SUIT_DataObject* obj = dataObject();
+  if ( !obj )
+    return;
+
+  myT.setText( 0, obj->name() );
+
+  int aIconW = obj->icon().width();
+  if ( aIconW > 0 )
+  {
+    if ( aIconW > 20 )
+    {
+      QWMatrix aM;
+      double aScale = 20.0 / aIconW;
+      aM.scale( aScale, aScale );
+      myT.setPixmap( 0, obj->icon().xForm( aM ) );
+    }
+    else
+      myT.setPixmap( 0, obj->icon() );
+  }
+
+  myT.setDragEnabled( obj->isDragable() );
+  myT.setDropEnabled( true );
+}
+
+/*!
+    Class: OB_ListItem
+    Descr: List view item for OB_Browser.
+*/
+
+OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListView* parent )
+: ListItemF<QListViewItem>( *this, obj ),
+ QListViewItem(parent)
+{
+       update();
+}
+
+OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListViewItem* parent )
+: ListItemF<QListViewItem>( *this, obj),
+ QListViewItem(parent)
+{
+       update();
+}
+
+OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListView* parent, QListViewItem* after )
+: ListItemF<QListViewItem>( *this, obj),
+QListViewItem(parent, after )
+{
+       update();
+}
+
+OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListViewItem* parent, QListViewItem* after )
+: ListItemF<QListViewItem>( *this,obj),
+QListViewItem(parent, after )
+{
+       update();
+}
+
+OB_ListItem::~OB_ListItem()
+{
+}
+
+void OB_ListItem::setSelected( bool s )
+{
+       setSel( s );
+       QListViewItem::setSelected( s );
+}
+
+void OB_ListItem::paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r )
+{
+  QColorGroup col_group( cg );
+       paintFoc( p, col_group, r );
+
+  QRect R( r );
+  if ( listView() && !listView()->allColumnsShowFocus() )
+    R.setWidth( width( p->fontMetrics(), listView(), 0 ) );
+
+  QListViewItem::paintFocus( p, col_group, R );
+}
+
+void OB_ListItem::paintCell( QPainter* p, const QColorGroup& cg, int c, int w, int align )
+{
+  QColorGroup col_group( cg );
+       paintC( p, col_group, c ,w, align );
+
+  int W = w;
+  if ( listView() && !listView()->allColumnsShowFocus() )
+    W = width( p->fontMetrics(), listView(), c );
+
+       QListViewItem::paintCell( p, col_group, c, W, align );
+}
+
+int OB_ListItem::RTTI()
+{
+  return 1000;
+}
+
+int OB_ListItem::rtti() const
+{
+  return RTTI();
+}
+
+void OB_ListItem::setText( int column, const QString& text )
+{
+  QListViewItem::setText( column, text );
+  QFontMetrics fm = listView()->fontMetrics();
+  int necessary = width( fm, listView(), column ),
+      current = listView()->columnWidth( column );
+
+  if( listView()->columnWidthMode( column )==QListView::Maximum && necessary>current )
+    listView()->setColumnWidth( column, necessary );
+}
+
+/*!
+    Class: OB_CheckListItem
+    Descr: Check list view item for OB_Browser.
+*/
+
+OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListView* parent, Type type )
+: ListItemF<QCheckListItem>( *this, obj),
+QCheckListItem( parent, "", type )
+{
+       update();
+}
+
+OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListViewItem* parent, Type type )
+: ListItemF<QCheckListItem>( *this, obj),
+QCheckListItem( parent, "", type )
+{
+       update();
+}
+
+OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListView* parent, QListViewItem* after, Type type )
+: ListItemF<QCheckListItem>( *this, obj),
+#if defined(QT_VERSION) && QT_VERSION >= 0x030101
+ QCheckListItem( parent, after, "", type )
+#else
+ QCheckListItem( parent, "", type )
+#endif
+{
+       update();
+}
+
+OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListViewItem* parent, QListViewItem* after, Type type )
+: ListItemF<QCheckListItem>( *this, obj),
+#if defined(QT_VERSION) && QT_VERSION >= 0x030101
+ QCheckListItem( parent, after, "", type )
+#else
+ QCheckListItem( parent, "", type )
+#endif
+{
+       update();
+}
+
+OB_CheckListItem::~OB_CheckListItem()
+{
+}
+
+void OB_CheckListItem::setSelected( bool s )
+{
+       setSel( s );
+       QCheckListItem::setSelected( s );
+}
+
+void OB_CheckListItem::paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r )
+{
+  QColorGroup col_group( cg );
+       paintFoc( p, col_group, r );
+
+  QRect R( r );
+  if ( listView() && !listView()->allColumnsShowFocus() )
+    R.setWidth( width( p->fontMetrics(), listView(), 0 ) );
+
+       QCheckListItem::paintFocus( p, col_group, R );
+}
+
+void OB_CheckListItem::paintCell( QPainter* p, const QColorGroup& cg, int c, int w, int align )
+{
+  QColorGroup col_group( cg );
+       paintC( p, col_group, c ,w, align );
+
+  int W = w;
+  if ( listView() && !listView()->allColumnsShowFocus() )
+    W = width( p->fontMetrics(), listView(), c );
+
+  QCheckListItem::paintCell( p, col_group, c, W, align );
+}
+
+int OB_CheckListItem::RTTI()
+{
+  return OB_ListItem::RTTI() + 1;
+}
+
+int OB_CheckListItem::rtti() const
+{
+  return RTTI();
+}
+
+void OB_CheckListItem::stateChange( bool on )
+{
+  QCheckListItem::stateChange( on );
+
+  if ( dataObject() )
+    dataObject()->setOn( on );
+}
diff --git a/src/ObjBrowser/OB_ListItem.h b/src/ObjBrowser/OB_ListItem.h
new file mode 100755 (executable)
index 0000000..6b06cd8
--- /dev/null
@@ -0,0 +1,115 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+
+#ifndef OB_LISTITEM_H
+#define OB_LISTITEM_H
+
+#include "OB.h"
+
+#include <qlistview.h>
+
+class SUIT_DataObject;
+
+/* 
+  base template class for ListViewItems and CheckListItems
+*/
+
+template<class T> class ListItemF
+{
+public:
+       ListItemF(T&, SUIT_DataObject* );
+  /*ListItem( SUIT_DataObject*, QListView* );
+  ListItem( SUIT_DataObject*, QListViewItem* );
+  ListItem( SUIT_DataObject*, QListView*, QListViewItem* );
+  ListItem( SUIT_DataObject*, QListViewItem*, QListViewItem* );
+
+  ListItem( SUIT_DataObject*, QListView*, int );
+  ListItem( SUIT_DataObject*, QListViewItem*, int );
+  ListItem( SUIT_DataObject*, QListView*, QListViewItem*, int );
+  ListItem( SUIT_DataObject*, QListViewItem*, QListViewItem*, int );*/
+
+  void            setSel( bool s );
+  inline SUIT_DataObject* dataObject() const { return myObject; }
+  void            paintFoc( QPainter* p, QColorGroup& cg, const QRect& r );
+  void            paintC( QPainter* p, QColorGroup& cg, int c, int w, int align );
+
+protected:
+  void                     update();
+
+protected:
+  SUIT_DataObject* myObject;
+  T& myT;
+};
+
+/* 
+   ListViewItem class
+*/
+
+class OB_EXPORT OB_ListItem : public ListItemF<QListViewItem>, public QListViewItem
+{
+public:
+       OB_ListItem( SUIT_DataObject*, QListView* );
+       OB_ListItem( SUIT_DataObject*, QListViewItem* );
+       OB_ListItem( SUIT_DataObject*, QListView*, QListViewItem* );
+       OB_ListItem( SUIT_DataObject*, QListViewItem*, QListViewItem* );
+
+       virtual ~OB_ListItem();
+
+  virtual void            setSelected( bool s );
+  virtual void            paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r );
+  virtual void            paintCell( QPainter* p, const QColorGroup& cg, int c, int w, int align );
+
+  virtual void setText ( int column, const QString & text );
+
+  virtual int      rtti() const;
+
+  static int       RTTI();
+};
+
+/* 
+   CheckListItem class
+*/
+
+class OB_EXPORT OB_CheckListItem : public ListItemF<QCheckListItem>, public QCheckListItem
+{
+public:
+  OB_CheckListItem( SUIT_DataObject*, QListView*, Type = CheckBox );
+  OB_CheckListItem( SUIT_DataObject*, QListViewItem*, Type = CheckBox );
+  OB_CheckListItem( SUIT_DataObject*, QListView*, QListViewItem*, Type = CheckBox );
+  OB_CheckListItem( SUIT_DataObject*, QListViewItem*, QListViewItem*, Type = CheckBox );
+
+  virtual ~OB_CheckListItem();
+
+  virtual void            setSelected( bool s );
+  virtual void            paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r );
+  virtual void            paintCell( QPainter* p, const QColorGroup& cg, int c, int w, int align );
+
+
+  virtual int      rtti() const;
+
+  static int       RTTI();
+
+protected:
+  void             stateChange( bool );
+
+//private:
+//  void             update();
+};
+
+#endif
diff --git a/src/ObjBrowser/OB_ListView.cxx b/src/ObjBrowser/OB_ListView.cxx
new file mode 100755 (executable)
index 0000000..53d6260
--- /dev/null
@@ -0,0 +1,200 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "OB_ListView.h"
+
+#include "OB_Filter.h"
+#include "OB_ListItem.h"
+
+#include <SUIT_DataObject.h>
+
+#include <qdragobject.h>
+
+OB_ListView::OB_ListView( QWidget* parent, const char* name, WFlags f )
+: QtxListView( parent, name, f ),
+myFilter( 0 )
+{
+}
+
+OB_ListView::OB_ListView( const int state, QWidget* parent, const char* name, WFlags f )
+: QtxListView( state, parent, name, f ),
+myFilter( 0 )
+{
+}
+
+OB_ListView::~OB_ListView()
+{
+  delete myFilter;
+}
+
+OB_Filter* OB_ListView::filter() const
+{
+  return myFilter;
+}
+
+void OB_ListView::setFilter( OB_Filter* f )
+{
+  if ( myFilter == f )
+    return;
+
+  delete myFilter;
+  myFilter = f;
+}
+
+bool OB_ListView::isOk( QListViewItem* item ) const
+{
+  bool ok = true;
+  SUIT_DataObject* obj = dataObject( item );
+  if ( obj && filter() )
+    ok = filter()->isOk( obj );
+  return ok;
+}
+
+QDragObject* OB_ListView::dragObject()
+{
+  myItems.clear();
+
+  for ( QListViewItemIterator it( this ); it.current(); ++it )
+    if ( it.current()->isSelected() )
+      myItems.append( it.current() );
+
+  return new QTextDrag( "", this );
+}
+
+void OB_ListView::dragEnterEvent( QDragEnterEvent* e )
+{
+  e->accept();
+}
+
+void OB_ListView::dragMoveEvent( QDragMoveEvent* e )
+{
+  QListViewItem* item = dropItem( e );
+
+  if ( isDropAccepted( item ) )
+  {
+    setCurrentItem( item );
+    e->accept( true );
+  }
+  else
+    e->accept( false );
+}
+
+void OB_ListView::dropEvent( QDropEvent* e )
+{
+  QListViewItem* item = dropItem( e );
+  if ( isDropAccepted( item ) )
+  {
+    e->accept();
+    emit dropped( myItems, item, e->action() );
+  }
+  myItems.clear();
+}
+
+void OB_ListView::keyPressEvent( QKeyEvent* ke )
+{
+  if ( ( ke->key() == Qt::Key_Plus || ke->key() == Qt::Key_Minus ) && ke->state() & ControlButton )
+  {
+    bool isOpen = ke->key() == Qt::Key_Plus;
+    for ( QListViewItemIterator it( this ); it.current(); ++it )
+      if ( it.current()->childCount() )
+        it.current()->setOpen( isOpen );
+  }
+  else
+    QtxListView::keyPressEvent( ke );
+}
+
+QListViewItem* OB_ListView::dropItem( QDropEvent* e ) const
+{
+  QListViewItem* item = 0;
+  if ( e )
+    item = itemAt( QPoint( e->pos().x() - viewport()->x(), e->pos().y() - viewport()->y() ) );
+
+  return item;
+}
+
+SUIT_DataObject* OB_ListView::dataObject( QListViewItem* item ) const
+{
+  if ( !item )
+    return 0;
+
+  SUIT_DataObject* obj = 0;
+
+  if ( dynamic_cast<OB_ListItem*>( item ) )
+    obj = dynamic_cast<OB_ListItem*>( item )->dataObject();
+  else if ( dynamic_cast<OB_CheckListItem*>( item ) )
+    obj = dynamic_cast<OB_CheckListItem*>( item )->dataObject();
+
+  return obj;
+}
+
+bool OB_ListView::isDropAccepted( QListViewItem* item ) const
+{
+  bool res = true;
+
+  for ( QPtrListIterator<QListViewItem> it( myItems ); it.current() && res; ++it )
+    res = res && isDropAccepted( it.current(), item );
+
+  return res;
+}
+
+bool OB_ListView::isDropAccepted( QListViewItem* drag, QListViewItem* drop ) const
+{
+  SUIT_DataObject* dragObj = dataObject( drag );
+  SUIT_DataObject* dropObj = dataObject( drop );
+
+  if ( !dragObj || !dropObj )
+    return false;
+
+  return dropObj->isDropAccepted( dragObj );
+}
+
+void OB_ListView::setColumnWidth( int col, int width )
+{
+  int max = columnMaxWidth( col );
+  if( max>0 && width>max )
+    width = max;
+  QListView::setColumnWidth( col, width );
+}
+
+int OB_ListView::columnMaxWidth( const int col ) const
+{
+  int res = -1;
+  if( myMaxColWidth.contains( col ) )
+    res = myMaxColWidth[col];
+  else if( myMaxColRatio.contains( col ) )
+    res = int( myMaxColRatio[col]*height() );
+  return res;
+}
+
+void OB_ListView::setColumnMaxWidth( const int col, const int w )
+{
+  myMaxColWidth.insert( col, w );
+}
+
+double OB_ListView::columnMaxRatio( const int col ) const
+{
+  double res = 0.0;
+  if( myMaxColRatio.contains( col ) )
+    res = myMaxColRatio[col];
+  return res;
+}
+
+void OB_ListView::setColumnMaxRatio( const int col, const double r )
+{
+  myMaxColRatio.insert( col, r );
+}
diff --git a/src/ObjBrowser/OB_ListView.h b/src/ObjBrowser/OB_ListView.h
new file mode 100755 (executable)
index 0000000..03a394c
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef OB_LISTVIEW_H
+#define OB_LISTVIEW_H
+
+#include "OB.h"
+
+
+#include <QtxListView.h>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+#include <qptrlist.h>
+
+class OB_Filter;
+class QListViewItem;
+class SUIT_DataObject;
+
+class OB_EXPORT OB_ListView : public QtxListView
+{
+  Q_OBJECT
+
+public:
+  OB_ListView( QWidget* = 0, const char* = 0, WFlags = 0 );
+  OB_ListView( const int, QWidget* = 0, const char* = 0, WFlags = 0 );
+  virtual ~OB_ListView();
+
+  OB_Filter*              filter() const;
+  void                    setFilter( OB_Filter* );
+
+  bool                    isOk( QListViewItem* ) const;
+  virtual void            setColumnWidth( int, int );
+  int                     columnMaxWidth( const int ) const;
+  void                    setColumnMaxWidth( const int, const int );
+  double                  columnMaxRatio( const int ) const;
+  void                    setColumnMaxRatio( const int, const double );
+
+signals:
+  void                    dropped( QPtrList<QListViewItem>, QListViewItem*, int );
+
+protected:
+  virtual QDragObject*    dragObject();
+  virtual void            dropEvent( QDropEvent* );
+  virtual void            dragMoveEvent( QDragMoveEvent* );
+  virtual void            dragEnterEvent( QDragEnterEvent* );
+
+  virtual void            keyPressEvent( QKeyEvent* );
+
+private:
+  void                    updateHeader();
+  QListViewItem*          dropItem( QDropEvent* ) const;
+  SUIT_DataObject*        dataObject( QListViewItem* ) const;
+  bool                    isDropAccepted( QListViewItem* ) const;
+  bool                    isDropAccepted( QListViewItem*, QListViewItem* ) const;
+
+protected:
+  QPtrList<QListViewItem> myItems;
+  OB_Filter*              myFilter;
+  QMap<int,int>           myMaxColWidth;
+  QMap<int,double>        myMaxColRatio;
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/Plot2d/Plot2d_Curve.cxx b/src/Plot2d/Plot2d_Curve.cxx
new file mode 100755 (executable)
index 0000000..c0a9abb
--- /dev/null
@@ -0,0 +1,385 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "Plot2d_Curve.h"
+#include <qcolor.h>
+
+/*!
+  Constructor
+*/
+Plot2d_Curve::Plot2d_Curve()
+: myHorTitle( "" ), myVerTitle( "" ), 
+myHorUnits( "" ), myVerUnits( "" ), 
+myAutoAssign( true ), myColor( 0,0,0 ), myMarker( Circle ), myLine( Solid ), myLineWidth( 0 ),
+myYAxis( QwtPlot::yLeft )
+{
+}
+
+/*!
+  Destructor
+*/
+Plot2d_Curve::~Plot2d_Curve()
+{
+}
+
+/*!
+  Copy constructor. Makes deep copy of data.
+*/
+Plot2d_Curve::Plot2d_Curve( const Plot2d_Curve& curve )
+{
+  myAutoAssign = curve.isAutoAssign();
+  myHorTitle   = curve.getHorTitle();
+  myVerTitle   = curve.getVerTitle();
+  myHorUnits   = curve.getHorUnits();
+  myVerUnits   = curve.getVerUnits();
+  myColor      = curve.getColor();
+  myMarker     = curve.getMarker();
+  myLine       = curve.getLine();
+  myLineWidth  = curve.getLineWidth();
+  myPoints     = curve.getPointList();
+}
+
+/*!
+  operator=. Makes deep copy of data.
+*/
+Plot2d_Curve& Plot2d_Curve::operator=( const Plot2d_Curve& curve )
+{
+  myAutoAssign = curve.isAutoAssign();
+  myHorTitle   = curve.getHorTitle();
+  myVerTitle   = curve.getVerTitle();
+  myHorUnits   = curve.getHorUnits();
+  myVerUnits   = curve.getVerUnits();
+  myColor      = curve.getColor();
+  myMarker     = curve.getMarker();
+  myLine       = curve.getLine();
+  myLineWidth  = curve.getLineWidth();
+  myPoints     = curve.getPointList();
+  return *this;
+}
+
+QString Plot2d_Curve::getTableTitle() const
+{
+  return QString();
+}
+
+/*!
+  Sets curve's horizontal title
+*/
+void Plot2d_Curve::setHorTitle( const QString& title )
+{
+  myHorTitle = title;
+}
+
+/*!
+  Gets curve's horizontal title
+*/
+QString Plot2d_Curve::getHorTitle() const
+{
+  return myHorTitle;
+}
+
+/*!
+  Sets curve's vertical title
+*/
+void Plot2d_Curve::setVerTitle( const QString& title )
+{
+  myVerTitle = title;
+}
+
+/*!
+  Gets curve's vertical title
+*/
+QString Plot2d_Curve::getVerTitle() const
+{
+  return myVerTitle;
+}
+
+/*!
+  Sets curve's horizontal units
+*/
+void Plot2d_Curve::setHorUnits( const QString& units )
+{
+  myHorUnits = units;
+}
+
+/*!
+  Gets curve's horizontal units
+*/
+QString Plot2d_Curve::getHorUnits() const
+{
+  return myHorUnits;
+}
+
+/*!
+  Sets curve's vertical units
+*/
+void Plot2d_Curve::setVerUnits( const QString& units )
+{
+  myVerUnits = units;
+}
+
+/*!
+  Gets curve's vertical units
+*/
+QString Plot2d_Curve::getVerUnits() const
+{
+  return myVerUnits;
+}
+
+/*!
+  Adds one point for curve.
+*/
+void Plot2d_Curve::addPoint(double theX, double theY)
+{
+  Plot2d_Point aPoint;
+  aPoint.x = theX;
+  aPoint.y = theY;
+  myPoints.append(aPoint);
+}
+
+/*!
+  Insert one point for curve on some position.
+*/
+void Plot2d_Curve::insertPoint(int thePos, double theX, double theY)
+{
+  Plot2d_Point aPoint;
+  aPoint.x = theX;
+  aPoint.y = theY;
+
+  QValueList<Plot2d_Point>::iterator aIt;
+  int aCurrent = 0;
+  for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) {
+    if (thePos == aCurrent) {
+      myPoints.insert(aIt, aPoint);
+      return;
+    }
+    aCurrent++;  
+  }
+  myPoints.append(aPoint);
+}
+
+/*!
+  Delete one point for curve on some position.
+*/
+void Plot2d_Curve::deletePoint(int thePos)
+{
+  QValueList<Plot2d_Point>::iterator aIt;
+  int aCurrent = 0;
+  for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) {
+    if (thePos == aCurrent) {
+      myPoints.remove(aIt);
+      return;
+    }
+    aCurrent++;  
+  }
+}
+
+/*!
+  Remove all points for curve.
+*/
+void Plot2d_Curve::clearAllPoints()
+{
+  myPoints.clear();
+}
+
+/*!
+  Gets curve's data : abscissas of points
+*/
+pointList Plot2d_Curve::getPointList() const
+{
+  return myPoints;
+}
+
+/*!
+  Sets curve's data. 
+*/
+void Plot2d_Curve::setData( const double* hData, const double* vData, long size )
+{
+  clearAllPoints();
+  for(long i = 0; i < size; i++) addPoint(hData[i], vData[i]);
+}
+
+/*!
+  Gets curve's data : abscissas of points
+*/
+double* Plot2d_Curve::horData() const
+{
+  int aNPoints = nbPoints();
+  double* aX = new double[aNPoints];
+  for (int i = 0; i < aNPoints; i++) {
+    aX[i] = myPoints[i].x;
+  }
+  return aX;
+}
+
+/*!
+  Gets curve's data : ordinates of points
+*/
+double* Plot2d_Curve::verData() const
+{
+  int aNPoints = nbPoints();
+  double* aY = new double[aNPoints];
+  for (int i = 0; i < aNPoints; i++) {
+    aY[i] = myPoints[i].y;
+  }
+  return aY;
+}
+
+/*!
+  Gets curve's data : number of points
+*/
+int Plot2d_Curve::nbPoints() const
+{
+  return myPoints.count();
+}
+
+/*!
+  Returns true if curve has no data
+*/
+bool Plot2d_Curve::isEmpty() const
+{
+  return myPoints.isEmpty();
+}
+
+/*!
+  Sets curve's AutoAssign flag - in this case attributes will be set automatically
+*/
+void Plot2d_Curve::setAutoAssign( bool on )
+{
+  myAutoAssign = on;
+}
+
+/*!
+  Gets curve's AutoAssign flag state
+*/
+bool Plot2d_Curve::isAutoAssign() const
+{
+  return myAutoAssign;
+}
+
+/*!
+  Sets curve's color ( and resets AutoAssign flag )
+*/
+void Plot2d_Curve::setColor( const QColor& color )
+{
+  myColor = color;
+  myAutoAssign = false;
+}
+
+/*!
+  Gets curve's color
+*/
+QColor Plot2d_Curve::getColor() const
+{
+  return myColor;
+}
+
+/*!
+  Sets curve's marker ( and resets AutoAssign flag )
+*/
+void Plot2d_Curve::setMarker( MarkerType marker )
+{
+  myMarker = marker;
+  myAutoAssign = false;
+}
+
+/*!
+  Gets curve's marker
+*/
+Plot2d_Curve::MarkerType Plot2d_Curve::getMarker() const
+{
+  return myMarker;
+}
+
+/*!
+  Sets curve's line type and width ( and resets AutoAssign flag )
+  NOTE : A line width of 0 will produce a 1 pixel wide line using a fast algorithm for diagonals. 
+         A line width of 1 will also produce a 1 pixel wide line, but uses a slower more accurate 
+         algorithm for diagonals. 
+         For horizontal and vertical lines a line width of 0 is the same as a line width of 1.
+*/
+void Plot2d_Curve::setLine( LineType line, const int lineWidth )
+{
+  myLine = line;
+  myLineWidth = lineWidth;
+  if ( myLineWidth < 0 ) myLineWidth = 0;
+  myAutoAssign = false;
+}
+
+/*!
+  Gets curve's line type
+*/
+Plot2d_Curve::LineType Plot2d_Curve::getLine() const
+{
+  return myLine;
+}
+
+/*!
+  Gets curve's line width
+*/
+int Plot2d_Curve::getLineWidth() const
+{
+  return myLineWidth;
+}
+
+/*!
+  Sets curve's y axis
+*/
+void Plot2d_Curve::setYAxis(QwtPlot::Axis theYAxis)
+{
+  if(theYAxis == QwtPlot::yLeft || theYAxis == QwtPlot::yRight)
+    myYAxis = theYAxis;
+}
+
+/*!
+  Gets curve's y axis
+*/
+QwtPlot::Axis Plot2d_Curve::getYAxis() const
+{
+  return myYAxis;
+}
+
+/*!
+  Gets curve's minimal abscissa
+*/
+double Plot2d_Curve::getMinX() const
+{
+  QValueList<Plot2d_Point>::const_iterator aIt;
+  double aMinX = 1e150;
+  int aCurrent = 0;
+  for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) {
+    if ( (*aIt).x < aMinX )
+      aMinX = (*aIt).x;
+  }
+  return aMinX;
+}
+
+/*!
+  Gets curve's minimal ordinate
+*/
+double Plot2d_Curve::getMinY() const
+{
+  QValueList<Plot2d_Point>::const_iterator aIt;
+  double aMinY = 1e150;
+  int aCurrent = 0;
+  for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) {
+    if ( (*aIt).y < aMinY )
+      aMinY = (*aIt).y;
+  }
+  return aMinY;
+}
diff --git a/src/Plot2d/Plot2d_Curve.h b/src/Plot2d/Plot2d_Curve.h
new file mode 100755 (executable)
index 0000000..b17f7c3
--- /dev/null
@@ -0,0 +1,108 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef PLOT2D_CURVE_H
+#define PLOT2D_CURVE_H
+
+#include "Plot2d.h"
+#include <qvaluelist.h>
+#include <qptrlist.h>
+#include <qwt_plot.h>
+
+class QColor;
+
+typedef struct
+{
+  double x;
+  double y;
+} Plot2d_Point;
+
+typedef QValueList<Plot2d_Point> pointList;
+
+class PLOT2D_EXPORT Plot2d_Curve
+{
+public:
+  enum MarkerType { None,      Circle,    Rectangle, Diamond,
+        DTriangle, UTriangle, LTriangle, RTriangle,
+        Cross, XCross };
+  enum LineType { NoPen, Solid, Dash, Dot, DashDot, DashDotDot };
+
+  Plot2d_Curve();
+  virtual ~Plot2d_Curve();
+  Plot2d_Curve( const Plot2d_Curve& curve );
+  Plot2d_Curve& operator= ( const Plot2d_Curve& curve );
+
+  virtual QString getTableTitle() const;
+  
+  void        setHorTitle( const QString& title );
+  QString     getHorTitle() const;
+  void        setVerTitle( const QString& title );
+  QString     getVerTitle() const;
+  void        setHorUnits( const QString& units );
+  QString     getHorUnits() const;
+  void        setVerUnits( const QString& units );
+  QString     getVerUnits() const;
+  void        addPoint(double theX, double theY);
+  void        insertPoint(int thePos, double theX, double theY);
+  void        deletePoint(int thePos);
+  void        clearAllPoints();
+  pointList   getPointList() const;
+
+  void        setData( const double* hData, const double* vData, long size );
+  double*     horData() const;
+  double*     verData() const;
+
+  int         nbPoints() const;
+  bool        isEmpty() const;
+
+  void        setAutoAssign( bool on );
+  bool        isAutoAssign() const;
+  void        setColor( const QColor& color );
+  QColor      getColor() const;
+  void        setMarker( MarkerType marker );
+  MarkerType  getMarker() const;
+  void        setLine( LineType line, const int lineWidth = 0 );
+  LineType    getLine() const;
+  int         getLineWidth() const;
+  void        setYAxis(QwtPlot::Axis theYAxis);
+  QwtPlot::Axis getYAxis() const;
+
+  // Protection against QwtCurve::drawLines() bug in Qwt 0.4.x: 
+  // it crashes if switched to X/Y logarithmic mode, when one or more points have
+  // non-positive X/Y coordinate
+  double      getMinX() const;
+  double      getMinY() const;
+
+protected:
+  bool        myAutoAssign;
+  QString     myHorTitle;
+  QString     myVerTitle;
+  QString     myHorUnits;
+  QString     myVerUnits;
+  QColor      myColor;
+  MarkerType  myMarker;
+  LineType    myLine;
+  int         myLineWidth;
+  QwtPlot::Axis myYAxis;
+
+  pointList   myPoints;
+};
+
+typedef QPtrList<Plot2d_Curve> curveList;
+
+#endif
diff --git a/src/Plot2d/Plot2d_SetupViewDlg.cxx b/src/Plot2d/Plot2d_SetupViewDlg.cxx
new file mode 100755 (executable)
index 0000000..0969b6b
--- /dev/null
@@ -0,0 +1,669 @@
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Plot2d_SetupViewDlg.cxx
+//  Author : Vadim SANDLER
+//  Module : SALOME
+//  $Header$
+
+#include "Plot2d_SetupViewDlg.h"
+
+#include <qcheckbox.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qspinbox.h>
+#include <qtoolbutton.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcolordialog.h>
+#include <qtabwidget.h>
+
+#define MARGIN_SIZE          11
+#define SPACING_SIZE         6
+#define MIN_EDIT_WIDTH       200
+#define MIN_COMBO_WIDTH      100
+#define MIN_SPIN_WIDTH       70
+
+/*!
+  Constructor
+*/
+Plot2d_SetupViewDlg::Plot2d_SetupViewDlg( QWidget* parent, bool showDefCheck, bool secondAxisY )
+    : QDialog( parent, "Plot2d_SetupViewDlg", true, 
+         WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+{
+  mySecondAxisY = secondAxisY;
+  setCaption( tr("TLT_SETUP_PLOT2D_VIEW") );
+  setSizeGripEnabled( TRUE );
+  QGridLayout* topLayout = new QGridLayout( this ); 
+  topLayout->setSpacing( SPACING_SIZE );
+  topLayout->setMargin( MARGIN_SIZE );
+  
+  // main title
+  myTitleCheck = new QCheckBox( tr( "PLOT2D_ENABLE_MAIN_TITLE" ), this );
+  myTitleEdit  = new QLineEdit( this );
+  myTitleEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myTitleEdit->setMinimumWidth( MIN_EDIT_WIDTH );
+  // curve type : points, lines, spline
+  QLabel* aCurveLab = new QLabel( tr( "PLOT2D_CURVE_TYPE_LBL" ), this );
+  myCurveCombo      = new QComboBox( false, this );
+  myCurveCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myCurveCombo->setMinimumWidth( MIN_COMBO_WIDTH );
+  myCurveCombo->insertItem( tr( "PLOT2D_CURVE_TYPE_POINTS" ) );
+  myCurveCombo->insertItem( tr( "PLOT2D_CURVE_TYPE_LINES" ) );
+  myCurveCombo->insertItem( tr( "PLOT2D_CURVE_TYPE_SPLINE" ) );
+  // legend
+  myLegendCheck = new QCheckBox( tr( "PLOT2D_ENABLE_LEGEND" ), this );
+  myLegendCombo = new QComboBox( false, this );
+  myLegendCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myLegendCombo->setMinimumWidth( MIN_COMBO_WIDTH );
+  myLegendCombo->insertItem( tr( "PLOT2D_LEGEND_POSITION_LEFT" ) );
+  myLegendCombo->insertItem( tr( "PLOT2D_LEGEND_POSITION_RIGHT" ) );
+  myLegendCombo->insertItem( tr( "PLOT2D_LEGEND_POSITION_TOP" ) );
+  myLegendCombo->insertItem( tr( "PLOT2D_LEGEND_POSITION_BOTTOM" ) );
+  // marker size
+  QLabel* aMarkerLab  = new QLabel( tr( "PLOT2D_MARKER_SIZE_LBL" ), this );
+  myMarkerSpin = new QSpinBox( 0, 100, 1, this );
+  myMarkerSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myMarkerSpin->setMinimumWidth( MIN_SPIN_WIDTH );
+
+  // background color
+  QLabel* aBGLab  = new QLabel( tr( "PLOT2D_BACKGROUND_COLOR_LBL" ), this );
+  myBackgroundBtn = new QToolButton( this );
+  myBackgroundBtn->setMinimumWidth(20);
+
+  // scale mode
+  QGroupBox* aScaleGrp = new QGroupBox( tr( "PLOT2D_SCALE_TLT" ), this );
+  aScaleGrp->setColumnLayout(0, Qt::Vertical );
+  aScaleGrp->layout()->setSpacing( 0 );  aScaleGrp->layout()->setMargin( 0 );
+  QGridLayout* aScaleLayout = new QGridLayout( aScaleGrp->layout() );
+  aScaleLayout->setMargin( MARGIN_SIZE ); aScaleLayout->setSpacing( SPACING_SIZE );
+
+  QLabel* xScaleLab = new QLabel( tr( "PLOT2D_SCALE_MODE_HOR" ), aScaleGrp );
+  myXModeCombo = new QComboBox( false, aScaleGrp );
+  myXModeCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myXModeCombo->setMinimumWidth( MIN_COMBO_WIDTH );
+  myXModeCombo->insertItem( tr( "PLOT2D_SCALE_MODE_LINEAR" ) );
+  myXModeCombo->insertItem( tr( "PLOT2D_SCALE_MODE_LOGARITHMIC" ) );
+  QLabel* yScaleLab = new QLabel( tr( "PLOT2D_SCALE_MODE_VER" ), aScaleGrp );
+  myYModeCombo = new QComboBox( false, aScaleGrp );
+  myYModeCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myYModeCombo->setMinimumWidth( MIN_COMBO_WIDTH );
+  myYModeCombo->insertItem( tr( "PLOT2D_SCALE_MODE_LINEAR" ) );
+  myYModeCombo->insertItem( tr( "PLOT2D_SCALE_MODE_LOGARITHMIC" ) );
+
+  aScaleLayout->addWidget( xScaleLab,    0, 0 );
+  aScaleLayout->addWidget( myXModeCombo, 0, 1 );
+  aScaleLayout->addWidget( yScaleLab,    0, 2 );
+  aScaleLayout->addWidget( myYModeCombo, 0, 3 );
+
+  // tab widget for choose properties of axis 
+  QTabWidget* aTabWidget = new QTabWidget( this, "tabWidget" );
+
+  // widget for parameters on Ox
+  QWidget* aXWidget = new QWidget(aTabWidget);
+  QGridLayout* aXLayout = new QGridLayout( aXWidget ); 
+  aXLayout->setSpacing( SPACING_SIZE );
+  aXLayout->setMargin( MARGIN_SIZE );
+  // axis title
+  myTitleXCheck = new QCheckBox( tr( "PLOT2D_ENABLE_HOR_TITLE" ), aXWidget );
+  myTitleXEdit  = new QLineEdit( aXWidget );
+  myTitleXEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myTitleXEdit->setMinimumWidth( MIN_EDIT_WIDTH );
+  aXLayout->addWidget( myTitleXCheck,         1,    0    );
+  aXLayout->addMultiCellWidget( myTitleXEdit, 1, 1, 1, 3 );
+  // grid
+  QGroupBox* aGridGrpX = new QGroupBox( tr( "PLOT2D_GRID_TLT" ), aXWidget );
+  aGridGrpX->setColumnLayout(0, Qt::Vertical );
+  aGridGrpX->layout()->setSpacing( 0 );  aGridGrpX->layout()->setMargin( 0 );
+  QGridLayout* aGridLayoutX = new QGridLayout( aGridGrpX->layout() );
+  aGridLayoutX->setMargin( MARGIN_SIZE ); aGridLayoutX->setSpacing( SPACING_SIZE );
+  myXGridCheck      = new QCheckBox( tr( "PLOT2D_GRID_ENABLE_HOR_MAJOR" ), aGridGrpX );
+  QLabel* aXMajLbl  = new QLabel( tr( "PLOT2D_MAX_INTERVALS" ), aGridGrpX);
+  myXGridSpin       = new QSpinBox( 1, 100, 1, aGridGrpX );
+  myXGridSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myXGridSpin->setMinimumWidth( MIN_SPIN_WIDTH );
+  myXMinGridCheck      = new QCheckBox( tr( "PLOT2D_GRID_ENABLE_HOR_MINOR" ), aGridGrpX );
+  QLabel* aXMinLbl     = new QLabel( tr( "PLOT2D_MAX_INTERVALS" ), aGridGrpX);
+  myXMinGridSpin       = new QSpinBox( 1, 100, 1, aGridGrpX );
+  myXMinGridSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myXMinGridSpin->setMinimumWidth( MIN_SPIN_WIDTH );
+
+  aGridLayoutX->addWidget( myXGridCheck,    0, 0 );
+  aGridLayoutX->addWidget( aXMajLbl,        0, 1 );
+  aGridLayoutX->addWidget( myXGridSpin,     0, 2 );
+  aGridLayoutX->addWidget( myXMinGridCheck, 1, 0 );
+  aGridLayoutX->addWidget( aXMinLbl,        1, 1 );
+  aGridLayoutX->addWidget( myXMinGridSpin,  1, 2 );
+  aXLayout->addMultiCellWidget( aGridGrpX, 3, 3, 0, 3 );
+
+  aTabWidget->addTab( aXWidget, tr( "INF_AXES_X" ) );
+
+  // widget for parameters on Oy
+  QWidget* aYWidget = new QWidget(aTabWidget);
+  QGridLayout* aYLayout = new QGridLayout( aYWidget ); 
+  aYLayout->setSpacing( SPACING_SIZE );
+  aYLayout->setMargin( MARGIN_SIZE );
+  // axis title
+  myTitleYCheck = new QCheckBox( tr( "PLOT2D_ENABLE_VER_TITLE" ), aYWidget );
+  myTitleYEdit  = new QLineEdit( aYWidget );
+  myTitleYEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myTitleYEdit->setMinimumWidth( MIN_EDIT_WIDTH );
+  aYLayout->addWidget( myTitleYCheck,         1,    0    );
+  aYLayout->addMultiCellWidget( myTitleYEdit, 1, 1, 1, 3 );
+  // grid
+  QGroupBox* aGridGrpY = new QGroupBox( tr( "PLOT2D_GRID_TLT" ), aYWidget );
+  aGridGrpY->setColumnLayout(0, Qt::Vertical );
+  aGridGrpY->layout()->setSpacing( 0 );  aGridGrpY->layout()->setMargin( 0 );
+  QGridLayout* aGridLayoutY = new QGridLayout( aGridGrpY->layout() );
+  aGridLayoutY->setMargin( MARGIN_SIZE ); aGridLayoutY->setSpacing( SPACING_SIZE );
+  myYGridCheck      = new QCheckBox( tr( "PLOT2D_GRID_ENABLE_VER_MAJOR" ), aGridGrpY );
+  QLabel* aYMajLbl  = new QLabel( tr( "PLOT2D_MAX_INTERVALS" ), aGridGrpY);
+  myYGridSpin       = new QSpinBox( 1, 100, 1, aGridGrpY );
+  myYGridSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myYGridSpin->setMinimumWidth( MIN_SPIN_WIDTH );
+  myYMinGridCheck      = new QCheckBox( tr( "PLOT2D_GRID_ENABLE_VER_MINOR" ), aGridGrpY );
+  QLabel* aYMinLbl     = new QLabel( tr( "PLOT2D_MAX_INTERVALS" ), aGridGrpY);
+  myYMinGridSpin       = new QSpinBox( 1, 100, 1, aGridGrpY );
+  myYMinGridSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  myYMinGridSpin->setMinimumWidth( MIN_SPIN_WIDTH );
+
+  aGridLayoutY->addWidget( myYGridCheck,    0, 0 );
+  aGridLayoutY->addWidget( aYMajLbl,        0, 1 );
+  aGridLayoutY->addWidget( myYGridSpin,     0, 2 );
+  aGridLayoutY->addWidget( myYMinGridCheck, 1, 0 );
+  aGridLayoutY->addWidget( aYMinLbl,        1, 1 );
+  aGridLayoutY->addWidget( myYMinGridSpin,  1, 2 );
+  aYLayout->addMultiCellWidget( aGridGrpY, 3, 3, 0, 3 );
+
+  aTabWidget->addTab( aYWidget, tr( "INF_AXES_Y_LEFT" ) );
+
+  // if exist second axis Oy, addition new tab widget for right axis
+  if (mySecondAxisY) {
+    // widget for parameters on Oy
+    QWidget* aYWidget2 = new QWidget(aTabWidget);
+    QGridLayout* aYLayout2 = new QGridLayout( aYWidget2 );
+    aYLayout2->setSpacing( SPACING_SIZE );
+    aYLayout2->setMargin( MARGIN_SIZE );
+    // axis title
+    myTitleY2Check = new QCheckBox( tr( "PLOT2D_ENABLE_VER_TITLE" ), aYWidget2 );
+    myTitleY2Edit  = new QLineEdit( aYWidget2 );
+    myTitleY2Edit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+    myTitleY2Edit->setMinimumWidth( MIN_EDIT_WIDTH );
+    aYLayout2->addWidget( myTitleY2Check,         1,    0    );
+    aYLayout2->addMultiCellWidget( myTitleY2Edit, 1, 1, 1, 3 );
+    // grid
+    QGroupBox* aGridGrpY2 = new QGroupBox( tr( "PLOT2D_GRID_TLT" ), aYWidget2 );
+    aGridGrpY2->setColumnLayout(0, Qt::Vertical );
+    aGridGrpY2->layout()->setSpacing( 0 );  aGridGrpY2->layout()->setMargin( 0 );
+    QGridLayout* aGridLayoutY2 = new QGridLayout( aGridGrpY2->layout() );
+    aGridLayoutY2->setMargin( MARGIN_SIZE ); aGridLayoutY2->setSpacing( SPACING_SIZE );
+    myY2GridCheck      = new QCheckBox( tr( "PLOT2D_GRID_ENABLE_VER_MAJOR" ), aGridGrpY2 );
+    QLabel* aY2MajLbl  = new QLabel( tr( "PLOT2D_MAX_INTERVALS" ), aGridGrpY2);
+    myY2GridSpin       = new QSpinBox( 1, 100, 1, aGridGrpY2 );
+    myY2GridSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+    myY2GridSpin->setMinimumWidth( MIN_SPIN_WIDTH );
+    myY2MinGridCheck      = new QCheckBox( tr( "PLOT2D_GRID_ENABLE_VER_MINOR" ), aGridGrpY2 );
+    QLabel* aY2MinLbl     = new QLabel( tr( "PLOT2D_MAX_INTERVALS" ), aGridGrpY2);
+    myY2MinGridSpin       = new QSpinBox( 1, 100, 1, aGridGrpY2 );
+    myY2MinGridSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+    myY2MinGridSpin->setMinimumWidth( MIN_SPIN_WIDTH );
+
+    aGridLayoutY2->addWidget( myY2GridCheck,    0, 0 );
+    aGridLayoutY2->addWidget( aY2MajLbl,        0, 1 );
+    aGridLayoutY2->addWidget( myY2GridSpin,     0, 2 );
+    aGridLayoutY2->addWidget( myY2MinGridCheck, 1, 0 );
+    aGridLayoutY2->addWidget( aY2MinLbl,        1, 1 );
+    aGridLayoutY2->addWidget( myY2MinGridSpin,  1, 2 );
+    aYLayout2->addMultiCellWidget( aGridGrpY2, 3, 3, 0, 3 );
+
+    aTabWidget->addTab( aYWidget2, tr( "INF_AXES_Y_RIGHT" ) );
+  }
+  else {
+    myTitleY2Check   = 0;
+    myTitleY2Edit    = 0;
+    myY2GridCheck    = 0;
+    myY2GridSpin     = 0;
+    myY2MinGridCheck = 0;
+    myY2MinGridSpin  = 0;
+    myY2ModeCombo    = 0;
+  }
+  aTabWidget->setCurrentPage( 0 );
+  /* "Set as default" check box */
+  myDefCheck = new QCheckBox( tr( "PLOT2D_SET_AS_DEFAULT_CHECK" ), this );
+  /* OK/Cancel buttons */
+  myOkBtn = new QPushButton( tr( "BUT_OK" ), this );
+  myOkBtn->setAutoDefault( TRUE );
+  myOkBtn->setDefault( TRUE );
+  myCancelBtn = new QPushButton( tr( "BUT_CANCEL" ), this );
+  myCancelBtn->setAutoDefault( TRUE );
+  QHBoxLayout* btnLayout = new QHBoxLayout;
+  btnLayout->addWidget( myOkBtn );
+  btnLayout->addStretch();
+  btnLayout->addWidget( myCancelBtn );
+  
+  // layout widgets
+  topLayout->addWidget( myTitleCheck,          0,    0    );
+  topLayout->addMultiCellWidget( myTitleEdit,  0, 0, 1, 3 );
+  topLayout->addWidget( aCurveLab,             1,    0    );
+  topLayout->addWidget( myCurveCombo,          1,    1    );
+  topLayout->addWidget( myLegendCheck,         1,    2    );
+  topLayout->addWidget( myLegendCombo,         1,    3    );
+  topLayout->addWidget( aMarkerLab,            2,    0    );
+  topLayout->addWidget( myMarkerSpin,          2,    1    );
+  QHBoxLayout* bgLayout = new QHBoxLayout;
+  bgLayout->addWidget( myBackgroundBtn ); bgLayout->addStretch();
+  topLayout->addWidget( aBGLab,                2,    2    );
+  topLayout->addLayout( bgLayout,              2,    3    );
+  topLayout->addMultiCellWidget( aScaleGrp,    3, 3, 0, 3 );
+  topLayout->addMultiCellWidget( aTabWidget,   4, 4, 0, 3 );
+  topLayout->addMultiCellWidget( myDefCheck,   5, 5, 0, 3 );
+  topLayout->setRowStretch( 5, 5 );
+
+  topLayout->addMultiCellLayout( btnLayout,    6, 6, 0, 3 );
+  
+  if ( !showDefCheck )
+    myDefCheck->hide();
+
+  connect( myTitleCheck,    SIGNAL( clicked() ), this, SLOT( onMainTitleChecked() ) );
+  connect( myTitleXCheck,   SIGNAL( clicked() ), this, SLOT( onXTitleChecked() ) );
+  connect( myTitleYCheck,   SIGNAL( clicked() ), this, SLOT( onYTitleChecked() ) );
+  connect( myBackgroundBtn, SIGNAL( clicked() ), this, SLOT( onBackgroundClicked() ) );
+  connect( myLegendCheck,   SIGNAL( clicked() ), this, SLOT( onLegendChecked() ) );
+  connect( myXGridCheck,    SIGNAL( clicked() ), this, SLOT( onXGridMajorChecked() ) );
+  connect( myYGridCheck,    SIGNAL( clicked() ), this, SLOT( onYGridMajorChecked() ) );
+  connect( myXMinGridCheck, SIGNAL( clicked() ), this, SLOT( onXGridMinorChecked() ) );
+  connect( myYMinGridCheck, SIGNAL( clicked() ), this, SLOT( onYGridMinorChecked() ) );
+
+  connect( myOkBtn,         SIGNAL( clicked() ), this, SLOT( accept() ) );
+  connect( myCancelBtn,     SIGNAL( clicked() ), this, SLOT( reject() ) );
+  
+  if (mySecondAxisY) {
+    connect( myTitleY2Check,   SIGNAL( clicked() ), this, SLOT( onY2TitleChecked() ) );
+    connect( myY2GridCheck,    SIGNAL( clicked() ), this, SLOT( onY2GridMajorChecked() ) );
+    connect( myY2MinGridCheck, SIGNAL( clicked() ), this, SLOT( onY2GridMinorChecked() ) );
+  }
+
+  // init fields
+  setBackgroundColor( Qt::gray );
+  onMainTitleChecked();
+  onXTitleChecked();
+  onYTitleChecked();
+  onLegendChecked();
+  onXGridMajorChecked();
+  onYGridMajorChecked();
+  onXGridMinorChecked();
+  if (mySecondAxisY) {
+    onY2TitleChecked();
+    onY2GridMajorChecked();
+    onY2GridMinorChecked();
+  }
+}
+
+/*!
+  Destructor
+*/
+Plot2d_SetupViewDlg::~Plot2d_SetupViewDlg()
+{
+}
+/*!
+  Sets main title attributes
+*/
+void Plot2d_SetupViewDlg::setMainTitle( bool enable, const QString& title )
+{
+  myTitleCheck->setChecked( enable );
+  if ( !title.isNull() )
+    myTitleEdit->setText( title );
+  onMainTitleChecked();
+}
+/*!
+  Returns TRUE if main title is enabled
+*/
+bool Plot2d_SetupViewDlg::isMainTitleEnabled()
+{
+  return myTitleCheck->isChecked();
+}
+/*!
+  Gets main title
+*/
+QString Plot2d_SetupViewDlg::getMainTitle()
+{
+  return myTitleEdit->text();
+}
+/*!
+  Sets horizontal axis title attributes
+*/
+void Plot2d_SetupViewDlg::setXTitle( bool enable, const QString& title )
+{
+  myTitleXCheck->setChecked( enable );
+  if ( !title.isNull() )
+    myTitleXEdit->setText( title );
+  onXTitleChecked();
+}
+/*!
+  Returns TRUE if horizontal axis title is enabled
+*/
+bool Plot2d_SetupViewDlg::isXTitleEnabled()
+{
+  return myTitleXCheck->isChecked();
+}
+/*!
+  Gets horizontal axis title
+*/
+QString Plot2d_SetupViewDlg::getXTitle()
+{
+  return myTitleXEdit->text();
+}
+/*!
+  Sets vertical left axis title attributes
+*/
+void Plot2d_SetupViewDlg::setYTitle( bool enable, const QString& title )
+{
+  myTitleYCheck->setChecked( enable );
+  if ( !title.isNull() )
+    myTitleYEdit->setText( title );
+  onYTitleChecked();
+}
+/*!
+  Sets vertical right axis title attributes
+*/
+void Plot2d_SetupViewDlg::setY2Title( bool enable, const QString& title )
+{
+  myTitleY2Check->setChecked( enable );
+  if ( !title.isNull() )
+    myTitleY2Edit->setText( title );
+  onY2TitleChecked();
+}
+/*!
+  Returns TRUE if vertical left axis title is enabled
+*/
+bool Plot2d_SetupViewDlg::isYTitleEnabled()
+{
+  return myTitleYCheck->isChecked();
+}
+/*!
+  Returns TRUE if vertical right axis title is enabled
+*/
+bool Plot2d_SetupViewDlg::isY2TitleEnabled()
+{
+  return myTitleY2Check->isChecked();
+}
+/*!
+  Gets vertical left axis title
+*/
+QString Plot2d_SetupViewDlg::getYTitle()
+{
+  return myTitleYEdit->text();
+}
+/*!
+  Gets vertical right axis title
+*/
+QString Plot2d_SetupViewDlg::getY2Title()
+{
+  return myTitleY2Edit->text();
+}
+/*!
+  Sets curve type : 0 - points, 1 - lines, 2 - splines
+*/
+void Plot2d_SetupViewDlg::setCurveType( const int type )
+{
+  myCurveCombo->setCurrentItem( type );
+}
+/*!
+  Gets curve type : 0 - points, 1 - lines, 2 - splines
+*/
+int Plot2d_SetupViewDlg::getCurveType()
+{
+  return myCurveCombo->currentItem();
+}
+/*!
+  Sets legend attributes : pos = 0 - left, 1 - right, 2 - top, 3 - bottom
+*/
+void Plot2d_SetupViewDlg::setLegend( bool enable, int pos )
+{
+  myLegendCheck->setChecked( enable );
+  myLegendCombo->setCurrentItem( pos );
+  onLegendChecked();
+}
+/*!
+  Returns TRUE if legend is enabled
+*/
+bool Plot2d_SetupViewDlg::isLegendEnabled()
+{
+  return myLegendCheck->isChecked();
+}
+/*!
+  Returns legend position
+*/
+int Plot2d_SetupViewDlg::getLegendPos()
+{
+  return myLegendCombo->currentItem();
+}
+/*!
+  Sets marker size
+*/
+void Plot2d_SetupViewDlg::setMarkerSize( const int size )
+{
+  myMarkerSpin->setValue( size );
+}
+/*!
+  Gets marker size
+*/
+int Plot2d_SetupViewDlg::getMarkerSize()
+{
+  return myMarkerSpin->value();
+}
+/*!
+  Sets background color
+*/
+void Plot2d_SetupViewDlg::setBackgroundColor( const QColor& color )
+{
+  QPalette pal = myBackgroundBtn->palette();
+  QColorGroup ca = pal.active();
+  ca.setColor( QColorGroup::Button, color );
+  QColorGroup ci = pal.inactive();
+  ci.setColor( QColorGroup::Button, color );
+  pal.setActive( ca );
+  pal.setInactive( ci );
+  myBackgroundBtn->setPalette( pal );
+}
+/*!
+  Gets background color
+*/
+QColor Plot2d_SetupViewDlg::getBackgroundColor()
+{
+  return myBackgroundBtn->palette().active().button();
+}
+/*!
+  Sets major grid parameters
+*/
+void Plot2d_SetupViewDlg::setMajorGrid( bool enableX, const int divX,
+                                        bool enableY, const int divY,
+                                        bool enableY2, const int divY2  )
+{
+  myXGridCheck->setChecked( enableX );
+  myXGridSpin->setValue( divX );
+  myYGridCheck->setChecked( enableY );
+  myYGridSpin->setValue( divY );
+  onXGridMajorChecked();
+  onYGridMajorChecked();
+  if (mySecondAxisY) {
+    myY2GridCheck->setChecked( enableY2 );
+    myY2GridSpin->setValue( divY2 );
+    onY2GridMajorChecked();
+  }
+}
+/*!
+  Gets major grid parameters
+*/
+void Plot2d_SetupViewDlg::getMajorGrid( bool& enableX, int& divX,
+                                        bool& enableY, int& divY,
+                                        bool& enableY2, int& divY2)
+{
+  enableX  = myXGridCheck->isChecked();
+  divX     = myXGridSpin->value();
+  enableY  = myYGridCheck->isChecked();
+  divY     = myYGridSpin->value();
+  if (mySecondAxisY) {
+    enableY2 = myY2GridCheck->isChecked();
+    divY2    = myY2GridSpin->value();
+  }
+  else {
+    enableY2 = false;
+    divY2    = 1;
+  }
+}
+/*!
+  Sets minor grid parameters
+*/
+void Plot2d_SetupViewDlg::setMinorGrid( bool enableX, const int divX,
+                                        bool enableY, const int divY,
+                                        bool enableY2, const int divY2)
+{
+  myXMinGridCheck->setChecked( enableX );
+  myXMinGridSpin->setValue( divX );
+  myYMinGridCheck->setChecked( enableY );
+  myYMinGridSpin->setValue( divY );
+  onXGridMinorChecked();
+  onYGridMinorChecked();
+  if (mySecondAxisY) {
+    myY2MinGridCheck->setChecked( enableY2 );
+    myY2MinGridSpin->setValue( divY2 );
+    onY2GridMinorChecked();
+  }
+}
+/*!
+  Gets minor grid parameters
+*/
+void Plot2d_SetupViewDlg::getMinorGrid( bool& enableX, int& divX,
+                                        bool& enableY, int& divY,
+                                        bool& enableY2, int& divY2)
+{
+  enableX  = myXMinGridCheck->isChecked();
+  divX     = myXMinGridSpin->value();
+  enableY  = myYMinGridCheck->isChecked();
+  divY     = myYMinGridSpin->value();
+  if (mySecondAxisY) {
+    enableY2 = myY2MinGridCheck->isChecked();
+    divY2    = myY2MinGridSpin->value();
+  }
+  else {
+    enableY2 = false;
+    divY2    = 1;
+  }
+}
+/*!
+  Sets scale mode for hor. and ver. axes : 0 - linear, 1 - logarithmic
+*/
+void Plot2d_SetupViewDlg::setScaleMode( const int xMode, const int yMode )
+{
+  myXModeCombo->setCurrentItem( xMode );
+  myYModeCombo->setCurrentItem( yMode );
+}
+/*!
+  Gets scale mode for hor. axis : 0 - linear, 1 - logarithmic
+*/
+int  Plot2d_SetupViewDlg::getXScaleMode()
+{
+  return myXModeCombo->currentItem();
+}
+/*!
+  Gets scale mode for hor. axis : 0 - linear, 1 - logarithmic
+*/
+int  Plot2d_SetupViewDlg::getYScaleMode()
+{
+  return myYModeCombo->currentItem();
+}
+/*!
+  Slot, called when user clicks "Show main title" check box
+*/
+void Plot2d_SetupViewDlg::onMainTitleChecked()
+{
+  myTitleEdit->setEnabled( myTitleCheck->isChecked() );
+}
+/*!
+  Slot, called when user clicks "Show horizontal axis title" check box
+*/
+void Plot2d_SetupViewDlg::onXTitleChecked()
+{
+  myTitleXEdit->setEnabled( myTitleXCheck->isChecked() );
+}
+/*!
+  Slot, called when user clicks "Show vertical left axis title" check box
+*/
+void Plot2d_SetupViewDlg::onYTitleChecked()
+{
+  myTitleYEdit->setEnabled( myTitleYCheck->isChecked() );
+}
+/*!
+  Slot, called when user clicks "Show vertical right axis title" check box
+*/
+void Plot2d_SetupViewDlg::onY2TitleChecked()
+{
+  myTitleY2Edit->setEnabled( myTitleY2Check->isChecked() );
+}
+/*!
+  Slot, called when user clicks "Change bacground color" button
+*/
+void Plot2d_SetupViewDlg::onBackgroundClicked()
+{
+  QColor color = QColorDialog::getColor( getBackgroundColor() );
+  if ( color.isValid() ) {
+    setBackgroundColor( color );
+  }
+}
+/*!
+  Slot, called when user clicks "Show Legend" check box
+*/
+void Plot2d_SetupViewDlg::onLegendChecked()
+{
+  myLegendCombo->setEnabled( myLegendCheck->isChecked() );
+}
+/*!
+  Slot, called when user clicks "Enable hor. major grid" check box
+*/
+void Plot2d_SetupViewDlg::onXGridMajorChecked()
+{
+  myXMinGridCheck->setEnabled( myXGridCheck->isChecked() );
+}
+/*!
+  Slot, called when user clicks  "Enable ver. major grid" check box
+*/
+void Plot2d_SetupViewDlg::onYGridMajorChecked()
+{
+  myYMinGridCheck->setEnabled( myYGridCheck->isChecked() );
+}
+/*!
+  Slot, called when user clicks  "Enable ver. major grid" check box
+*/
+void Plot2d_SetupViewDlg::onY2GridMajorChecked()
+{
+  myY2MinGridCheck->setEnabled( myY2GridCheck->isChecked() );
+}
+/*!
+  Slot, called when user clicks  "Enable hor. minor grid" check box
+*/
+void Plot2d_SetupViewDlg::onXGridMinorChecked()
+{
+}
+/*!
+  Slot, called when user clicks  "Enable ver. minor grid" check box
+*/
+void Plot2d_SetupViewDlg::onYGridMinorChecked()
+{
+}
+/*!
+  Slot, called when user clicks  "Enable ver. minor grid" check box
+*/
+void Plot2d_SetupViewDlg::onY2GridMinorChecked()
+{
+}
+/*!
+  Retursns true if "Set as default" check box is on
+*/
+bool Plot2d_SetupViewDlg::isSetAsDefault()
+{
+  return myDefCheck->isChecked();
+}
diff --git a/src/Plot2d/Plot2d_ViewFrame.cxx b/src/Plot2d/Plot2d_ViewFrame.cxx
new file mode 100755 (executable)
index 0000000..67933db
--- /dev/null
@@ -0,0 +1,1928 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "Plot2d_ViewFrame.h"
+
+#include "Plot2d_Prs.h"
+#include "Plot2d_Curve.h"
+#include "Plot2d_FitDataDlg.h"
+#include "Plot2d_ViewWindow.h"
+#include "Plot2d_SetupViewDlg.h"
+
+#include "SUIT_Tools.h"
+#include "SUIT_Session.h"
+#include "SUIT_MessageBox.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_Application.h"
+
+#include "qapplication.h"
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qcursor.h>
+#include <qcolordialog.h>
+#include <qptrlist.h>
+#include <qlayout.h>
+#include <qmap.h>
+#include <qpainter.h>
+#include <qpaintdevicemetrics.h>
+
+#include <qwt_math.h>
+#include <qwt_plot_canvas.h>
+#include <iostream>
+#include <stdlib.h>
+#include <qprinter.h>
+
+#include <qwt_legend.h>
+
+#define DEFAULT_LINE_WIDTH     0     // (default) line width
+#define DEFAULT_MARKER_SIZE    9     // default marker size
+#define MIN_RECT_SIZE          11    // min sensibility area size
+
+const char* imageZoomCursor[] = { 
+"32 32 3 1",
+". c None",
+"a c #000000",
+"# c #ffffff",
+"................................",
+"................................",
+".#######........................",
+"..aaaaaaa.......................",
+"................................",
+".............#####..............",
+"...........##.aaaa##............",
+"..........#.aa.....a#...........",
+".........#.a.........#..........",
+".........#a..........#a.........",
+"........#.a...........#.........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+".........#...........#.a........",
+".........#a..........#a.........",
+".........##.........#.a.........",
+"........#####.....##.a..........",
+".......###aaa#####.aa...........",
+"......###aa...aaaaa.......#.....",
+".....###aa................#a....",
+"....###aa.................#a....",
+"...###aa...............#######..",
+"....#aa.................aa#aaaa.",
+".....a....................#a....",
+"..........................#a....",
+"...........................a....",
+"................................",
+"................................",
+"................................",
+"................................"};
+
+const char* imageCrossCursor[] = { 
+  "32 32 3 1",
+  ". c None",
+  "a c #000000",
+  "# c #ffffff",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "...............#................",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  ".......#################........",
+  "........aaaaaaa#aaaaaaaaa.......",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "...............#a...............",
+  "................a...............",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................",
+  "................................"};
+  
+
+//=================================================================================
+// Plot2d_ViewFrame implementation
+//=================================================================================
+
+/*!
+  Constructor
+*/
+Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
+     : QWidget (parent, title, 0),
+       myOperation( NoOpId ), 
+       myCurveType( 1 ), 
+       myShowLegend( true ), myLegendPos( 1 ),
+       myMarkerSize( DEFAULT_MARKER_SIZE ),
+       myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
+       myBackground( white ),
+       myTitleEnabled( true ), myXTitleEnabled( true ),
+       myYTitleEnabled( true ), myY2TitleEnabled (true),
+       myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ), 
+       myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
+       myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
+       myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
+       myXMode( 0 ), myYMode( 0 ), mySecondY( false )
+{
+  /* Plot 2d View */
+  QVBoxLayout* aLayout = new QVBoxLayout( this ); 
+  myPlot = new Plot2d_Plot2d( this );
+  aLayout->addWidget( myPlot );
+
+//  createActions();
+
+  connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
+     this,   SLOT( plotMouseMoved( const QMouseEvent& ) ) );
+  connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
+     this,   SLOT( plotMousePressed( const QMouseEvent& ) ) );
+  connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
+     this,   SLOT( plotMouseReleased( const QMouseEvent& ) ) );
+  //connect( myPlot, SIGNAL( legendClicked( long ) ),
+  //   this,   SLOT( onLegendClicked( long ) ) );
+
+  /* Initial Setup - get from the preferences */
+  readPreferences();
+
+  myPlot->setMargin( 5 );
+  setCurveType( myCurveType, false );
+  setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
+  setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
+            myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
+
+  setTitle( myTitleEnabled,  myTitle,  MainTitle, false );
+  setTitle( myXTitleEnabled, myXTitle, XTitle, false );
+  setTitle( myYTitleEnabled, myYTitle, YTitle, false );
+
+  if (mySecondY)
+    setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
+  setHorScaleMode( myXMode, false );
+  setVerScaleMode( myYMode, false );
+  setBackgroundColor( myBackground );
+  setLegendPos( myLegendPos );
+  showLegend( myShowLegend, false );
+  myPlot->replot();
+
+  if ( parent ) {
+    resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
+  }
+  QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
+  QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
+  myXDistance = xMap.d2() - xMap.d1();
+  myYDistance = yMap.d2() - yMap.d1();
+  myYDistance2 = 0;
+  if (mySecondY) {
+    QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
+    myYDistance2 = yMap2.d2() - yMap2.d1();
+  }
+}
+/*!
+  Destructor
+*/
+Plot2d_ViewFrame::~Plot2d_ViewFrame()
+{
+}
+/*!
+  Gets window's central widget
+*/
+QWidget* Plot2d_ViewFrame::getViewWidget()
+{
+  return (QWidget*)myPlot;
+}
+/*!
+  Actually this method just re-displays all curves which are presented in the viewer
+*/
+void Plot2d_ViewFrame::DisplayAll()
+{
+  QList<Plot2d_Curve> clist;
+  getCurves( clist );
+  for ( int i = 0; i < (int)clist.count(); i++ ) {
+    updateCurve( clist.at( i ), false );
+  }
+  myPlot->replot();
+}
+/*!
+   Removes all curves from the view
+*/
+void Plot2d_ViewFrame::EraseAll() 
+{
+  myPlot->clear();
+  myCurves.clear();
+  myPlot->replot();
+}
+/*!
+  Redraws viewframe contents
+*/
+void Plot2d_ViewFrame::Repaint()
+{
+  myPlot->replot();
+}
+/*!
+  Display presentation
+*/
+void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
+{
+  if ( !prs || prs->IsNull() )
+    return;
+
+  if (prs->isSecondY()) {
+    myPlot->enableAxis(QwtPlot::yRight, true);
+    mySecondY = true;
+  }
+  else {
+    myPlot->enableAxis(QwtPlot::yRight, false);
+    mySecondY = false;
+  }
+
+  // display all curves from presentation
+  curveList aCurves = prs->getCurves();
+  displayCurves( aCurves );
+  setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
+  setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
+            myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
+}
+
+/*!
+  Erase presentation
+*/
+void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
+{
+  if ( !prs || prs->IsNull() )
+    return;
+
+  // erase all curves from presentation
+  curveList aCurves = prs->getCurves();
+  eraseCurves( aCurves );
+}
+
+/*!
+  Sets title
+*/
+void Plot2d_ViewFrame::setTitle( const QString& title )
+{
+  setTitle( myTitleEnabled, title, MainTitle, true );
+}
+
+/*!
+  Reads Plot2d view settings from the preferences
+*/
+void Plot2d_ViewFrame::readPreferences()
+{
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+  myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
+  setCurveType( resMgr->integerValue( "Plot2d", "CurveType", myCurveType ) );
+
+  myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
+  myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
+  myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
+  myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
+
+  myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
+  myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
+  myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
+  myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
+
+  myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
+  myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
+  myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
+
+  myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
+  myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
+  myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
+
+  myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
+  myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
+  if ( mySecondY )
+    myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
+
+  myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
+  myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
+  if ( mySecondY )
+    myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
+
+  myXMode = resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode );
+  myXMode = QMAX( 0, QMIN( 1, myXMode ) );
+
+  myYMode = resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode );
+  myYMode = QMAX( 0, QMIN( 1, myYMode ) );
+}
+
+/*!
+  Writes Plot2d view settings to the preferences
+*/
+void Plot2d_ViewFrame::writePreferences()
+{
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+  resMgr->setValue( "Plot2d", "CurveType", myCurveType );
+  resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
+  resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
+  resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
+  resMgr->setValue( "Plot2d", "Background", myBackground );
+  resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
+  resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
+  resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
+  if ( mySecondY )
+    resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
+
+  resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
+  resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
+  resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
+  resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
+
+  resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
+  resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
+
+  resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
+  resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
+
+  resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
+
+  if ( mySecondY )
+  {
+    resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
+    resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
+    resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
+    resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
+  }
+
+  resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
+}
+
+/*!
+  Prints mouse cursor coordinates into string
+*/
+QString Plot2d_ViewFrame::getInfo( const QPoint& pnt ) 
+{
+  int i;
+  bool xFound = false, yFound = false;
+  double xCoord, yCoord;
+  const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
+  for ( i = 0; i < aXscale->majCnt(); i++ ) {
+    double majXmark = aXscale->majMark( i );
+    int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
+    if ( xmark-2 == pnt.x() ) {
+      xCoord = majXmark; 
+      xFound = true;
+      break;
+    }
+  }
+  if ( !xFound ) {
+    for ( i = 0; i < aXscale->minCnt(); i++ ) {
+      double minXmark = aXscale->minMark( i );
+      int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
+      if ( xmark-2 == pnt.x() ) {
+        xCoord = minXmark; 
+        xFound = true;
+        break;
+      }
+    }
+  }  
+  const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
+  for ( i = 0; i < aYscale->majCnt(); i++ ) {
+    double majYmark = aYscale->majMark( i );
+    int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
+    if ( ymark-2 == pnt.y() ) {
+      yCoord = majYmark; 
+      yFound = true;
+      break;
+    }
+  }
+  if ( !yFound ) {
+    for ( i = 0; i < aYscale->minCnt(); i++ ) {
+      double minYmark = aYscale->minMark( i );
+      int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
+      if ( ymark-2 == pnt.y() ) {
+        yCoord = minYmark; 
+        yFound = true;
+        break;
+      }
+    }
+  }  
+
+  QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
+  if ( strX == "-0" )
+    strX = "0";
+  QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
+  if ( strY == "-0" )
+    strY = "0";
+  QString info = "";
+
+  if (mySecondY) {
+    bool yFound2 = false;
+    double yCoord2;
+
+    const QwtScaleDiv* aYscale2 = myPlot->axisScale( QwtPlot::yRight );
+    for ( i = 0; i < aYscale2->majCnt(); i++ ) {
+      double majYmark = aYscale2->majMark( i );
+      int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
+      if ( ymark-2 == pnt.y() ) {
+        yCoord2 = majYmark; 
+        yFound2 = true;
+        break;
+      }
+    }
+    if ( !yFound2 ) {
+      for ( i = 0; i < aYscale2->minCnt(); i++ ) {
+        double minYmark = aYscale2->minMark( i );
+        int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
+        if ( ymark-2 == pnt.y() ) {
+          yCoord2 = minYmark; 
+          yFound2 = true;
+          break;
+        }
+      }
+    }
+    QString strY2 = QString::number( yFound2 ? yCoord2 : 
+                      myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).stripWhiteSpace();
+    if ( strY2 == "-0" )
+    strY2 = "0";
+    info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
+  }
+  else
+    info = tr("INF_COORDINATES").arg( strX ).arg( strY );
+
+  return info;
+}
+
+/*!
+  Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
+*/
+static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
+{
+  QwtSymbol::Style ms = QwtSymbol::None;  
+  switch ( m ) {
+  case Plot2d_Curve::Circle:
+    ms = QwtSymbol::Ellipse;   break;
+  case Plot2d_Curve::Rectangle:
+    ms = QwtSymbol::Rect;      break;
+  case Plot2d_Curve::Diamond:
+    ms = QwtSymbol::Diamond;   break;
+  case Plot2d_Curve::DTriangle:
+    ms = QwtSymbol::DTriangle; break;
+  case Plot2d_Curve::UTriangle:
+    ms = QwtSymbol::UTriangle; break;
+  case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
+    ms = QwtSymbol::RTriangle; break;
+  case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
+    ms = QwtSymbol::LTriangle; break;
+  case Plot2d_Curve::Cross:
+    ms = QwtSymbol::Cross;     break;
+  case Plot2d_Curve::XCross:
+    ms = QwtSymbol::XCross;    break;
+  case Plot2d_Curve::None:
+  default:
+    ms = QwtSymbol::None;      break;
+  }
+  return ms;
+}
+
+/*!
+  Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
+*/
+static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
+{
+  Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;  
+  switch ( m ) {
+  case QwtSymbol::Ellipse:
+    ms = Plot2d_Curve::Circle;    break;
+  case QwtSymbol::Rect:
+    ms = Plot2d_Curve::Rectangle; break;
+  case QwtSymbol::Diamond:
+    ms = Plot2d_Curve::Diamond;   break;
+  case QwtSymbol::DTriangle:
+    ms = Plot2d_Curve::DTriangle; break;
+  case QwtSymbol::UTriangle:
+    ms = Plot2d_Curve::UTriangle; break;
+  case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
+    ms = Plot2d_Curve::LTriangle; break;
+  case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
+    ms = Plot2d_Curve::RTriangle; break;
+  case QwtSymbol::Cross:
+    ms = Plot2d_Curve::Cross;     break;
+  case QwtSymbol::XCross:
+    ms = Plot2d_Curve::XCross;    break;
+  case QwtSymbol::None:
+  default:
+    ms = Plot2d_Curve::None;      break;
+  }
+  return ms;
+}
+
+/*!
+  Converts Plot2d_Curve's line style to Qwt line style [ static ]
+*/
+static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
+{
+  Qt::PenStyle ps = Qt::NoPen;
+  switch ( p ) {
+  case Plot2d_Curve::Solid:
+    ps = Qt::SolidLine;      break;
+  case Plot2d_Curve::Dash:
+    ps = Qt::DashLine;       break;
+  case Plot2d_Curve::Dot:
+    ps = Qt::DotLine;        break;
+  case Plot2d_Curve::DashDot:
+    ps = Qt::DashDotLine;    break;
+  case Plot2d_Curve::DashDotDot:
+    ps = Qt::DashDotDotLine; break;
+  case Plot2d_Curve::NoPen:
+  default:
+    ps = Qt::NoPen;          break;
+  }
+  return ps;
+}
+
+/*!
+  Converts Qwt line style to Plot2d_Curve's line style [ static ]
+*/
+static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
+{
+  Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
+  switch ( p ) {
+  case Qt::SolidLine:
+    ps = Plot2d_Curve::Solid;      break;
+  case Qt::DashLine:
+    ps = Plot2d_Curve::Dash;       break;
+  case Qt::DotLine:
+    ps = Plot2d_Curve::Dot;        break;
+  case Qt::DashDotLine:
+    ps = Plot2d_Curve::DashDot;    break;
+  case Qt::DashDotDotLine:
+    ps = Plot2d_Curve::DashDotDot; break;
+  case Qt::NoPen:
+  default:
+    ps = Plot2d_Curve::NoPen;      break;
+  }
+  return ps;
+}
+
+/*!
+  Adds curve into view
+*/
+void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
+{
+  if ( !curve )
+    return;
+  // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
+  // it crashes if switched to X/Y logarithmic mode, when one or more points have
+  // non-positive X/Y coordinate
+  if ( myXMode && curve->getMinX() <= 0. )
+    setHorScaleMode( 0, false );
+  if ( myYMode && curve->getMinY() <= 0. )
+    setVerScaleMode( 0, false );
+
+
+  if ( hasCurve( curve ) ) {
+    updateCurve( curve, update );
+  }
+  else {
+    long curveKey = myPlot->insertCurve( curve->getVerTitle() );
+    myPlot->setCurveYAxis(curveKey, curve->getYAxis());
+
+    myCurves.insert( curveKey, curve );
+    if ( curve->isAutoAssign() ) {
+      QwtSymbol::Style typeMarker;
+      QColor           color;
+      Qt::PenStyle     typeLine;
+      myPlot->getNextMarker( typeMarker, color, typeLine );
+      myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
+      myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker, 
+               QBrush( color ), 
+               QPen( color ), 
+               QSize( myMarkerSize, myMarkerSize ) ) );
+      curve->setColor( color );
+      curve->setLine( qwt2plotLine( typeLine ) );
+      curve->setMarker( qwt2plotMarker( typeMarker ) );
+    }
+    else {
+      Qt::PenStyle     ps = plot2qwtLine( curve->getLine() );
+      QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
+      myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
+      myPlot->setCurveSymbol( curveKey, QwtSymbol( ms, 
+               QBrush( curve->getColor() ), 
+               QPen( curve->getColor() ), 
+               QSize( myMarkerSize, myMarkerSize ) ) );
+    }
+    if ( myCurveType == 0 )
+      myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
+    else if ( myCurveType == 1 )
+      myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
+    else if ( myCurveType == 2 )
+      myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
+    myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
+  }
+  updateTitles();
+  if ( update )
+    myPlot->replot();
+}
+
+/*!
+  Adds curves into view
+*/
+void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
+{
+  myPlot->setUpdatesEnabled( false );
+  QPtrListIterator<Plot2d_Curve> it(curves);
+  Plot2d_Curve* aCurve;
+  while( (aCurve = it.current()) ) {
+    displayCurve( aCurve, false );
+    ++it;
+  }
+
+  fitAll();
+  myPlot->setUpdatesEnabled( true );
+  if ( update )
+    myPlot->replot();
+}
+
+/*!
+  Erases curve
+*/
+void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
+{
+  if ( !curve )
+    return;
+  int curveKey = hasCurve( curve );
+  if ( curveKey ) {
+    myPlot->removeCurve( curveKey );
+    myCurves.remove( curveKey );
+    updateTitles();
+    if ( update )
+      myPlot->replot();
+  }
+}
+
+/*!
+  Erases curves
+*/
+void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
+{
+  QPtrListIterator<Plot2d_Curve> it(curves);
+  Plot2d_Curve* aCurve;
+  while( (aCurve = it.current()) ) {
+    eraseCurve( aCurve, false );
+    ++it;
+  }
+//  fitAll();
+  if ( update )
+    myPlot->replot();
+}
+
+/*!
+  Updates curves attributes
+*/
+void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
+{
+  if ( !curve )
+    return;
+  int curveKey = hasCurve( curve );
+  if ( curveKey ) {
+    if ( !curve->isAutoAssign() ) {
+      Qt::PenStyle     ps = plot2qwtLine( curve->getLine() );
+      QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
+      myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
+      myPlot->setCurveSymbol( curveKey, QwtSymbol( ms, 
+               QBrush( curve->getColor() ), 
+               QPen( curve->getColor() ), 
+               QSize( myMarkerSize, myMarkerSize ) ) );
+      myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
+    }
+    myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
+    myPlot->curve( curveKey )->setEnabled( true );
+    if ( update )
+      myPlot->replot();
+  }
+}
+
+/*!
+  Returns curve key if is is displayed in the viewer and 0 otherwise
+*/
+int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
+{
+  QIntDictIterator<Plot2d_Curve> it( myCurves );
+  for ( ; it.current(); ++it ) {
+    if ( it.current() == curve )
+      return it.currentKey();
+  }
+  return 0;
+}
+
+/*!
+  Gets lsit of displayed curves
+*/
+int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
+{
+  clist.clear();
+  clist.setAutoDelete( false );
+  QIntDictIterator<Plot2d_Curve> it( myCurves );
+  for ( ; it.current(); ++it ) {
+    clist.append( it.current() );
+  }
+  return clist.count();
+}
+
+/*!
+  Returns true if the curve is visible
+*/
+bool Plot2d_ViewFrame::isVisible( Plot2d_Curve* curve )
+{
+  if(curve) {
+    int key = hasCurve( curve );
+    if ( key )
+      return myPlot->curve( key )->enabled();
+  }
+  return false;
+} 
+
+/*!
+  update legend
+*/
+void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
+{
+  if ( !prs || prs->IsNull() )
+    return;
+  curveList aCurves = prs->getCurves();
+
+  QPtrListIterator<Plot2d_Curve> it(aCurves);
+  Plot2d_Curve* aCurve;
+  while( (aCurve = it.current()) ) {
+    int curveKey = hasCurve( aCurve );
+    if ( curveKey )
+      myPlot->setCurveTitle( curveKey, aCurve->getVerTitle() );
+    ++it;
+  }
+}
+
+/*!
+  Fits the view to see all data
+*/
+void Plot2d_ViewFrame::fitAll()
+{
+  QwtDiMap xMap1 = myPlot->canvasMap( QwtPlot::xBottom );
+
+  myPlot->setAxisAutoScale( QwtPlot::yLeft );
+  myPlot->setAxisAutoScale( QwtPlot::xBottom );
+  myPlot->replot();
+
+  // for existing grid
+  QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
+  QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
+
+  myPlot->setAxisScale( QwtPlot::xBottom, 
+      myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ), 
+      myPlot->invTransform( QwtPlot::xBottom, xMap.i2() ) );
+  myPlot->setAxisScale( QwtPlot::yLeft, 
+      myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
+      myPlot->invTransform( QwtPlot::yLeft, yMap.i2() ) );
+
+  if (mySecondY) {
+    myPlot->setAxisAutoScale( QwtPlot::yRight );
+    myPlot->replot();
+    QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
+    myPlot->setAxisScale( QwtPlot::yRight, 
+        myPlot->invTransform( QwtPlot::yRight, yMap2.i1() ), 
+        myPlot->invTransform( QwtPlot::yRight, yMap2.i2() ) );
+  }
+  myPlot->replot();
+}
+
+/*!
+  Fits the view to rectangle area (pixels)
+*/
+void Plot2d_ViewFrame::fitArea( const QRect& area )
+{
+  QRect rect = area.normalize();
+  if ( rect.width() < MIN_RECT_SIZE ) {
+    rect.setWidth( MIN_RECT_SIZE );
+    rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
+  }
+  if ( rect.height() < MIN_RECT_SIZE ) {
+    rect.setHeight( MIN_RECT_SIZE );
+    rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
+  }
+  myPlot->setAxisScale( QwtPlot::yLeft, 
+            myPlot->invTransform( QwtPlot::yLeft, rect.top() ), 
+            myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
+  if (mySecondY)
+    myPlot->setAxisScale( QwtPlot::yRight, 
+            myPlot->invTransform( QwtPlot::yRight, rect.top() ), 
+            myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
+  myPlot->setAxisScale( QwtPlot::xBottom, 
+            myPlot->invTransform( QwtPlot::xBottom, rect.left() ), 
+            myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
+  myPlot->replot();
+}
+
+/*!
+  "Fit Data" command for TUI interface
+*/
+void Plot2d_ViewFrame::fitData(const int mode,
+                              const double xMin, const double xMax,
+                              const double yMin, const double yMax,
+                              double y2Min, double y2Max)
+{
+  if ( mode == 0 || mode == 2 ) {
+    myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
+    if (mySecondY)
+      myPlot->setAxisScale( QwtPlot::yRight, y2Max, y2Min );
+  }
+  if ( mode == 0 || mode == 1 ) 
+    myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax ); 
+  myPlot->replot();
+}
+
+/*!
+  Gets current fit ranges for view frame
+*/
+void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
+                                   double& yMin, double& yMax,
+                                   double& y2Min, double& y2Max)
+{
+  int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
+  int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
+  int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
+  int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
+  xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
+  xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
+  yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
+  yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
+  y2Min = 0;
+  y2Max = 0;
+  if (mySecondY) {
+    int iyMin = myPlot->canvasMap( QwtPlot::yRight ).i1();
+    int iyMax = myPlot->canvasMap( QwtPlot::yRight ).i2();
+    y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
+    y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
+  }
+}
+
+/*!
+  Tests if it is necessary to start operation on mouse action
+*/
+int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
+{
+  int btn = me.button() | me.state();
+  const int zoomBtn = ControlButton | LeftButton;
+  const int panBtn  = ControlButton | MidButton;
+  const int fitBtn  = ControlButton | RightButton;
+
+  switch (btn)
+  {
+  case zoomBtn:
+    {
+      QPixmap zoomPixmap (imageZoomCursor);
+      QCursor zoomCursor (zoomPixmap);
+      myPlot->canvas()->setCursor( zoomCursor );
+      return ZoomId;
+    }
+  case panBtn:
+    myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
+    return PanId;
+  case fitBtn:
+    myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
+    return FitAreaId;
+  default :
+    return NoOpId;
+  }
+}
+
+/*!
+  "Settings" toolbar action slot
+*/
+void Plot2d_ViewFrame::onSettings()
+{
+#ifdef TEST_AUTOASSIGN
+  typedef QMap<int,int> IList;
+  typedef QMap<QString,int> SList;
+  IList mars, lins;
+  SList cols;
+  cols[ "red-min" ]   = 1000;
+  cols[ "red-max" ]   = -1;
+  cols[ "green-min" ] = 1000;
+  cols[ "green-max" ] = -1;
+  cols[ "blue-min" ]  = 1000;
+  cols[ "blue-max" ]  = -1;
+  for ( unsigned i = 0; i < 10000; i++ ) {
+    QwtSymbol::Style typeMarker;
+    QColor           color;
+    Qt::PenStyle     typeLine;
+    myPlot->getNextMarker( typeMarker, color, typeLine );
+    if ( mars.contains(typeMarker) )
+      mars[ typeMarker ] = mars[ typeMarker ]+1;
+    else
+      mars[ typeMarker ] = 0;
+    if ( lins.contains(typeLine) )
+      lins[ typeLine ] = lins[ typeLine ]+1;
+    else
+      lins[ typeLine ] = 0;
+    if ( cols[ "red-max" ] < color.red() )
+      cols[ "red-max" ] = color.red();
+    if ( cols[ "red-min" ] > color.red() )
+      cols[ "red-min" ] = color.red();
+    if ( cols[ "green-max" ] < color.green() )
+      cols[ "green-max" ] = color.green();
+    if ( cols[ "green-min" ] > color.green() )
+      cols[ "green-min" ] = color.green();
+    if ( cols[ "blue-max" ] < color.blue() )
+      cols[ "blue-max" ] = color.blue();
+    if ( cols[ "blue-min" ] > color.blue() )
+      cols[ "blue-min" ] = color.blue();
+  }
+#endif
+  
+  Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
+  dlg->setMainTitle( myTitleEnabled, myTitle );
+  dlg->setXTitle( myXTitleEnabled, myXTitle );
+  dlg->setYTitle( myYTitleEnabled, myYTitle );
+  if (mySecondY)
+    dlg->setY2Title( myY2TitleEnabled, myY2Title );
+  dlg->setCurveType( myCurveType );
+  dlg->setLegend( myShowLegend, myLegendPos );
+  dlg->setMarkerSize( myMarkerSize );
+  dlg->setBackgroundColor( myBackground );
+  dlg->setScaleMode(myXMode, myYMode);
+  //
+  dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
+         myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
+         myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
+  dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
+         myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
+         myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
+  if ( dlg->exec() == QDialog::Accepted ) {
+    // horizontal axis title
+    setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
+    // vertical left axis title
+    setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
+    if (mySecondY) // vertical right axis title
+      setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
+
+    // main title
+    setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
+    // curve type
+    if ( myCurveType != dlg->getCurveType() ) {
+      setCurveType( dlg->getCurveType(), false );
+    }
+    // legend
+    if ( myShowLegend != dlg->isLegendEnabled() ) {
+      showLegend( dlg->isLegendEnabled(), false );
+    }
+    if ( myLegendPos != dlg->getLegendPos() ) {
+      setLegendPos( dlg->getLegendPos() );
+    }
+    // marker size
+    if ( myMarkerSize != dlg->getMarkerSize() ) {
+      setMarkerSize( dlg->getMarkerSize(), false );
+    }
+    // background color
+    if ( myBackground != dlg->getBackgroundColor() ) {
+      setBackgroundColor( dlg->getBackgroundColor() );
+    }
+    // grid
+    bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
+         aY2GridMajorEnabled, aY2GridMinorEnabled;
+    int  aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
+         aY2GridMaxMajor, aY2GridMaxMinor;
+    dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
+                       aY2GridMajorEnabled, aY2GridMaxMajor);
+    dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
+                       aY2GridMinorEnabled, aY2GridMaxMinor);
+    setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
+    setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
+              aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
+    if ( myXMode != dlg->getXScaleMode() ) {
+      setHorScaleMode( dlg->getXScaleMode() );
+    }
+    if ( myYMode != dlg->getYScaleMode() ) {
+      setVerScaleMode( dlg->getYScaleMode() );
+    }
+    // update view
+    myPlot->replot();
+    // update preferences
+    if ( dlg->isSetAsDefault() ) 
+      writePreferences();
+  }
+  delete dlg;
+}
+
+/*!
+  "Fit Data" command slot
+*/
+void Plot2d_ViewFrame::onFitData()
+{
+  Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
+  double xMin,xMax,yMin,yMax,y2Min,y2Max;
+  getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
+  
+  dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
+  if ( dlg->exec() == QDialog::Accepted ) {
+    int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
+    fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
+  }
+  delete dlg;
+}
+
+/*!
+  Change background color
+*/
+void Plot2d_ViewFrame::onChangeBackground()
+{
+  QColor selColor = QColorDialog::getColor ( backgroundColor(), this );        
+  if ( selColor.isValid() ) {
+    setBackgroundColor( selColor );
+  }
+}
+
+/*!
+  Sets curve type
+*/
+void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
+{
+  myCurveType = curveType;
+  QArray<long> keys = myPlot->curveKeys();
+  for ( int i = 0; i < (int)keys.count(); i++ ) {
+    if ( myCurveType == 0 )
+      myPlot->setCurveStyle( keys[i], QwtCurve::Dots );//QwtCurve::NoCurve
+    else if ( myCurveType == 1 )
+      myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
+    else if ( myCurveType == 2 )
+      myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
+  }
+  if ( update )
+    myPlot->replot();
+  emit vpCurveChanged();
+}
+
+void Plot2d_ViewFrame::setCurveTitle( int curveKey, const QString& title ) 
+{ 
+  if(myPlot) myPlot->setCurveTitle(curveKey, title); 
+}   
+
+/*!
+  Shows/hides legend
+*/
+void Plot2d_ViewFrame::showLegend( bool show, bool update )
+{
+  myShowLegend = show;
+  myPlot->setAutoLegend( myShowLegend );
+  myPlot->enableLegend( myShowLegend );
+  if ( update )
+    myPlot->replot();
+}
+
+/*!
+  Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
+*/
+void Plot2d_ViewFrame::setLegendPos( int pos )
+{
+  myLegendPos = pos;
+  switch( pos ) {
+  case 0:
+    myPlot->setLegendPos( Qwt::Left );
+    break;
+  case 1:
+    myPlot->setLegendPos( Qwt::Right );
+    break;
+  case 2:
+    myPlot->setLegendPos( Qwt::Top );
+    break;
+  case 3:
+    myPlot->setLegendPos( Qwt::Bottom );
+    break;
+  }
+}
+
+/*!
+  Sets new marker size
+*/
+void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
+{
+  if ( myMarkerSize != size )
+  {
+    myMarkerSize = size;
+    QArray<long> keys = myPlot->curveKeys();
+    for ( int i = 0; i < (int)keys.count(); i++ )
+    {
+      QwtPlotCurve* crv = myPlot->curve( keys[i] );
+      if ( crv )
+      {
+        QwtSymbol aSymbol = crv->symbol();
+        aSymbol.setSize( myMarkerSize, myMarkerSize );
+        myPlot->setCurveSymbol( keys[i], aSymbol );
+      }
+    }
+    if ( update )
+      myPlot->replot();
+  }
+}
+
+/*!
+  Sets background color
+*/
+void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
+{
+  myBackground = color;
+  //myPlot->setCanvasBackground( myBackground );
+  myPlot->canvas()->setPalette( myBackground );
+  myPlot->setPalette( myBackground );
+  QPalette aPal = myPlot->getLegend()->palette();
+  for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
+    QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
+    aPal.setColor( cg, QColorGroup::Base, myBackground );
+    aPal.setColor( cg, QColorGroup::Background, myBackground );
+  }
+  myPlot->getLegend()->setPalette( aPal );
+  Repaint();
+}
+/*!
+  Gets background color
+*/
+QColor Plot2d_ViewFrame::backgroundColor() const
+{
+  return myBackground;
+}
+/*!
+  Sets hor.axis grid parameters
+*/
+void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax, 
+         bool xMinorEnabled, const int xMinorMax, 
+         bool update )
+{
+  myXGridMajorEnabled = xMajorEnabled;
+  myXGridMinorEnabled = xMinorEnabled;
+  myXGridMaxMajor = xMajorMax;
+  myXGridMaxMinor = xMinorMax;
+  myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
+  myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
+  myPlot->setGridXAxis(QwtPlot::xBottom);
+  myPlot->enableGridX( myXGridMajorEnabled );
+  myPlot->enableGridXMin( myXGridMinorEnabled );
+  if ( update )
+    myPlot->replot();
+}
+/*!
+  Sets ver.axis grid parameters
+*/
+void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax, 
+                                 bool yMinorEnabled, const int yMinorMax,
+                                 bool y2MajorEnabled, const int y2MajorMax, 
+                                 bool y2MinorEnabled, const int y2MinorMax, 
+                                 bool update )
+{
+  myYGridMajorEnabled = yMajorEnabled;
+  myYGridMinorEnabled = yMinorEnabled;
+  myYGridMaxMajor = yMajorMax;
+  myYGridMaxMinor = yMinorMax;
+
+  if (mySecondY) {
+    myY2GridMajorEnabled = y2MajorEnabled;
+    myY2GridMinorEnabled = y2MinorEnabled;
+    myY2GridMaxMajor = y2MajorMax;
+    myY2GridMaxMinor = y2MinorMax;
+  }
+  myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
+  myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
+
+  if (mySecondY) {
+    myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
+    myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
+  }
+
+  myPlot->setGridYAxis(QwtPlot::yLeft);
+
+  if (mySecondY) {
+    if (myYGridMajorEnabled) {
+      myPlot->enableGridYMin(myYGridMinorEnabled);
+      myPlot->enableGridY( myYGridMajorEnabled);
+    }
+    else if (myY2GridMajorEnabled) {
+      myPlot->setGridYAxis(QwtPlot::yRight);
+      myPlot->enableGridYMin(myY2GridMinorEnabled);
+      myPlot->enableGridY(myY2GridMajorEnabled);
+    }
+    else {
+      myPlot->enableGridYMin(false);
+      myPlot->enableGridY(false);
+    }
+  }
+  else {
+    myPlot->enableGridY( myYGridMajorEnabled );
+    myPlot->enableGridYMin( myYGridMinorEnabled );
+  }
+  if ( update )
+    myPlot->replot();
+}
+
+/*!
+  Sets title for some axis
+*/
+void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
+                                 ObjectType type, bool update )
+{
+  switch (type) {
+    case MainTitle:
+      myTitleEnabled = enabled;
+      myTitle = title;
+      myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
+      break;
+    case XTitle:
+      myXTitleEnabled = enabled;
+      myXTitle = title;
+      myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
+      break;
+    case YTitle:
+      myYTitleEnabled = enabled;
+      myYTitle = title;
+      myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
+      break;
+    case Y2Title:
+      myY2TitleEnabled = enabled;
+      myY2Title = title;
+      myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString::null );
+      break;
+  }
+  if ( update )
+    myPlot->replot();
+}
+/*!
+  Sets title for some axis
+*/
+QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
+{
+  QString title = "";
+  switch (type) {
+    case MainTitle:
+      title = myTitle;   break;
+    case XTitle:
+      title = myXTitle;  break;
+    case YTitle:
+      title = myYTitle;  break;
+    case Y2Title:
+      title = myY2Title; break;
+  }
+  return title;
+}
+/*!
+  Sets font for Plot2d object : title or axis
+*/
+void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
+{
+  switch (type) {
+    case MainTitle:
+      myPlot->setTitleFont(font);
+      break;
+    case XTitle:
+      myPlot->setAxisTitleFont(QwtPlot::xBottom, font); break;
+    case YTitle:
+      myPlot->setAxisTitleFont(QwtPlot::yLeft, font);   break;
+    case Y2Title:
+      myPlot->setAxisTitleFont(QwtPlot::yRight, font);  break;
+    case XAxis:
+      myPlot->setAxisFont(QwtPlot::xBottom, font);      break;
+    case YAxis:
+      myPlot->setAxisFont(QwtPlot::yLeft, font);        break;
+    case Y2Axis:
+      myPlot->setAxisFont(QwtPlot::yRight, font);       break;
+  }
+  if ( update )
+    myPlot->replot();
+}
+/*!
+  Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
+*/
+void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
+{
+  // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
+  // it crashes if switched to X/Y logarithmic mode, when one or more points have
+  // non-positive X/Y coordinate
+  if ( mode && !isXLogEnabled() ){
+    SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"), tr("BUT_OK"));
+    return;
+  }
+
+  myXMode = mode;
+  if ( myXMode == 0 ) // linear
+    myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
+  else                // logarithmic
+    myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
+
+  if ( update )
+    fitAll();
+  emit vpModeHorChanged();
+}
+/*!
+  Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
+*/
+void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
+{
+  // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
+  // it crashes if switched to X/Y logarithmic mode, when one or more points have
+  // non-positive X/Y coordinate
+  if ( mode && !isYLogEnabled() ){
+    SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"), tr("BUT_OK"));
+    return;
+  }
+
+  myYMode = mode;
+  if ( myYMode == 0 ) { // linear
+    myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
+    if (mySecondY)
+      myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
+  }
+  else {               // logarithmic
+    myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
+    if (mySecondY)
+      myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, true );
+  }
+  if ( update )
+    fitAll();
+  emit vpModeVerChanged();
+}
+
+/*!
+  Return, scale mode for horizontal axis
+*/
+bool Plot2d_ViewFrame::isModeHorLinear()
+{
+  return (myXMode == 0 ? true : false);
+}
+
+/*!
+  Return, scale mode for vertical axis
+*/
+bool Plot2d_ViewFrame::isModeVerLinear()
+{
+  return (myYMode == 0 ? true : false);
+}
+/*!
+  Slot, called when user presses mouse button
+*/
+void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
+{
+  Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
+   if (aParent)
+     aParent->putInfo(getInfo(me.pos()));
+  if ( myOperation == NoOpId )
+    myOperation = testOperation( me );
+  if ( myOperation != NoOpId ) {
+    myPnt = me.pos();
+    if ( myOperation == FitAreaId ) {
+      myPlot->setOutlineStyle( Qwt::Rect );
+    }
+    else if ( myOperation == GlPanId ) {
+      myPlot->setAxisScale( QwtPlot::yLeft,
+          myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2, 
+          myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
+      myPlot->setAxisScale( QwtPlot::xBottom, 
+          myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2, 
+          myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
+      if (mySecondY)
+        myPlot->setAxisScale( QwtPlot::yRight,
+          myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2, 
+          myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
+      myPlot->replot();
+    }
+  }
+  else {
+    int btn = me.button() | me.state();
+    if (btn == RightButton) {
+      QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
+                                            me.pos(), btn, me.state());
+      // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
+      parent()->eventFilter(this, aEvent);
+    }
+  }
+}
+/*!
+  Slot, called when user moves mouse
+*/
+void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
+{
+  int    dx = me.pos().x() - myPnt.x();
+  int    dy = me.pos().y() - myPnt.y();
+
+  if ( myOperation != NoOpId) {
+    if ( myOperation == ZoomId ) {
+      QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
+      QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
+
+      myPlot->setAxisScale( QwtPlot::yLeft, 
+          myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
+          myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
+      myPlot->setAxisScale( QwtPlot::xBottom, 
+          myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ), 
+          myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
+      if (mySecondY) {
+        QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
+        myPlot->setAxisScale( QwtPlot::yRight, 
+          myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
+          myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
+      }
+      myPlot->replot();
+      myPnt = me.pos();
+    }
+    else if ( myOperation == PanId ) {
+      QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
+      QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
+
+      myPlot->setAxisScale( QwtPlot::yLeft, 
+          myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ), 
+          myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
+      myPlot->setAxisScale( QwtPlot::xBottom, 
+          myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
+          myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) ); 
+      if (mySecondY) {
+        QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
+        myPlot->setAxisScale( QwtPlot::yRight,
+          myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ), 
+          myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
+      }
+      myPlot->replot();
+      myPnt = me.pos();
+    }
+  }
+  else {
+     Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
+     if (aParent)
+       aParent->putInfo(getInfo(me.pos()));
+  }
+}
+/*!
+  Slot, called when user releases mouse
+*/
+void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
+{
+  if ( myOperation == NoOpId && me.button() == RightButton )
+  {
+    QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
+                              me.pos(), me.globalPos(),
+                              me.state() );
+    emit contextMenuRequested( &aEvent );
+  }
+  if ( myOperation == FitAreaId ) {
+    QRect rect( myPnt, me.pos() );
+    fitArea( rect );
+  }
+  myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
+  myPlot->setOutlineStyle( Qwt::Triangle );
+
+  Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
+   if (aParent)
+     aParent->putInfo(tr("INF_READY"));
+  myOperation = NoOpId;
+}
+/*!
+  Slot, called when user wheeling mouse
+*/
+void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
+{ 
+  double aDelta = event->delta();
+  double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
+
+  QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
+  QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
+
+  myPlot->setAxisScale( QwtPlot::yLeft,
+    myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
+    myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
+  myPlot->setAxisScale( QwtPlot::xBottom, 
+    myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
+    myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
+  if (mySecondY) {
+    QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
+    myPlot->setAxisScale( QwtPlot::yRight,
+      myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
+      myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
+  }
+  myPlot->replot();
+  myPnt = event->pos();
+}
+/*!
+  View operations : Pan view
+*/
+void Plot2d_ViewFrame::onViewPan()
+{ 
+  QCursor panCursor (Qt::SizeAllCursor);
+  myPlot->canvas()->setCursor( panCursor );
+  myOperation = PanId;
+  qApp->installEventFilter( this );
+}
+/*!
+  View operations : Zoom view
+*/
+void Plot2d_ViewFrame::onViewZoom() 
+{
+  QPixmap zoomPixmap (imageZoomCursor);
+  QCursor zoomCursor (zoomPixmap);
+  myPlot->canvas()->setCursor( zoomCursor );
+  myOperation = ZoomId;
+  qApp->installEventFilter( this );
+}
+/*!
+  View operations : Fot All
+*/
+void Plot2d_ViewFrame::onViewFitAll() 
+{ 
+  fitAll();
+}
+/*!
+  View operations : Fit Area
+*/
+void Plot2d_ViewFrame::onViewFitArea() 
+{
+  myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
+  myOperation = FitAreaId;
+  qApp->installEventFilter( this );
+}
+/*!
+  View operations : Global panning
+*/
+void Plot2d_ViewFrame::onViewGlobalPan() 
+{
+  QPixmap globalPanPixmap (imageCrossCursor);
+  QCursor glPanCursor (globalPanPixmap);
+  myPlot->canvas()->setCursor( glPanCursor );
+  myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
+  myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
+  if (mySecondY)
+    myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
+  myPlot->replot();
+  QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
+  QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
+
+  myXDistance = xMap.d2() - xMap.d1();
+  myYDistance = yMap.d2() - yMap.d1();
+
+  if (mySecondY) {
+    QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
+    myYDistance2 = yMap2.d2() - yMap2.d1();
+  }
+  fitAll();
+  myOperation = GlPanId;
+  qApp->installEventFilter( this );
+}
+
+/*!
+  Precaution for logarithmic X scale
+*/
+bool Plot2d_ViewFrame::isXLogEnabled() const
+{
+  bool allPositive = true;
+  QIntDictIterator<Plot2d_Curve> it( myCurves );
+  for ( ; allPositive && it.current(); ++it ) {
+    allPositive = ( it.current()->getMinX() > 0. );
+  }
+  return allPositive;
+}
+
+/*!
+  Precaution for logarithmic Y scale
+*/
+bool Plot2d_ViewFrame::isYLogEnabled() const
+{
+  bool allPositive = true;
+  QIntDictIterator<Plot2d_Curve> it( myCurves );
+  for ( ; allPositive && it.current(); ++it ) {
+    allPositive = ( it.current()->getMinY() > 0. );
+  }
+  return allPositive;
+}
+
+//=================================================================================
+// Plot2d_Plot2d implementation
+//=================================================================================
+/*!
+  Constructor
+*/
+Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
+     : QwtPlot( parent )
+{
+  // outline
+  enableOutline( true );
+  setOutlineStyle( Qwt::Triangle );
+  setOutlinePen( green );
+  // legend
+  setAutoLegend( false );
+  setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
+  enableLegend( false );
+  // grid
+  enableGridX( false );
+  enableGridXMin( false );
+  enableGridY( false );
+  enableGridYMin( false );
+  // auto scaling by default
+  setAxisAutoScale( QwtPlot::yLeft );
+  setAxisAutoScale( QwtPlot::yRight );
+  setAxisAutoScale( QwtPlot::xBottom );
+}
+/*!
+  Recalculates and redraws Plot 2d view 
+*/
+void Plot2d_Plot2d::replot()
+{
+  updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
+  QwtPlot::replot(); 
+}
+
+/*!
+  Checks if two colors are close to each other [ static ]
+  uses COLOR_DISTANCE variable as max tolerance for comparing of colors
+*/
+const long COLOR_DISTANCE = 100;
+const int  MAX_ATTEMPTS   = 10;
+static bool closeColors( const QColor& color1, const QColor& color2 )
+{
+  long tol = abs( color2.red()   - color1.red() ) + 
+             abs( color2.green() - color1.green() ) +
+       abs( color2.blue()  - color1.blue() );
+
+  return ( tol <= COLOR_DISTANCE );
+}
+/*!
+  Gets new unique marker for item if possible
+*/
+void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine ) 
+{
+  bool bOk = false;
+  int cnt = 1;
+  while ( !bOk ) {
+    int aRed    = (int)( 256.0 * rand() / RAND_MAX);    // generate random color
+    int aGreen  = (int)( 256.0 * rand() / RAND_MAX);    // ...
+    int aBlue   = (int)( 256.0 * rand() / RAND_MAX);    // ...
+    int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1;  // 9 markers types ( not including empty )
+    int aLine   = (int)( 5.0 * rand() / RAND_MAX) + 1;  // 5 line types ( not including empty )
+
+    typeMarker = ( QwtSymbol::Style )aMarker;
+    color      = QColor( aRed, aGreen, aBlue );
+    typeLine   = ( Qt::PenStyle )aLine;
+
+    cnt++;
+    if ( cnt == MAX_ATTEMPTS )
+      bOk = true;
+    else
+      bOk = !existMarker( typeMarker, color, typeLine );
+  }
+/*
+  static int aMarker = -1;
+  static int aColor  = -1;
+  static int aLine   = -1;
+
+  if ( myColors.isEmpty() ) {
+    // creating colors list
+    myColors.append( Qt::white );
+    myColors.append( Qt::blue );
+    myColors.append( Qt::gray );
+    myColors.append( Qt::darkGreen );
+    myColors.append( Qt::magenta );
+    myColors.append( Qt::darkGray );
+    myColors.append( Qt::red );
+    myColors.append( Qt::darkBlue );
+    myColors.append( Qt::darkYellow );
+    myColors.append( Qt::cyan );
+    myColors.append( Qt::darkRed );
+    myColors.append( Qt::darkCyan );
+    myColors.append( Qt::yellow );
+    myColors.append( Qt::darkMagenta );
+    myColors.append( Qt::green );
+    myColors.append( Qt::black );
+  }
+
+  int nbMarkers = 11;                   // QwtSymbol supports 11 marker types
+  int nbLines   = 6;                    // Qt supports 6 line types
+  int nbColors  = myColors.count();     // number of default colors supported
+
+  aMarker = ( aMarker + 1 ) % nbMarkers;  
+  if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
+  aColor  = ( aColor  + 1 ) % nbColors;
+  aLine   = ( aLine   + 1 ) % nbLines;    
+  if ( aLine == Qt::NoPen ) aLine++;             
+
+  typeMarker = ( QwtSymbol::Style )aMarker;
+  color      = myColors[ aColor ];
+  typeLine   = ( Qt::PenStyle )aLine;
+  if ( !existMarker( typeMarker, color, typeLine ) )
+    return;
+
+  int i, j, k;
+  for ( i = 0; i < nbMarkers; i++ ) {
+    aMarker = ( aMarker + 1 ) % nbMarkers;
+    if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
+    for ( j = 0; j < nbColors; j++ ) {
+      aColor  = ( aColor  + 1 ) % nbColors;
+      for ( k = 0; k < nbLines; k++ ) {
+        aLine = ( aLine + 1 ) % nbLines;
+  if ( aLine == Qt::NoPen ) aLine++;             
+        if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
+          typeMarker = ( QwtSymbol::Style )aMarker;
+          color      = myColors[ aColor ];
+          typeLine   = ( Qt::PenStyle )aLine;
+          return;
+        }
+      }
+    }
+  }
+*/
+}
+
+QSizePolicy Plot2d_Plot2d::sizePolicy() const
+{
+  return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
+}
+
+QSize Plot2d_Plot2d::sizeHint() const
+{
+  return QwtPlot::minimumSizeHint();
+}
+
+/*!
+  return minimum size for qwt plot
+*/
+QSize Plot2d_Plot2d::minimumSizeHint() const
+{
+  return QSize( 0, 0 );
+//  QSize aSize = QwtPlot::minimumSizeHint();
+//  return QSize(aSize.width()*3/4, aSize.height());
+}
+/*!
+  Checks if marker belongs to any enitity
+*/
+bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine ) 
+{
+  // getting all curves
+  QArray<long> keys = curveKeys();
+  //QColor aRgbColor;
+
+  if ( closeColors( color, backgroundColor() ) )
+      return true;
+  for ( int i = 0; i < (int)keys.count(); i++ )
+  {
+    QwtPlotCurve* crv = curve( keys[i] );
+    if ( crv ) {
+      QwtSymbol::Style aStyle = crv->symbol().style();
+      QColor           aColor = crv->pen().color();
+      Qt::PenStyle     aLine  = crv->pen().style();
+//      if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
+      if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
+  return true;
+    }
+  }
+  return false;
+}
+
+// TEMPORARY SOLUTION!!!  TO BE IMPLEMENTED!!!
+Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
+{
+  return 0;
+}
+
+void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
+{
+  if( !vf )
+    return;
+
+  myCurveType = vf->myCurveType;
+  myShowLegend = vf->myShowLegend;
+  myLegendPos = vf->myLegendPos;
+  myMarkerSize = vf->myMarkerSize;
+  myBackground = vf->myBackground;
+  myTitle = vf->myTitle; 
+  myXTitle = vf->myXTitle;
+  myYTitle = vf->myYTitle;
+  myY2Title = vf->myY2Title;
+  myTitleEnabled = vf->myTitleEnabled;
+  myXTitleEnabled = vf->myXTitleEnabled;
+  myYTitleEnabled = vf->myYTitleEnabled;
+  myY2TitleEnabled = vf->myY2TitleEnabled;
+  myXGridMajorEnabled = vf->myXGridMajorEnabled;
+  myYGridMajorEnabled = vf->myYGridMajorEnabled;
+  myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
+  myXGridMinorEnabled = vf->myXGridMinorEnabled;
+  myYGridMinorEnabled = vf->myYGridMinorEnabled;
+  myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
+  myXGridMaxMajor = vf->myXGridMaxMajor;
+  myYGridMaxMajor = vf->myYGridMaxMajor;
+  myY2GridMaxMajor = vf->myY2GridMaxMajor;
+  myXGridMaxMinor = vf->myXGridMaxMinor;
+  myYGridMaxMinor = vf->myYGridMaxMinor;
+  myY2GridMaxMinor = vf->myY2GridMaxMinor;
+  myXMode = vf->myXMode;
+  myYMode = vf->myYMode;
+  mySecondY = vf->mySecondY;
+}
+
+/*!
+  Updates titles according to curves
+*/
+#define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
+void Plot2d_ViewFrame::updateTitles() 
+{
+  QIntDictIterator<Plot2d_Curve> it( myCurves );
+  QStringList aXTitles;
+  QStringList aYTitles;
+  QStringList aXUnits;
+  QStringList aYUnits;
+  QStringList aTables;
+  int i = 0;
+  while ( it.current() ) {
+    // collect titles and units from all curves...
+    QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
+    QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
+    QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
+    QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
+    
+    aYTitles.append( yTitle );
+    if ( aXTitles.find( xTitle ) == aXTitles.end() )
+      aXTitles.append( xTitle );
+    if ( aXUnits.find( xUnits ) == aXUnits.end() )
+      aXUnits.append( xUnits );
+    if ( aYUnits.find( yUnits ) == aYUnits.end() )
+      aYUnits.append( yUnits );
+
+    QString aName = it.current()->getTableTitle();
+    if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
+      aTables.append( aName );
+
+    ++it;
+    ++i;
+  }
+  // ... and update plot 2d view
+  QString xUnits, yUnits;
+  if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
+    xUnits = BRACKETIZE( aXUnits[0] );
+  if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
+    yUnits = BRACKETIZE( aYUnits[0] );
+  QString xTitle, yTitle;
+  if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
+    xTitle = aXTitles[0];
+  if ( aYTitles.count() == 1 )
+    yTitle = aYTitles[0];
+
+  if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
+    xTitle += " ";
+  if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
+    yTitle += " ";
+
+  setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
+  setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
+  setTitle( true, aTables.join("; "), MainTitle, true );
+}
+
+bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
+{
+#ifdef WIN32
+  return false;
+
+#else
+  bool res = false;
+  if( myPlot )
+  {
+    QPaintDevice* pd = 0;
+    if( format=="PS" )
+    {
+      QPrinter* pr = new QPrinter( QPrinter::HighResolution );
+      pr->setPageSize( QPrinter::A4 );
+      pr->setOutputToFile( true );
+      pr->setOutputFileName( file );
+      pr->setPrintProgram( "" );
+      pd = pr;
+    }
+
+    if( pd )
+    {
+      myPlot->print( *pd );
+      res = true;
+      delete pd;
+    }
+  }
+  return res;
+#endif
+}
diff --git a/src/Plot2d/Plot2d_ViewFrame.h b/src/Plot2d/Plot2d_ViewFrame.h
new file mode 100755 (executable)
index 0000000..51faa08
--- /dev/null
@@ -0,0 +1,196 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef PLOT2D_VIEWFRAME_H
+#define PLOT2D_VIEWFRAME_H
+
+#include "Plot2d_Curve.h"
+#include <qwidget.h>
+#include <qintdict.h>
+
+class Plot2d_Plot2d;
+class Plot2d_Prs;
+
+typedef QIntDict<Plot2d_Curve> CurveDict;
+
+class PLOT2D_EXPORT Plot2d_ViewFrame : public QWidget
+{ 
+  Q_OBJECT
+
+  enum { NoOpId, FitAreaId, ZoomId, PanId, GlPanId, DumpId, 
+   ModeXLinearId, ModeXLogarithmicId, ModeYLinearId, ModeYLogarithmicId,
+   LegendId, CurvePointsId, CurveLinesId, CurveSplinesId };
+public:
+  /* Construction/destruction */
+  Plot2d_ViewFrame( QWidget* parent, const QString& title = "" );
+  virtual ~Plot2d_ViewFrame();
+
+  enum ObjectType { MainTitle, XTitle, YTitle, Y2Title, XAxis, YAxis, Y2Axis };
+
+public:
+  QWidget* getViewWidget();
+
+  /* display */
+  void    DisplayAll();
+  void    EraseAll();
+  void    Repaint();
+
+  void    Display( const Plot2d_Prs* );
+  void    Erase( const Plot2d_Prs*, const bool = false );
+  Plot2d_Prs* CreatePrs( const char* entry = 0 );
+
+  /* operations */
+  void    updateTitles();
+  void    setTitle( const QString& title );
+  QString getTitle() const { return myTitle; }
+  void    displayCurve( Plot2d_Curve* curve, bool update = false );
+  void    displayCurves( const curveList& curves, bool update = false );
+  void    eraseCurve( Plot2d_Curve* curve, bool update = false );
+  void    eraseCurves( const curveList& curves, bool update = false );
+  int     getCurves( curveList& clist );
+  const   CurveDict& getCurves() { return myCurves; }
+  int     hasCurve( Plot2d_Curve* curve );
+  bool    isVisible( Plot2d_Curve* curve );
+  void    updateCurve( Plot2d_Curve* curve, bool update = false );
+  void    updateLegend( const Plot2d_Prs* prs );
+  void    fitAll();
+  void    fitArea( const QRect& area );
+  void    fitData(const int mode,
+                 const double xMin, const double xMax,
+                 const double yMin, const double yMax,
+                 const double y2Min = 0, const double y2Max = 0);
+
+  void    getFitRanges(double& xMin, double& xMax,
+                      double& yMin, double& yMax,
+                      double& y2Min, double& y2Max);
+
+  /* view parameters */
+  void    copyPreferences( Plot2d_ViewFrame* );
+  void    setCurveType( int curveType, bool update = true );
+  int     getCurveType() const { return myCurveType; }
+  void    setCurveTitle( int curveKey, const QString& title );
+  void    showLegend( bool show, bool update = true );
+  void    setLegendPos( int pos );
+  int     getLegendPos() const { return myLegendPos; }
+  void    setMarkerSize( const int size, bool update = true  );
+  int     getMarkerSize() const { return myMarkerSize; }
+  void    setBackgroundColor( const QColor& color );
+  QColor  backgroundColor() const;
+  void    setXGrid( bool xMajorEnabled, const int xMajorMax,
+                    bool xMinorEnabled, const int xMinorMax, bool update = true );
+  void    setYGrid( bool yMajorEnabled, const int yMajorMax,
+                    bool yMinorEnabled, const int yMinorMax,
+                    bool y2MajorEnabled, const int y2MajorMax,
+                    bool y2MinorEnabled, const int y2MinorMax, bool update = true );
+  void    setTitle( bool enabled, const QString& title, ObjectType type, bool update = true );
+  QString getTitle( ObjectType type ) const;
+
+  void    setFont( const QFont& font, ObjectType type, bool update = true );
+  void    setHorScaleMode( const int mode, bool update = true );
+  int     getHorScaleMode() const { return myXMode; }
+  void    setVerScaleMode( const int mode, bool update = true );
+  int     getVerScaleMode() const { return myYMode; }
+
+  bool    isModeHorLinear();
+  bool    isModeVerLinear();
+  bool    isLegendShow() { return myShowLegend; };
+
+  // Protection against QwtCurve::drawLines() bug in Qwt 0.4.x: 
+  // it crashes if switched to X/Y logarithmic mode, when one or more points have
+  // non-positive X/Y coordinate
+  bool    isXLogEnabled() const;
+  bool    isYLogEnabled() const;
+
+  virtual bool print( const QString& file, const QString& format ) const;
+
+protected:
+  int     testOperation( const QMouseEvent& );
+  void    readPreferences();
+  void    writePreferences();
+  QString getInfo( const QPoint& pnt );
+  virtual void wheelEvent( QWheelEvent* );
+
+public slots:
+  void    onViewPan(); 
+  void    onViewZoom();
+  void    onViewFitAll();
+  void    onViewFitArea();
+  void    onViewGlobalPan(); 
+  void    onSettings();
+  void    onFitData();
+  void    onChangeBackground();
+
+protected slots:
+  void    plotMousePressed( const QMouseEvent& );
+  void    plotMouseMoved( const QMouseEvent& );
+  void    plotMouseReleased( const QMouseEvent& );
+
+signals:
+  void    vpModeHorChanged();
+  void    vpModeVerChanged();
+  void    vpCurveChanged();
+  void    contextMenuRequested( QContextMenuEvent *e );
+
+protected:
+  Plot2d_Plot2d* myPlot;
+  int            myOperation;
+  QPoint         myPnt;
+  CurveDict      myCurves;
+
+  int            myCurveType;
+  bool           myShowLegend;
+  int            myLegendPos;
+  int            myMarkerSize;
+  QColor         myBackground;
+  QString        myTitle, myXTitle, myYTitle, myY2Title;
+  bool           myTitleEnabled, myXTitleEnabled, myYTitleEnabled, myY2TitleEnabled;
+  bool           myXGridMajorEnabled, myYGridMajorEnabled, myY2GridMajorEnabled;
+  bool           myXGridMinorEnabled, myYGridMinorEnabled, myY2GridMinorEnabled;
+  int            myXGridMaxMajor, myYGridMaxMajor, myY2GridMaxMajor;
+  int            myXGridMaxMinor, myYGridMaxMinor, myY2GridMaxMinor;
+  int            myXMode, myYMode;
+  double         myXDistance, myYDistance, myYDistance2;
+  bool           mySecondY;
+};
+
+class Plot2d_Plot2d : public QwtPlot 
+{
+public:
+  Plot2d_Plot2d( QWidget* parent );
+
+  void       replot();
+  void       getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine );
+  QwtLegend* getLegend() {
+#if QWT_VERSION < 0x040200
+     return d_legend;
+#else  
+     return legend(); /* mpv: porting to the Qwt 4.2.0 */
+#endif
+  }
+  virtual QSize       sizeHint() const;
+  virtual QSizePolicy sizePolicy() const;
+  virtual QSize       minimumSizeHint() const;
+
+protected:
+  bool       existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine );
+
+protected:
+  QValueList<QColor> myColors;
+};
+
+#endif
diff --git a/src/Plot2d/Plot2d_ViewWindow.cxx b/src/Plot2d/Plot2d_ViewWindow.cxx
new file mode 100755 (executable)
index 0000000..5c558ea
--- /dev/null
@@ -0,0 +1,467 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// Plot2d_ViewWindow.cxx: implementation of the Plot2d_ViewWindow class.
+//
+//////////////////////////////////////////////////////////////////////
+#include "Plot2d_ViewWindow.h"
+#include "Plot2d_ViewFrame.h"
+
+#include "SUIT_ViewManager.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_Session.h"
+#include "SUIT_ToolButton.h"
+#include "SUIT_Desktop.h"
+
+#include "QtxAction.h"
+
+#include <qstatusbar.h>
+#include <qlayout.h>
+#include <qapplication.h>
+#include <qpopupmenu.h>
+#include <qimage.h>
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+Plot2d_ViewWindow::Plot2d_ViewWindow(SUIT_Desktop* theDesktop, Plot2d_Viewer* theModel)
+: SUIT_ViewWindow(theDesktop)
+{
+  myModel = theModel;
+
+  myViewFrame = new Plot2d_ViewFrame(this, "plotView");
+  setCentralWidget(myViewFrame);
+
+  myToolBar = new QToolBar(this);
+  myToolBar->setCloseMode(QDockWindow::Undocked);
+  myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
+  createActions();
+  createToolBar();
+
+  connect(myViewFrame, SIGNAL(vpModeHorChanged()), this, SLOT(onChangeHorMode()));
+  connect(myViewFrame, SIGNAL(vpModeVerChanged()), this, SLOT(onChangeVerMode()));
+  connect(myViewFrame, SIGNAL(vpCurveChanged()),   this, SLOT(onChangeCurveMode()));
+  connect(myViewFrame, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
+          this,        SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
+
+}
+
+Plot2d_ViewWindow::~Plot2d_ViewWindow()
+{
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::putInfo(QString theMsg)
+{
+  QStatusBar*  aStatusBar = myDesktop->statusBar();
+  aStatusBar->message(theMsg/*, 3000*/);
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::contextMenuPopup( QPopupMenu* thePopup )
+{
+  // scaling
+  QPopupMenu* scalingPopup = new QPopupMenu( thePopup );
+  myActionsMap[ PModeXLinearId ]->addTo( scalingPopup );
+  myActionsMap[ PModeXLogarithmicId ]->addTo( scalingPopup );
+  onChangeHorMode();
+  scalingPopup->insertSeparator();
+  myActionsMap[ PModeYLinearId ]->addTo( scalingPopup );
+  myActionsMap[ PModeYLogarithmicId ]->addTo( scalingPopup );
+  thePopup->insertItem( tr( "SCALING_POPUP" ), scalingPopup );
+  onChangeVerMode();
+
+  thePopup->insertItem(tr("TOT_PLOT2D_FITDATA"), myViewFrame, SLOT(onFitData()));
+  // curve type
+  QPopupMenu* curTypePopup = new QPopupMenu( thePopup );
+  myActionsMap[ CurvPointsId ]->addTo( curTypePopup );
+  myActionsMap[ CurvLinesId ]->addTo( curTypePopup );
+  myActionsMap[ CurvSplinesId ]->addTo( curTypePopup );
+  thePopup->insertItem( tr( "CURVE_TYPE_POPUP" ), curTypePopup );
+
+  // legend
+  myActionsMap[ LegendId ]->addTo(thePopup);
+  // settings
+  myActionsMap[ CurvSettingsId ]->addTo(thePopup);
+}
+
+//****************************************************************
+bool Plot2d_ViewWindow::eventFilter(QObject* watched, QEvent* e)
+{
+  if (watched == myViewFrame) {
+    int aType = e->type();
+    switch(aType) {
+    case QEvent::MouseButtonPress:
+      emit mousePressed(this, (QMouseEvent*) e);
+      return true;
+
+    case QEvent::MouseButtonRelease:
+      emit mouseReleased(this, (QMouseEvent*) e);
+      return true;
+
+    case QEvent::MouseMove:
+      emit mouseMoving(this, (QMouseEvent*) e);
+      return true;
+
+    default:
+      break;
+    }
+  }
+  return SUIT_ViewWindow::eventFilter(watched, e);
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::createActions()
+{
+  if ( !myActionsMap.isEmpty() )
+    return;
+
+  QtxAction* aAction;
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+
+  // Dump view
+  aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_DUMP" ) ),
+                           tr( "MNU_DUMP_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onDumpView()));
+  myActionsMap[ DumpId ] = aAction;
+
+  // FitAll
+  aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_FIT_ALL" ) ),
+                           tr( "MNU_FITALL" ), 0, this);
+  aAction->setStatusTip(tr("DSC_FITALL"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onFitAll()));
+  myActionsMap[ FitAllId ] = aAction;
+
+  // FitRect
+  aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_FIT_AREA" ) ),
+                           tr( "MNU_FITRECT" ), 0, this);
+  aAction->setStatusTip(tr("DSC_FITRECT"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onFitRect()));
+  myActionsMap[ FitRectId ] = aAction;
+
+  // Zoom
+  aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_ZOOM" ) ),
+                           tr( "MNU_ZOOM_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onZoom()));
+  myActionsMap[ ZoomId ] = aAction;
+
+  // Panning
+  aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_PAN" ) ),
+                           tr( "MNU_PAN_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_PAN_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onPanning()));
+  myActionsMap[ PanId ] = aAction;
+
+  // Global Panning
+  aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_GLOBALPAN" ) ),
+                           tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onGlobalPanning()));
+  myActionsMap[ GlobalPanId ] = aAction;
+
+  // Curve type - points
+  aAction = new QtxAction(tr("TOT_PLOT2D_CURVES_POINTS"),
+                aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_CURVES_POINTS")),
+                tr("MEN_PLOT2D_CURVES_POINTS"), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_CURVES_POINTS"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onCurves()));
+  aAction->setToggleAction(true);
+  myActionsMap[ CurvPointsId ] = aAction;
+
+  // Curve type - lines
+  aAction = new QtxAction(tr("TOT_PLOT2D_CURVES_LINES"),
+               aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_CURVES_LINES")),
+               tr("MEN_PLOT2D_CURVES_LINES"), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_CURVES_LINES"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onCurves()));
+  aAction->setToggleAction(true);
+  myActionsMap[ CurvLinesId ] = aAction;
+
+  // Curve type - splines
+  aAction = new QtxAction(tr("TOT_PLOT2D_CURVES_SPLINES"),
+                 aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_CURVES_SPLINES")),
+                 tr("MEN_PLOT2D_CURVES_SPLINES"), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_CURVES_SPLINES"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onCurves()));
+  aAction->setToggleAction(true);
+  myActionsMap[ CurvSplinesId ] = aAction;
+
+  // Mode for X (linear or logarithmic)
+  aAction = new QtxAction(tr("TOT_PLOT2D_MODE_LINEAR_HOR"),
+                 aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_MODE_LINEAR_HOR")),
+                 tr("MEN_PLOT2D_MODE_LINEAR_HOR"), 0, this);
+  aAction->setStatusTip (tr("PRP_PLOT2D_MODE_LINEAR_HOR"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onViewHorMode()));
+  myActionsMap[ HorId ] = aAction;
+
+  // Mode for Y (linear or logarithmic)
+  aAction = new QtxAction(tr("TOT_PLOT2D_MODE_LINEAR_VER"),
+                 aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_MODE_LINEAR_VER")),
+                 tr("MEN_PLOT2D_MODE_LINEAR_VER" ), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_MODE_LINEAR_VER"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onViewVerMode()));
+  myActionsMap[ VerId ] = aAction;
+
+  // Legend
+  aAction = new QtxAction(tr("TOT_PLOT2D_SHOW_LEGEND"),
+                aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_SHOW_LEGEND")),
+                tr("MEN_PLOT2D_SHOW_LEGEND"), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_SHOW_LEGEND"));
+  connect(aAction, SIGNAL(activated()), this, SLOT(onLegend()));
+  aAction->setToggleAction(true);
+  myActionsMap[ LegendId ] = aAction;
+
+  // Settings
+  aAction = new QtxAction(tr( "TOT_PLOT2D_SETTINGS"),
+                aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_SETTINGS")),
+                tr("MEN_PLOT2D_SETTINGS"), 0, this);
+  aAction->setStatusTip(tr( "PRP_PLOT2D_SETTINGS"));
+  connect(aAction, SIGNAL(activated()), myViewFrame, SLOT(onSettings()));
+  myActionsMap[ CurvSettingsId ] = aAction;
+
+  // Clone
+  aAction = new QtxAction(tr("MNU_CLONE_VIEW"), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_CLONE_VIEW" ) ),
+                           tr( "MNU_CLONE_VIEW" ), 0, this);
+  aAction->setStatusTip(tr("DSC_CLONE_VIEW"));
+  connect(aAction, SIGNAL(activated()), this, SIGNAL(cloneView()));
+  myActionsMap[ CloneId ] = aAction;
+
+  /* Popup Actions */
+  /* Linear/logarithmic mode */
+  // Horizontal axis
+  aAction = new QtxAction(tr("TOT_PLOT2D_MODE_LINEAR_HOR"),
+                 aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_MODE_LINEAR_HOR")),
+                 tr("MEN_PLOT2D_MODE_LINEAR_HOR"), 0, this);
+  aAction->setStatusTip (tr("PRP_PLOT2D_MODE_LINEAR_HOR"));
+  aAction->setToggleAction(true);
+  myActionsMap[PModeXLinearId] = aAction;
+  connect(aAction, SIGNAL(activated()), this, SLOT(onViewHorMode()));
+
+  aAction = new QtxAction(tr("TOT_PLOT2D_MODE_LOGARITHMIC_HOR"),
+              aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_MODE_LOGARITHMIC_HOR")),
+              tr("MEN_PLOT2D_MODE_LOGARITHMIC_HOR"), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_MODE_LOGARITHMIC_HOR"));
+  aAction->setToggleAction(true);
+  myActionsMap[PModeXLogarithmicId] = aAction;
+  connect(aAction, SIGNAL(activated()), this, SLOT(onViewHorMode()));
+
+  // Vertical axis
+  aAction = new QtxAction(tr("TOT_PLOT2D_MODE_LINEAR_VER"),
+                 aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_MODE_LINEAR_VER")),
+                 tr("MEN_PLOT2D_MODE_LINEAR_VER" ), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_MODE_LINEAR_VER"));
+  aAction->setToggleAction(true);
+  myActionsMap[PModeYLinearId] = aAction;
+  connect(aAction, SIGNAL(activated()), this, SLOT(onViewVerMode()));
+
+  aAction = new QtxAction(tr("TOT_PLOT2D_MODE_LOGARITHMIC_VER"),
+                 aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_MODE_LOGARITHMIC_VER")),
+                 tr("MEN_PLOT2D_MODE_LOGARITHMIC_VER" ), 0, this);
+  aAction->setStatusTip(tr("PRP_PLOT2D_MODE_LOGARITHMIC_VER"));
+  aAction->setToggleAction(true);
+  myActionsMap[PModeYLogarithmicId] = aAction;
+  connect(aAction, SIGNAL(activated()), this, SLOT(onViewVerMode()));
+
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::createToolBar()
+{
+  myActionsMap[DumpId]->addTo(myToolBar);
+
+  SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar);
+  aScaleBtn->AddAction(myActionsMap[FitAllId]);
+  aScaleBtn->AddAction(myActionsMap[FitRectId]);
+  aScaleBtn->AddAction(myActionsMap[ZoomId]);
+
+  SUIT_ToolButton* aPanBtn = new SUIT_ToolButton(myToolBar);
+  aPanBtn->AddAction(myActionsMap[PanId]);
+  aPanBtn->AddAction(myActionsMap[GlobalPanId]);
+
+  myCurveBtn = new SUIT_ToolButton(myToolBar);
+  myCurveBtn->AddAction(myActionsMap[CurvPointsId]);
+  myCurveBtn->AddAction(myActionsMap[CurvLinesId]);
+  myCurveBtn->AddAction(myActionsMap[CurvSplinesId]);
+  myActionsMap[CurvLinesId]->setOn(true);
+  onChangeCurveMode();
+
+  myActionsMap[HorId]->addTo(myToolBar);
+  onChangeHorMode();
+  myActionsMap[VerId]->addTo(myToolBar);
+  onChangeVerMode();
+
+  myActionsMap[LegendId]->addTo(myToolBar);
+  myActionsMap[CurvSettingsId]->addTo(myToolBar);
+  myActionsMap[CloneId]->addTo(myToolBar);
+  onChangeLegendMode();
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onChangeHorMode()
+{
+  bool aLinear = myViewFrame->isModeHorLinear();
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+
+  myActionsMap[PModeXLinearId]->setOn( aLinear );
+  myActionsMap[PModeXLogarithmicId]->setOn( !aLinear );
+
+  QPixmap pix = aResMgr->loadPixmap( "Plot2d", tr( aLinear ? "ICON_PLOT2D_MODE_LOGARITHMIC_HOR" :
+                                                             "ICON_PLOT2D_MODE_LINEAR_HOR" ) );
+  myActionsMap[HorId]->setIconSet( pix );
+  myActionsMap[HorId]->setToolTip( tr( aLinear ? "TOT_PLOT2D_MODE_LOGARITHMIC_HOR" :
+                                                 "TOT_PLOT2D_MODE_LINEAR_HOR" ) );
+  myActionsMap[HorId]->setStatusTip( tr( aLinear ? "PRP_PLOT2D_MODE_LOGARITHMIC_HOR" :
+                                                   "PRP_PLOT2D_MODE_LINEAR_HOR" ) );
+
+  myActionsMap[GlobalPanId]->setEnabled( myViewFrame->isModeVerLinear() && myViewFrame->isModeHorLinear() );
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onChangeVerMode()
+{
+  bool aLinear = myViewFrame->isModeVerLinear();
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+
+  myActionsMap[PModeYLinearId]->setOn( aLinear );
+  myActionsMap[PModeYLogarithmicId]->setOn( !aLinear );
+
+  QPixmap pix = aResMgr->loadPixmap( "Plot2d", tr( aLinear ? "ICON_PLOT2D_MODE_LOGARITHMIC_VER" :
+                                                             "ICON_PLOT2D_MODE_LINEAR_VER" ) );
+  myActionsMap[VerId]->setIconSet( pix );
+  myActionsMap[VerId]->setToolTip( tr( aLinear ? "TOT_PLOT2D_MODE_LOGARITHMIC_VER" :
+                                                 "TOT_PLOT2D_MODE_LINEAR_VER" ) );
+  myActionsMap[VerId]->setStatusTip( tr( aLinear ? "PRP_PLOT2D_MODE_LOGARITHMIC_VER" :
+                                                   "PRP_PLOT2D_MODE_LINEAR_VER" ) );
+
+  myActionsMap[GlobalPanId]->setEnabled( myViewFrame->isModeVerLinear() && myViewFrame->isModeHorLinear() );
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onChangeCurveMode()
+{
+  int aCurveType = myViewFrame->getCurveType();
+  myCurveBtn->SetItem(aCurveType);
+
+  myActionsMap[CurvPointsId]->setOn(aCurveType == 0);
+  myActionsMap[CurvLinesId]->setOn(aCurveType == 1);
+  myActionsMap[CurvSplinesId]->setOn(aCurveType == 2);
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onChangeLegendMode()
+{
+  myActionsMap[ LegendId ]->setOn(myViewFrame->isLegendShow());
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onFitAll()
+{
+  myViewFrame->onViewFitAll();
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onFitRect()
+{
+  myViewFrame->onViewFitArea();
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onZoom()
+{
+  myViewFrame->onViewZoom();
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onPanning()
+{
+  myViewFrame->onViewPan();
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onGlobalPanning()
+{
+  myViewFrame->onViewGlobalPan();
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onViewHorMode()
+{
+  if (myViewFrame->isModeHorLinear())
+    myViewFrame->setHorScaleMode(1);
+  else
+    myViewFrame->setHorScaleMode(0);
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onViewVerMode()
+{
+  if (myViewFrame->isModeVerLinear())
+    myViewFrame->setVerScaleMode(1);
+  else
+    myViewFrame->setVerScaleMode(0);
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onLegend()
+{
+  myViewFrame->showLegend(!myViewFrame->isLegendShow());
+  onChangeLegendMode();
+}
+
+//****************************************************************
+void Plot2d_ViewWindow::onCurves()
+{
+  QtxAction* aSender = (QtxAction*) sender();
+  if(aSender == myActionsMap[CurvPointsId])
+    myViewFrame->setCurveType(0);
+  else if(aSender == myActionsMap[CurvLinesId])
+    myViewFrame->setCurveType(1);
+  else if(aSender == myActionsMap[CurvSplinesId])
+    myViewFrame->setCurveType(2);
+}
+//****************************************************************
+void Plot2d_ViewWindow::onDumpView()
+{
+  qApp->postEvent( myViewFrame, new QPaintEvent( QRect( 0, 0, myViewFrame->width(), myViewFrame->height() ), TRUE ) );
+  SUIT_ViewWindow::onDumpView();
+}
+
+//****************************************************************
+QImage Plot2d_ViewWindow::dumpView()
+{
+  QPixmap px = QPixmap::grabWindow( myViewFrame->winId() );
+  return px.convertToImage();
+}
+
+bool Plot2d_ViewWindow::dumpViewToFormat( const QString& fileName, const QString& format )
+{
+  bool res = myViewFrame ? myViewFrame->print( fileName, format ) : false;
+  if( !res )
+    res = SUIT_ViewWindow::dumpViewToFormat( fileName, format );
+
+  return res;
+}
+
+QString Plot2d_ViewWindow::filter() const
+{
+  return SUIT_ViewWindow::filter() + ";;" + tr( "POSTSCRIPT_FILES" );
+}
diff --git a/src/Plot2d/Plot2d_ViewWindow.h b/src/Plot2d/Plot2d_ViewWindow.h
new file mode 100755 (executable)
index 0000000..571d692
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef PLOT2D_VIEWWINDOW_H
+#define PLOT2D_VIEWWINDOW_H
+
+#include "Plot2d.h"
+#include <SUIT_ViewWindow.h>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class SUIT_Desktop;
+class Plot2d_Viewer;
+class Plot2d_ViewFrame;
+class QtxAction;
+class SUIT_ToolButton;
+
+class PLOT2D_EXPORT Plot2d_ViewWindow : public SUIT_ViewWindow  
+{
+  Q_OBJECT
+
+public:
+  Plot2d_ViewWindow( SUIT_Desktop* theDesktop, Plot2d_Viewer* theModel );
+  virtual ~Plot2d_ViewWindow();
+
+  Plot2d_Viewer*    getModel() { return myModel; }
+  void              putInfo(QString theMsg);
+  Plot2d_ViewFrame* getViewFrame() { return myViewFrame; };
+  QToolBar*         getToolBar() { return myToolBar; };
+  void              contextMenuPopup( QPopupMenu* thePopup );
+
+protected:
+  virtual QImage    dumpView();
+  virtual QString   filter() const;
+  virtual bool      dumpViewToFormat( const QString& fileName, const QString& format );
+
+private:
+  bool eventFilter(QObject* watched, QEvent* e);
+
+  void createActions();
+  void createToolBar();
+
+public slots:
+  void onChangeHorMode();
+  void onChangeVerMode();
+  void onChangeCurveMode();
+  void onChangeLegendMode();
+  
+  void onFitAll();
+  void onFitRect();
+  void onZoom();
+  void onPanning();
+  void onGlobalPanning();
+  void onViewHorMode();
+  void onViewVerMode();
+  void onLegend();
+  void onCurves();
+
+  void onDumpView();
+
+signals:
+  void cloneView();
+
+protected:
+  enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, HorId,
+         VerId, LegendId, CurvPointsId, CurvLinesId, CurvSplinesId, CurvSettingsId, CloneId,
+         PModeXLinearId, PModeXLogarithmicId, PModeYLinearId, PModeYLogarithmicId };
+  typedef QMap<int, QtxAction*> ActionsMap;
+  ActionsMap        myActionsMap;
+
+private:
+  Plot2d_Viewer*    myModel;
+  Plot2d_ViewFrame* myViewFrame;
+  QToolBar*         myToolBar;
+
+  SUIT_ToolButton*  myCurveBtn;
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/Plot2d/resources/Plot2d_msg_en.po b/src/Plot2d/resources/Plot2d_msg_en.po
new file mode 100755 (executable)
index 0000000..a646152
--- /dev/null
@@ -0,0 +1,393 @@
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: example-Qt-message-extraction\n"
+"POT-Creation-Date: 1999-02-23 15:38+0200\n"
+"PO-Revision-Date: 1999-02-23 15:38+0200\n"
+"Last-Translator: \n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+# ------------------------------------
+# Plot2d_ViewFrame
+# ------------------------------------
+msgid "TOT_PLOT2D_MODE_LINEAR_HOR"
+msgstr "Horizontal axis: linear"
+
+msgid "MEN_PLOT2D_MODE_LINEAR_HOR"
+msgstr "Horizontal axis: linear"
+
+msgid "PRP_PLOT2D_MODE_LINEAR_HOR"
+msgstr "Switches view to linear scaling mode along horizontal axis"
+
+msgid "TOT_PLOT2D_MODE_LOGARITHMIC_HOR"
+msgstr "Horizontal axis: logarithmic"
+
+msgid "MEN_PLOT2D_MODE_LOGARITHMIC_HOR"
+msgstr "Horizontal axis: logarithmic"
+
+msgid "PRP_PLOT2D_MODE_LOGARITHMIC_HOR"
+msgstr "Switches view to logarithmic scaling mode along horizontal axis"
+
+msgid "TOT_PLOT2D_MODE_LINEAR_VER"
+msgstr "Vertical axis: linear"
+
+msgid "MEN_PLOT2D_MODE_LINEAR_VER"
+msgstr "Vertical axis: linear"
+
+msgid "PRP_PLOT2D_MODE_LINEAR_VER"
+msgstr "Switches view to linear scaling mode along vertical axis"
+
+msgid "TOT_PLOT2D_MODE_LOGARITHMIC_VER"
+msgstr "Vertical axis: logarithmic"
+
+msgid "MEN_PLOT2D_MODE_LOGARITHMIC_VER"
+msgstr "Vertical axis: logarithmic"
+
+msgid "PRP_PLOT2D_MODE_LOGARITHMIC_VER"
+msgstr "Switches view to logarithmic scaling mode along vertical axis"
+
+msgid "TOT_PLOT2D_SHOW_LEGEND"
+msgstr "Show Legend"
+
+msgid "MEN_PLOT2D_SHOW_LEGEND"
+msgstr "Show &Legend"
+
+msgid "PRP_PLOT2D_SHOW_LEGEND"
+msgstr "Enables/disables legend"
+
+msgid "TOT_PLOT2D_CURVES_POINTS"
+msgstr "Draw points"
+
+msgid "MEN_PLOT2D_CURVES_POINTS"
+msgstr "Draw points"
+
+msgid "PRP_PLOT2D_CURVES_POINTS"
+msgstr "Switches view to points mode"
+
+msgid "TOT_PLOT2D_CURVES_LINES"
+msgstr "Draw lines"
+
+msgid "MEN_PLOT2D_CURVES_LINES"
+msgstr "Draw lines"
+
+msgid "PRP_PLOT2D_CURVES_LINES"
+msgstr "Switches view to lines mode"
+
+msgid "TOT_PLOT2D_CURVES_SPLINES"
+msgstr "Draw splines"
+
+msgid "MEN_PLOT2D_CURVES_SPLINES"
+msgstr "Draw splines"
+
+msgid "PRP_PLOT2D_CURVES_SPLINES"
+msgstr "Switches view to splines mode"
+
+msgid "TOT_PLOT2D_SETTINGS"
+msgstr "Settings"
+
+msgid "MEN_PLOT2D_SETTINGS"
+msgstr "&Settings"
+
+msgid "PRP_PLOT2D_SETTINGS"
+msgstr "Setups view properties"
+
+msgid "TOT_PLOT2D_FITDATA"
+msgstr "Fit range"
+
+msgid "MEN_PLOT2D_FITDATA"
+msgstr "Fit &Range"
+
+msgid "PRP_PLOT2D_FITDATA"
+msgstr "Fits view to the given data range"
+
+msgid "TOT_PLOT2D_CHANGE_BACKGROUND"
+msgstr "Change background"
+
+msgid "MEN_PLOT2D_CHANGE_BACKGROUND"
+msgstr "Change background..."
+
+msgid "PRP_PLOT2D_CHANGE_BACKGROUND"
+msgstr "Change background color"
+
+msgid "SCALING_POPUP"
+msgstr "Scaling"
+
+msgid "CURVE_TYPE_POPUP"
+msgstr "Curve type"
+
+msgid "INF_COORDINATES"
+msgstr "Coordinates: X : %1, Y : %2"
+
+msgid "WARNING"
+msgstr "Warning"
+
+msgid "WRN_XLOG_NOT_ALLOWED"
+msgstr "Some points with non-positive abscissa values have been detected.\nLogarithmic scale for abscissa axis is not allowed."
+
+msgid "WRN_YLOG_NOT_ALLOWED"
+msgstr "Some points with non-positive ordinate values have been detected.\nLogarithmic scale for ordinate axis is not allowed."
+
+msgid "INF_COORDINATES_SOME_Y"
+msgstr "Coordinates: X : %1, Y : %2 ( %3 )"
+
+#msgid "INF_READY"
+#msgstr "Ready"
+
+msgid "PLOT2D_IMAGE_FILES"
+msgstr "Images Files (*.bmp *.png *.jpg *.jpeg)"
+
+msgid "INF_APP_DUMP_VIEW"
+msgstr "Dump view"
+
+msgid "ERR_DOC_CANT_SAVE_FILE"
+msgstr "Cannot save file"
+
+msgid "ERROR"
+msgstr "Error"
+
+msgid "BUT_OK"
+msgstr "Ok"
+
+# ------------------------------------
+# Plot2d_SetupViewDlg
+# ------------------------------------
+msgid "TLT_SETUP_PLOT2D_VIEW"
+msgstr "Plot 2d View Settings"
+
+msgid "PLOT2D_ENABLE_MAIN_TITLE"
+msgstr "Main title"
+
+msgid "PLOT2D_ENABLE_HOR_TITLE"
+msgstr "Horizontal axis title"
+
+msgid "INF_AXES_X"
+msgstr "Axis X"
+
+msgid "INF_AXES_Y_LEFT"
+msgstr "Axis Y Left"
+
+msgid "INF_AXES_Y_RIGHT"
+msgstr "Axis Y Right"
+
+msgid "PLOT2D_ENABLE_VER_TITLE"
+msgstr "Vertical axis title"
+
+msgid "PLOT2D_CURVE_TYPE_LBL"
+msgstr "Curve type:"
+
+msgid "PLOT2D_CURVE_TYPE_POINTS"
+msgstr "Points"
+
+msgid "PLOT2D_CURVE_TYPE_LINES"
+msgstr "Lines"
+
+msgid "PLOT2D_CURVE_TYPE_SPLINE"
+msgstr "Spline"
+
+msgid "PLOT2D_ENABLE_LEGEND"
+msgstr "Show legend"
+
+msgid "PLOT2D_LEGEND_POSITION_LEFT"
+msgstr "Left"
+
+msgid "PLOT2D_LEGEND_POSITION_RIGHT"
+msgstr "Right"
+
+msgid "PLOT2D_LEGEND_POSITION_TOP"
+msgstr "Top"
+
+msgid "PLOT2D_LEGEND_POSITION_BOTTOM"
+msgstr "Bottom"
+
+msgid "PLOT2D_MARKER_SIZE_LBL"
+msgstr "Marker size:"
+
+msgid "PLOT2D_BACKGROUND_COLOR_LBL"
+msgstr "Background color:"
+
+msgid "PLOT2D_SCALE_TLT"
+msgstr "Scale mode"
+
+msgid "PLOT2D_SCALE_MODE_HOR"
+msgstr "Horizontal axis:"
+
+msgid "PLOT2D_SCALE_MODE_VER"
+msgstr "Vertical axis:"
+
+msgid "PLOT2D_SCALE_MODE_LINEAR"
+msgstr "Linear"
+
+msgid "PLOT2D_SCALE_MODE_LOGARITHMIC"
+msgstr "Logarithmic"
+
+msgid "PLOT2D_GRID_TLT"
+msgstr "Grid / Axes marks"
+
+msgid "PLOT2D_GRID_ENABLE_HOR_MAJOR"
+msgstr "Horizontal major"
+
+msgid "PLOT2D_GRID_ENABLE_VER_MAJOR"
+msgstr "Vertical major"
+
+msgid "PLOT2D_GRID_ENABLE_HOR_MINOR"
+msgstr "Horizontal minor"
+
+msgid "PLOT2D_GRID_ENABLE_VER_MINOR"
+msgstr "Vertical minor"
+
+msgid "PLOT2D_MAX_INTERVALS"
+msgstr "Max intervals"
+
+msgid "PLOT2D_SET_AS_DEFAULT_CHECK"
+msgstr "Save settings as default"
+
+# ------------------------------------
+# Plot2d_FitDataDlg
+# ------------------------------------
+msgid "FIT_DATA_TLT"
+msgstr "Fit Data Range"
+
+msgid "Plot2d_FitDataDlg::FIT_ALL"
+msgstr "Fit both"
+
+msgid "Plot2d_FitDataDlg::FIT_HORIZONTAL"
+msgstr "Fit horizontally"
+
+msgid "Plot2d_FitDataDlg::FIT_VERTICAL"
+msgstr "Fit vertically"
+
+msgid "Plot2d_FitDataDlg::HORIZONTAL_AXIS"
+msgstr "Horizontal axis"
+
+msgid "Plot2d_FitDataDlg::VERTICAL_AXIS"
+msgstr "Vertical axis"
+
+msgid "Plot2d_FitDataDlg::VERTICAL_LEFT_AXIS"
+msgstr "Vertical left axis"
+
+msgid "Plot2d_FitDataDlg::VERTICAL_RIGHT_AXIS"
+msgstr "Vertical right axis"
+
+msgid "Plot2d_FitDataDlg::MIN_VALUE_LAB"
+msgstr "Min:"
+
+msgid "Plot2d_FitDataDlg::MAX_VALUE_LAB"
+msgstr "Max:"
+
+# ------------------------------------
+# Plot2d_ViewWindow
+# ------------------------------------
+
+msgid "LBL_TOOLBAR_LABEL"
+msgstr "View Operations"
+
+msgid "DSC_DUMP_VIEW"
+msgstr "Saves the active view in the image file"
+
+msgid "MNU_DUMP_VIEW"
+msgstr "Dump view..."
+
+msgid "DSC_FITALL"
+msgstr "Fit all objects inside the view frame"
+
+msgid "MNU_FITALL"
+msgstr "Fit All"
+
+msgid "DSC_FITRECT"
+msgstr "Fit area within the view frame"
+
+msgid "MNU_FITRECT"
+msgstr "Fit Area"
+
+msgid "DSC_ZOOM_VIEW"
+msgstr "Zoom the view"
+
+msgid "MNU_ZOOM_VIEW"
+msgstr "Zoom"
+
+msgid "DSC_PAN_VIEW"
+msgstr "Panning the view"
+
+msgid "MNU_PAN_VIEW"
+msgstr "Panning"
+
+msgid "DSC_GLOBALPAN_VIEW"
+msgstr "Selection of a new center of the view"
+
+msgid "MNU_GLOBALPAN_VIEW"
+msgstr "Global Panning"
+
+msgid "DSC_CLONE_VIEW"
+msgstr "Create new OCC viewer for the active scene"
+
+msgid "MNU_CLONE_VIEW"
+msgstr "Clone View"
+
+
+msgid "TLT_SETUP_CURVE"
+msgstr "Setup Curve"
+
+msgid "CURVE_LINE_TYPE_LAB"
+msgstr "Line type:"
+
+msgid "CURVE_LINE_WIDTH_LAB"
+msgstr "Line width:"
+
+msgid "CURVE_MARKER_TYPE_LAB"
+msgstr "Marker type:"
+
+msgid "CURVE_COLOR_LAB"
+msgstr "Color:"
+
+msgid "NONE_LINE_LBL"
+msgstr "None"
+
+msgid "SOLID_LINE_LBL"
+msgstr "Solid"
+
+msgid "DASH_LINE_LBL"
+msgstr "Dash"
+
+msgid "DOT_LINE_LBL"
+msgstr "Dot"
+
+msgid "DASHDOT_LINE_LBL"
+msgstr "DashDot"
+
+msgid "DAHSDOTDOT_LINE_LBL"
+msgstr "DashDotDot"
+
+msgid "NONE_MARKER_LBL"
+msgstr "None"
+
+msgid "CIRCLE_MARKER_LBL"
+msgstr "Circle"
+
+msgid "RECTANGLE_MARKER_LBL"
+msgstr "Rectangle"
+
+msgid "DIAMOND_MARKER_LBL"
+msgstr "Diamond"
+
+msgid "DTRIANGLE_MARKER_LBL"
+msgstr "Downward triangle"
+
+msgid "UTRIANGLE_MARKER_LBL"
+msgstr "Upward triangle"
+
+msgid "LTRIANGLE_MARKER_LBL"
+msgstr "Leftward triangle"
+
+msgid "RTRIANGLE_MARKER_LBL"
+msgstr "Rightward triangle"
+
+msgid "CROSS_MARKER_LBL"
+msgstr "Cross"
+
+msgid "XCROSS_MARKER_LBL"
+msgstr "Diagonal cross"
+
+msgid "POSTSCRIPT_FILES"
+msgstr "PostScript files (*.ps)"
diff --git a/src/PyInterp/PyInterp_Dispatcher.cxx b/src/PyInterp/PyInterp_Dispatcher.cxx
new file mode 100755 (executable)
index 0000000..3d5067d
--- /dev/null
@@ -0,0 +1,213 @@
+//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+//
+//  Copyright (C) 2005  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : PyInterp_Dispatcher.cxx
+//  Author : Sergey ANIKIN, OCC
+//  Module : GUI
+//  $Header$
+
+
+#include <PyInterp_base.h>
+#include <PyInterp_Dispatcher.h>
+#include <PyInterp_Watcher.h>
+
+#include <qapplication.h>
+#include <qobject.h>
+
+//#include <utilities.h>
+using namespace std;
+
+PyInterp_Dispatcher* PyInterp_Dispatcher::myInstance = 0;
+
+//////////////////////////////////////////////////////////
+// class : PyInterp_Request
+//////////////////////////////////////////////////////////
+
+void PyInterp_Request::process()
+{
+  safeExecute();
+
+  myMutex.lock();
+  //if ( !IsSync() && getListener() && getEvent() )
+  if ( getListener() && getEvent() )
+    postEvent();
+  myMutex.unlock();
+}
+
+void PyInterp_Request::safeExecute()
+{
+  execute();
+}
+
+void PyInterp_Request::Destroy( PyInterp_Request* request )
+{
+  // Lock and unlock the mutex to avoid errors on its deletion
+  request->myMutex.lock();
+  request->myMutex.unlock();
+  delete request;
+}
+
+QEvent* PyInterp_Request::createEvent() const
+{
+  return new PyInterp_Event( PyInterp_Event::NOTIFY, (PyInterp_Request*)this );
+}
+
+QEvent* PyInterp_Request::getEvent()
+{
+  //if ( !myEvent && !IsSync() )
+  if ( !myEvent )
+    myEvent = createEvent();
+  return myEvent;
+}
+
+void PyInterp_Request::postEvent()
+{
+#if QT_VERSION >= 0x030303
+//  MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.3.3")
+  QApplication::postEvent( getListener(), getEvent() );
+#else
+//  MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.0.5")
+  QThread::postEvent( getListener(), getEvent() );
+#endif
+}
+
+void PyInterp_Request::setListener( QObject* o )
+{
+  myMutex.lock();
+  myListener = o;
+  myMutex.unlock();
+}
+
+void PyInterp_LockRequest::safeExecute()
+{
+  if ( getInterp() ){
+    PyLockWrapper aLock = getInterp()->GetLockWrapper();
+    execute();
+  }
+}
+
+//////////////////////////////////////////////////////////
+// class : PyInterp_Event
+//////////////////////////////////////////////////////////
+
+PyInterp_Event::~PyInterp_Event()
+{
+  PyInterp_Request::Destroy( myRequest );
+  myRequest = 0;
+}
+
+//////////////////////////////////////////////////////////
+// class : PyInterp_Dispatcher
+//////////////////////////////////////////////////////////
+
+PyInterp_Dispatcher* PyInterp_Dispatcher::Get()
+{
+  if ( !myInstance )
+    myInstance = new PyInterp_Dispatcher();
+  return myInstance;
+}
+
+PyInterp_Dispatcher::PyInterp_Dispatcher() 
+: QThread()
+{
+  myWatcher = new PyInterp_Watcher();
+}
+
+PyInterp_Dispatcher::~PyInterp_Dispatcher()
+{
+  // Clear the request queue
+  myQueueMutex.lock();
+
+  for ( std::list<PyInterp_Request*>::iterator it = myQueue.begin(); it != myQueue.end(); ++it )
+    PyInterp_Request::Destroy( *it );
+  myQueue.clear();
+
+  myQueueMutex.unlock();
+
+  // Wait for run() to finish
+  wait();
+
+  delete myWatcher;
+  myWatcher = 0;
+}
+
+bool PyInterp_Dispatcher::IsBusy() const
+{
+  return running();
+}
+
+void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest )
+{
+  if ( !theRequest )
+    return;
+
+  //if ( theRequest->IsSync() && !IsBusy() ) // synchronous processing - nothing is done if dispatcher is busy!
+  if ( theRequest->IsSync() ) // synchronous processing - nothing is done if dispatcher is busy!
+    processRequest( theRequest );
+  else { // asynchronous processing
+    myQueueMutex.lock();
+    myQueue.push_back( theRequest );
+    if ( theRequest->getListener() )
+      QObject::connect( theRequest->getListener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) );
+    myQueueMutex.unlock();  
+
+    if ( !IsBusy() )
+      start();
+  }
+}
+
+void PyInterp_Dispatcher::run()
+{
+//  MESSAGE("*** PyInterp_Dispatcher::run(): STARTED")
+  PyInterp_Request* aRequest;
+
+  // prepare for queue size check
+  myQueueMutex.lock();
+
+  while( myQueue.size() ) {
+//    MESSAGE("*** PyInterp_Dispatcher::run(): next request taken from the queue")
+    aRequest = myQueue.front();
+
+    // let other threads append their requests to the end of the queue
+    myQueueMutex.unlock();
+
+    // processRequest() may delete a request, so this pointer must not be used
+    // after request is processed!
+    processRequest( aRequest );
+
+    // prepare for removal of the first request in the queue
+    myQueueMutex.lock();
+    // IMPORTANT: the first item could have been removed by objectDestroyed() --> we have to check it
+    if ( myQueue.front() == aRequest ) // It's still here --> remove it
+      myQueue.pop_front();
+
+//    MESSAGE("*** PyInterp_Dispatcher::run(): request processed")
+  }
+
+  myQueueMutex.unlock();
+//  MESSAGE("*** PyInterp_Dispatcher::run(): FINISHED")
+}
+
+void PyInterp_Dispatcher::processRequest( PyInterp_Request* theRequest )
+{
+  theRequest->process();
+}
+
+void PyInterp_Dispatcher::objectDestroyed( const QObject* o )
+{
+  // prepare for modification of the queue
+  myQueueMutex.lock();
+
+  for ( std::list<RequestPtr>::iterator it = myQueue.begin(); it != myQueue.end(); ++it ){
+    if ( o == (*it)->getListener() ){
+      (*it)->setListener( 0 ); // to prevent event posting
+      it = myQueue.erase( it );
+    }
+  }
+
+  myQueueMutex.unlock();
+}
+
diff --git a/src/PyInterp/PyInterp_base.cxx b/src/PyInterp/PyInterp_base.cxx
new file mode 100644 (file)
index 0000000..69ccefc
--- /dev/null
@@ -0,0 +1,300 @@
+//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : PyInterp_base.cxx
+//  Author : Christian CAREMOLI, Paul RASCLE, EDF
+//  Module : SALOME
+//  $Header$
+
+
+#include <string>
+#include <vector>
+
+#include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
+#include <cStringIO.h>
+
+using namespace std;
+
+PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): 
+  myThreadState(theThreadState),
+  mySaveThreadState(0)
+{
+#if defined(USE_GILSTATE)
+  if (myThreadState->interp == PyInterp_base::_interp) {
+    _savestate = PyGILState_Ensure();
+  } else {
+    PyEval_AcquireThread(myThreadState);
+  }
+#else 
+  PyEval_AcquireThread(myThreadState);
+#endif
+}
+
+PyLockWrapper::~PyLockWrapper()
+{
+#if defined(USE_GILSTATE)
+  if (myThreadState->interp == PyInterp_base::_interp) {
+    PyGILState_Release(_savestate);
+  } else {
+    PyEval_ReleaseThread(myThreadState);
+  }
+#else 
+  PyEval_ReleaseThread(myThreadState);
+#endif
+}
+
+class PyReleaseLock{
+public:
+  ~PyReleaseLock(){
+    PyEval_ReleaseLock();
+  }
+};
+
+
+PyLockWrapper PyInterp_base::GetLockWrapper(){
+  return _tstate;
+}
+
+
+// main python interpreter (static attributes)
+
+int PyInterp_base::_argc = 1;
+char* PyInterp_base::_argv[] = {""};
+
+PyObject *PyInterp_base::builtinmodule = NULL;
+
+PyThreadState *PyInterp_base::_gtstate = NULL;
+PyInterpreterState *PyInterp_base::_interp = NULL;
+
+
+/*!
+ * basic constructor here : herited classes constructors must call initalize() method
+ * defined here.
+ */
+PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
+{
+}
+
+PyInterp_base::~PyInterp_base()
+{
+}
+
+
+/*!
+ * Must be called by herited classes constructors. initialize() calls virtuals methods
+ * initstate & initcontext, not defined here in base class. initstate & initcontext methods
+ * must be implemented in herited classes, following the Python interpreter policy
+ * (mono or multi interpreter...).
+ */
+void PyInterp_base::initialize()
+{
+  _history.clear();       // start a new list of user's commands 
+  _ith = _history.begin();
+
+  init_python();
+  // Here the global lock is released
+
+  initState();
+
+  PyLockWrapper aLock= GetLockWrapper();
+
+  initContext();
+
+  // used to interpret & compile commands
+  PyObjWrapper m(PyImport_ImportModule("codeop"));
+  if(!m){
+    PyErr_Print();
+    return;
+  }
+
+  // Create cStringIO to capture stdout and stderr
+  PycString_IMPORT;
+  _vout = PycStringIO->NewOutput(128);
+  _verr = PycStringIO->NewOutput(128);
+
+  // All the initRun outputs are redirected to the standard output (console)
+  initRun();
+}
+
+void PyInterp_base::init_python()
+{
+  _atFirst = false;
+  if (Py_IsInitialized())
+    return;
+
+  // Python is not initialized
+  Py_SetProgramName(_argv[0]);
+  Py_Initialize(); // Initialize the interpreter
+  PySys_SetArgv(_argc, _argv);
+  PyEval_InitThreads(); // Create (and acquire) the interpreter lock
+  _interp = PyThreadState_Get()->interp;
+  _gtstate = PyEval_SaveThread(); // Release global thread state
+}
+
+string PyInterp_base::getbanner()
+{
+ // Should we take the lock ?
+ // PyEval_RestoreThread(_tstate);
+  string aBanner("Python ");
+  aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
+  aBanner = aBanner + "\ntype help to get general information on environment\n";
+  //PyEval_SaveThread();
+  return aBanner;
+}
+
+
+int PyInterp_base::initRun()
+{
+  PySys_SetObject("stderr",_verr);
+  PySys_SetObject("stdout",_vout);
+
+  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
+  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
+
+  //PyObject *m = PyImport_GetModuleDict();
+  
+  PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
+  PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
+
+  return 0;
+}
+
+
+/*!
+ * This function compiles a string (command) and then evaluates it in the dictionnary
+ * context if possible.
+ * Returns :
+ * -1 : fatal error 
+ *  1 : incomplete text
+ *  0 : complete text executed with success
+ */
+int compile_command(const char *command,PyObject *context)
+{
+  PyObject *m = PyImport_AddModule("codeop");
+  if(!m){ // Fatal error. No way to go on.
+    PyErr_Print();
+    return -1;
+  }
+  PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
+  if(!v){
+    // Error encountered. It should be SyntaxError,
+    //so we don't write out traceback
+    PyObjWrapper exception, value, tb;
+    PyErr_Fetch(&exception, &value, &tb);
+    PyErr_NormalizeException(&exception, &value, &tb);
+    PyErr_Display(exception, value, NULL);
+    return -1;
+  }else if (v == Py_None){
+    // Incomplete text we return 1 : we need a complete text to execute
+    return 1;
+  }else{
+    // Complete and correct text. We evaluate it.
+    //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+    //    PyObjWrapper r(PyEval_EvalCode(v,context,context));
+    //#else
+    PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
+    //#endif
+    if(!r){
+      // Execution error. We return -1
+      PyErr_Print();
+      return -1;
+    }
+    // The command has been successfully executed. Return 0
+    return 0;
+  }
+}
+
+
+int PyInterp_base::run(const char *command)
+{
+  if(_atFirst){
+    int ret = 0;
+    ret = simpleRun("from Help import *");
+    if (ret) { 
+      _atFirst = false;
+      return ret;
+    }
+    ret = simpleRun("import salome");
+    if (ret) { 
+      _atFirst = false;
+      return ret;
+    }
+    ret = simpleRun("salome.salome_init()");
+    if (ret) { 
+      _atFirst = false;
+      return ret;
+    }
+    _atFirst = false;
+  }
+  return simpleRun(command);
+}
+
+
+int PyInterp_base::simpleRun(const char *command)
+{
+  if( !_atFirst && strcmp(command,"") != 0 ) {
+    _history.push_back(command);
+    _ith = _history.end();
+  }
+
+  // We come from C++ to enter Python world
+  // We need to acquire the Python global lock
+  //PyLockWrapper aLock(_tstate); // san - lock is centralized now
+
+  // Reset redirected outputs before treatment
+  PySys_SetObject("stderr",_verr);
+  PySys_SetObject("stdout",_vout);
+
+  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
+  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
+
+  int ier = compile_command(command,_g);
+
+  // Outputs are redirected on standards outputs (console)
+  PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
+  PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
+
+  return ier;
+}
+
+
+const char * PyInterp_base::getPrevious()
+{
+  if(_ith != _history.begin()){
+    _ith--;
+    return (*_ith).c_str();
+  }
+  else
+    return BEGIN_HISTORY_PY;
+}
+
+
+const char * PyInterp_base::getNext()
+{
+  if(_ith != _history.end()){
+    _ith++;
+  }
+  if (_ith == _history.end())
+    return TOP_HISTORY_PY;
+  else
+    return (*_ith).c_str();
+}
+
+
+string PyInterp_base::getverr(){ 
+  //PyLockWrapper aLock(_tstate);
+  PyObjWrapper v(PycStringIO->cgetvalue(_verr));
+  string aRet(PyString_AsString(v));
+  return aRet;
+}
+
+
+string PyInterp_base::getvout(){  
+  //PyLockWrapper aLock(_tstate);
+  PyObjWrapper v(PycStringIO->cgetvalue(_vout));
+  string aRet(PyString_AsString(v));
+  return aRet;
+}
diff --git a/src/PyInterp/PyInterp_base.h b/src/PyInterp/PyInterp_base.h
new file mode 100644 (file)
index 0000000..6684777
--- /dev/null
@@ -0,0 +1,132 @@
+//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : PyInterp_base.h
+//  Author : Christian CAREMOLI, Paul RASCLE, EDF
+//  Module : SALOME
+//  $Header$
+
+#ifndef _PYINTERP_BASE_H_
+#define _PYINTERP_BASE_H_
+
+#include "PyInterp.h"
+
+#include <list>
+#include <string>
+#include <iostream>
+
+// include order important!
+// pthread then python then qt
+//#include <pthread.h>  // must be before Python.h !
+
+#include <Python.h>   // must be before qt includes ...
+#include <compile.h>   // Python include needed for versions before 2.4. Included in Python.h now.
+#include <eval.h>   // Python include needed for versions before 2.4. Included in Python.h now.
+
+//#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+//extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
+//#endif
+
+/* For 2.3, use the PyGILState_ calls */
+#if (PY_VERSION_HEX >= 0x02030000)
+#define USE_GILSTATE
+#endif
+
+#define TOP_HISTORY_PY "--- top of history ---"
+#define BEGIN_HISTORY_PY "--- begin of history ---"
+
+class PYINTERP_EXPORT PyLockWrapper
+{
+  PyThreadState* myThreadState;
+  PyThreadState* mySaveThreadState;
+#if defined(USE_GILSTATE)
+  PyGILState_STATE _savestate ;
+#endif
+ public:
+  PyLockWrapper(PyThreadState* theThreadState);
+  ~PyLockWrapper();
+};
+
+class PYINTERP_EXPORT PyInterp_base{
+ public:
+  static int _argc;
+  static char* _argv[];
+  static PyObject *builtinmodule;
+  static PyThreadState *_gtstate;
+  static PyInterpreterState *_interp;
+  
+  PyInterp_base();
+  ~PyInterp_base();
+  
+  virtual void initialize();
+  virtual void init_python();
+  // init_python() made virtual to:
+  // 1. Remove dependency on KERNEL in light SALOME configuration
+  // 2. Allow redefinition of this method in SalomeApp_PyInterp class (it should be empty there and rely on KERNEL_PYTHON)
+
+  virtual int run(const char *command); 
+
+  PyLockWrapper GetLockWrapper();
+
+  std::string getbanner(); 
+  std::string getverr();
+  std::string getvout();  
+
+  const char * getPrevious();
+  const char * getNext();    
+
+ protected:
+  PyThreadState * _tstate;
+  PyObject * _vout;
+  PyObject * _verr;
+  PyObject * _g;
+  PyObject * _codeop;
+  std::list<std::string> _history;
+  std::list<std::string>::iterator _ith;
+  bool _atFirst;
+
+  int simpleRun(const char* command);
+  int initRun();
+
+  virtual bool initState() = 0;
+  virtual bool initContext() = 0;  
+};
+
+
+class PYINTERP_EXPORT PyObjWrapper{
+  PyObject* myObject;
+public:
+  PyObjWrapper(PyObject* theObject): myObject(theObject) {}
+  PyObjWrapper(): myObject(0) {}
+  operator PyObject*(){
+    return myObject;
+  }
+  PyObject* operator->(){
+    return myObject;
+  }
+  PyObject* get(){
+    return myObject;
+  }
+  bool operator!(){
+    return !myObject;
+  }
+  bool operator==(PyObject* theObject){
+    return myObject == theObject;
+  }
+  PyObject** operator&(){
+    return &myObject;
+  }
+  PyObjWrapper& operator=(PyObjWrapper* theObjWrapper){
+    Py_XDECREF(myObject);
+    myObject = theObjWrapper->myObject;
+    return *this;
+  }
+  virtual ~PyObjWrapper(){ 
+    Py_XDECREF(myObject);
+  }
+};
+
+#endif
diff --git a/src/PythonConsole/PythonConsole_PyEditor.cxx b/src/PythonConsole/PythonConsole_PyEditor.cxx
new file mode 100755 (executable)
index 0000000..5bb4aed
--- /dev/null
@@ -0,0 +1,729 @@
+//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+//
+//  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : PythonConsole_PyEditor.cxx
+//  Author : Nicolas REJNERI
+//  Module : SALOME
+
+#include <PythonConsole_PyEditor.h> // this include must be first (see PyInterp_base.h)!
+
+#include <PyInterp_Dispatcher.h>
+
+#include <SUIT_Tools.h>
+
+#include <qmap.h>
+#include <qclipboard.h>
+#include <qdragobject.h>
+#include <qapplication.h>
+#include <qpopupmenu.h>
+
+using namespace std;
+
+//#ifdef _DEBUG_
+//static int MYDEBUG = 1;
+//#else
+//static int MYDEBUG = 0;
+//#endif
+
+
+enum { IdCopy, IdPaste, IdClear, IdSelectAll };
+
+
+static QString READY_PROMPT = ">>> ";
+static QString DOTS_PROMPT  = "... ";
+#define PROMPT_SIZE _currentPrompt.length()
+
+class ExecCommand : public PyInterp_LockRequest
+{
+public:
+  ExecCommand(PyInterp_base* theInterp, const char* theCommand,
+              PythonConsole_PyEditor* theListener, bool sync = false)
+    : PyInterp_LockRequest( theInterp, theListener, sync ),
+      myCommand( theCommand ), myState( PyInterp_Event::OK )
+  {}
+
+protected:
+  virtual void execute(){
+    if(myCommand != ""){
+//      if(MYDEBUG) MESSAGE("*** ExecCommand::execute() started");
+      int ret = getInterp()->run( myCommand.latin1() );
+//      if(MYDEBUG) MESSAGE("ExecCommand::execute() - myInterp = "<<getInterp()<<"; myCommand = '"<<myCommand.latin1()<<"' - "<<ret);
+      if(ret < 0)
+       myState = PyInterp_Event::ERROR;
+      else if(ret > 0)
+       myState = PyInterp_Event::INCOMPLETE;
+      myError  = getInterp()->getverr().c_str();
+      myOutput = getInterp()->getvout().c_str();
+//      if(MYDEBUG) MESSAGE("*** ExecCommand::execute() finished");
+    }else{
+      myError = "";
+      myOutput = "";
+    }
+  }
+
+  virtual QEvent* createEvent() const
+  {
+    return new PyInterp_Event( myState, (PyInterp_Request*)this );    
+  }
+
+public:
+  QString myError;
+  QString myOutput;
+
+private:
+  QString myCommand;
+  int myState;
+};
+
+
+/*!
+    Constructor
+*/
+PythonConsole_PyEditor::PythonConsole_PyEditor(PyInterp_base* theInterp, QWidget *theParent, const char* theName): 
+  QTextEdit(theParent,theName),
+  myInterp( 0 )
+{
+  QString fntSet( "" );
+  QFont aFont = SUIT_Tools::stringToFont( fntSet );
+  setFont(aFont);
+  //setTextFormat(QTextEdit::PlainText);
+  setUndoRedoEnabled( false );
+
+  _currentPrompt = READY_PROMPT;
+  setWordWrap(NoWrap);
+
+  connect(this,SIGNAL(returnPressed()),this,SLOT(handleReturn()) );
+
+  // san - This is necessary for troubleless initialization
+  onPyInterpChanged( theInterp );
+}
+
+/*!
+    Destructor
+*/
+PythonConsole_PyEditor::~PythonConsole_PyEditor()
+{
+//  if(MYDEBUG) MESSAGE("PythonConsole_PyEditor::~PythonConsole_PyEditor()");
+}
+
+/*!
+    Called to insert a string s 
+*/
+void PythonConsole_PyEditor::setText(QString s)
+{
+  int para=paragraphs()-1;
+  int col=paragraphLength(para);
+  insertAt(s,para,col);
+  int n = paragraphs()-1;  
+  setCursorPosition( n, paragraphLength(n)); 
+}
+
+/*!
+    Convenient method for executing a Python command,
+    as if the user typed it manually
+*/
+void PythonConsole_PyEditor::exec( const QString& command )
+{
+  // Some interactive command is being executed in this editor -> do nothing
+  if ( isReadOnly() )
+    return;
+  int para=paragraphs()-1;
+  removeParagraph( para );
+  _currentPrompt = READY_PROMPT;
+  _buf.truncate(0);
+  _isInHistory = false;
+  setText( "\n" + _currentPrompt); 
+  setText( command + "\n" ); 
+  handleReturn();
+}
+
+/*!
+    Called when an handleReturn
+*/
+void PythonConsole_PyEditor::handleReturn()
+{
+  int para=paragraphs()-2;
+  _buf.append(text(para).remove(0,PROMPT_SIZE));
+  _buf.truncate( _buf.length() - 1 );
+  setReadOnly( true );
+  viewport()->setCursor( waitCursor );
+  
+  // Post a request to execute Python command
+  // Editor will be informed via a custom event that execution has been completed
+  PyInterp_Dispatcher::Get()->Exec( new ExecCommand( myInterp, _buf.latin1(), this ) );
+}
+
+/*
+   Processes drop event: paste dragged text
+*/
+void PythonConsole_PyEditor::contentsDropEvent( QDropEvent* event )
+{
+  event->acceptAction();
+  QString text;
+  if ( QTextDrag::decode( event, text ) ) {
+    int par, col;
+    int endLine = paragraphs() -1;
+    col = charAt( event->pos(), &par );
+    
+    if ( col >= 0 && par >= 0 ) {
+      if ( par != endLine || col < PROMPT_SIZE ) {
+       par = endLine;
+       col = paragraphLength( endLine );
+      }
+      setCursorPosition( par, col );
+      insertAt( text, par, col );
+      removeSelection();
+    }
+  }
+}
+
+/*
+   Processes middle button release event - paste clipboard's contents
+*/
+void PythonConsole_PyEditor::contentsMouseReleaseEvent( QMouseEvent* event )
+{
+  if ( event->button() == LeftButton ) {
+    QTextEdit::contentsMouseReleaseEvent(event);
+    copy();
+  }
+  if ( event->button() == MidButton ) {
+    if (QApplication::clipboard()->supportsSelection()) {
+      int par, col;
+      int endLine = paragraphs() -1;
+      col = charAt( event->pos(), &par );
+      if ( col >= 0 && par >= 0 ) {
+       if ( par != endLine || col < PROMPT_SIZE )
+         setCursorPosition( endLine, paragraphLength( endLine ) );
+       else
+         setCursorPosition( par, col );
+       QApplication::clipboard()->setSelectionMode(TRUE);
+       paste();
+       QApplication::clipboard()->setSelectionMode(FALSE);
+      }
+    }
+  }
+  else {
+    QTextEdit::contentsMouseReleaseEvent(event);
+  }
+}
+
+/*
+   Processes own popup menu
+*/
+void PythonConsole_PyEditor::mousePressEvent (QMouseEvent* event)
+{
+  if ( event->button() == RightButton ) {
+    QPopupMenu *popup = new QPopupMenu( this );
+    QMap<int, int> idMap;
+
+    int para1, col1, para2, col2;
+    getSelection(&para1, &col1, &para2, &col2);
+    bool allSelected = hasSelectedText() &&
+      para1 == 0 && para2 == paragraphs()-1 && col1 == 0 && para2 == paragraphLength(para2);
+    int id;
+    id = popup->insertItem( tr( "EDIT_COPY_CMD" ) );
+    idMap.insert(IdCopy, id);
+    id = popup->insertItem( tr( "EDIT_PASTE_CMD" ) );
+    idMap.insert(IdPaste, id);
+    id = popup->insertItem( tr( "EDIT_CLEAR_CMD" ) );
+    idMap.insert(IdClear, id);
+    popup->insertSeparator();
+    id = popup->insertItem( tr( "EDIT_SELECTALL_CMD" ) );
+    idMap.insert(IdSelectAll, id);
+    popup->setItemEnabled( idMap[ IdCopy ],  hasSelectedText() );
+    popup->setItemEnabled( idMap[ IdPaste ],
+                         !isReadOnly() && (bool)QApplication::clipboard()->text().length() );
+    popup->setItemEnabled( idMap[ IdSelectAll ],
+                         (bool)text().length() && !allSelected );
+    
+    int r = popup->exec( event->globalPos() );
+    delete popup;
+    
+    if ( r == idMap[ IdCopy ] ) {
+      copy();
+    }
+    else if ( r == idMap[ IdPaste ] ) {
+      paste();
+    }
+    else if ( r == idMap[ IdClear ] ) {
+      clear();
+      setText(myBanner);
+      _currentPrompt = READY_PROMPT;
+      setText(_currentPrompt);
+    }
+    else if ( r == idMap[ IdSelectAll ] ) {
+      selectAll();
+    }
+  }
+  else {
+    QTextEdit::mousePressEvent(event);
+  }
+}
+
+/*!
+   Checks, is the string a command line or not.
+*/
+
+bool PythonConsole_PyEditor::isCommand( const QString& str) const
+{
+  // prompt may be '>>> ' or for '... '
+  return ( str.find( READY_PROMPT ) == 0 || str.find( DOTS_PROMPT ) == 0 );
+}
+
+
+/*!
+    Called when a keyPress event
+*/
+void PythonConsole_PyEditor::keyPressEvent( QKeyEvent* e )
+{
+  // get cursor position
+  int curLine, curCol;
+  getCursorPosition(&curLine, &curCol);
+
+  // get last edited line
+  int endLine = paragraphs() -1;
+
+  // get pressed key code
+  int aKey = e->key();
+
+  // check if <Ctrl> is pressed
+  bool ctrlPressed = e->state() & ControlButton;
+  // check if <Shift> is pressed
+  bool shftPressed = e->state() & ShiftButton;
+
+  // process <Ctrl>+<C> key-bindings
+  if ( aKey == Key_C && ctrlPressed ) {
+    _buf.truncate(0);
+    setText("\n");
+    _currentPrompt = READY_PROMPT;
+    setText(_currentPrompt);
+    return;
+  }
+
+  // check for printed key
+  aKey = ( aKey < Key_Space || aKey > Key_ydiaeresis ) ? aKey : 0;
+
+  switch ( aKey ) {
+  case 0 :
+    // any printed key
+    {
+      if ( curLine < endLine || curCol < PROMPT_SIZE )
+       moveCursor( QTextEdit::MoveEnd, false );
+      QTextEdit::keyPressEvent( e );
+      break;
+    }
+  case Key_Return:
+  case Key_Enter:
+    // <Enter> key
+    {
+      moveCursor( QTextEdit::MoveEnd, false );
+      QTextEdit::keyPressEvent( e );
+      break;
+    }
+  case Key_Up:
+    // <Up> arrow key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: previous command in history
+    // - with <Ctrl> modifier key pressed:  move cursor one row up without selection
+    // - with <Shift> modifier key pressed: move cursor one row up with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: scroll one row up
+    {
+      if ( ctrlPressed && shftPressed ) {
+       scrollBy( 0, -QFontMetrics( font() ).lineSpacing() );
+      }
+      else if ( shftPressed ) {
+       if ( curLine > 0 )
+         moveCursor( QTextEdit::MoveUp, true );
+      }
+      else if ( ctrlPressed ) {
+       moveCursor( QTextEdit::MoveUp, false );
+      }
+      else { 
+       QString histLine = _currentPrompt;
+       if ( ! _isInHistory ) {
+         _isInHistory = true;
+         _currentCommand = text( endLine ).remove( 0, PROMPT_SIZE );
+         _currentCommand.truncate( _currentCommand.length() - 1 );
+       }
+       QString previousCommand = myInterp->getPrevious();
+       if ( previousCommand.compare( BEGIN_HISTORY_PY ) != 0 )
+  {
+    removeParagraph( endLine );
+         histLine.append( previousCommand );
+    append( histLine );
+       }
+       moveCursor( QTextEdit::MoveEnd, false );
+      }
+      break;
+    }
+  case Key_Down:
+    // <Down> arrow key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: next command in history
+    // - with <Ctrl> modifier key pressed:  move cursor one row down without selection
+    // - with <Shift> modifier key pressed: move cursor one row down with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: scroll one row down
+    {
+      if ( ctrlPressed && shftPressed ) {
+       scrollBy( 0, QFontMetrics( font() ).lineSpacing() );
+      }
+      else if ( shftPressed ) {
+       if ( curLine < endLine )
+         moveCursor( QTextEdit::MoveDown, true );
+      }
+      else if ( ctrlPressed ) {
+       moveCursor( QTextEdit::MoveDown, false );
+      }
+      else { 
+       QString histLine = _currentPrompt;
+       QString nextCommand = myInterp->getNext();
+       if ( nextCommand.compare( TOP_HISTORY_PY ) != 0 ) {
+         removeParagraph( endLine );
+         histLine.append( nextCommand );
+         append( histLine );
+       }
+       else {
+         if (_isInHistory) {
+           _isInHistory = false;
+           removeParagraph( endLine );
+           histLine.append( _currentCommand );
+           append( histLine );
+         }
+       }
+       moveCursor( QTextEdit::MoveEnd, false );
+      }
+      break;
+    }
+  case Key_Left:
+    // <Left> arrow key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: move one symbol left (taking into account prompt)
+    // - with <Ctrl> modifier key pressed:  move one word left (taking into account prompt)
+    // - with <Shift> modifier key pressed: move one symbol left with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: move one word left with selection
+    {
+      if ( !shftPressed && isCommand( text( curLine ) ) && curCol <= PROMPT_SIZE ) {
+       setCursorPosition( curLine-1, 0 );
+       moveCursor( QTextEdit::MoveLineEnd, false );
+      }
+      else {
+       QTextEdit::keyPressEvent( e );
+      }
+      break;
+    }
+  case Key_Right:
+    // <Right> arrow key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: move one symbol right (taking into account prompt)
+    // - with <Ctrl> modifier key pressed:  move one word right (taking into account prompt)
+    // - with <Shift> modifier key pressed: move one symbol right with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: move one word right with selection
+    {
+      if ( !shftPressed ) {
+       if ( curCol < paragraphLength( curLine ) ) {
+         if ( isCommand( text( curLine ) ) && curCol < PROMPT_SIZE ) {
+           setCursorPosition( curLine, PROMPT_SIZE );
+           break;
+         }
+       }
+       else {
+         if ( curLine < endLine && isCommand( text( curLine+1 ) ) ) {
+           setCursorPosition( curLine+1, PROMPT_SIZE );
+           break;
+         }
+       }
+      }
+      QTextEdit::keyPressEvent( e );
+      break;
+    }
+  case Key_PageUp:
+    // <PageUp> key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: first command in history
+    // - with <Ctrl> modifier key pressed:  move cursor one page up without selection
+    // - with <Shift> modifier key pressed: move cursor one page up with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: scroll one page up
+    {
+      if ( ctrlPressed && shftPressed ) {
+       scrollBy( 0, -visibleHeight() );
+      }
+      else if ( shftPressed ) {
+       if ( curLine > 0 )
+         moveCursor( QTextEdit::MovePgUp, true );
+      }
+      else if ( ctrlPressed ) {
+       moveCursor( QTextEdit::MovePgUp, false );
+      }
+      else { 
+       QString histLine = _currentPrompt;
+       if ( ! _isInHistory ) {
+         _isInHistory = true;
+         _currentCommand = text( endLine ).remove( 0, PROMPT_SIZE );
+         _currentCommand.truncate( _currentCommand.length() - 1 );
+       }
+       QString firstCommand = myInterp->getPrevious();
+       QString pcmd;
+       while ( ( pcmd = QString( myInterp->getPrevious() ) ).compare( BEGIN_HISTORY_PY ) != 0 )
+         firstCommand = pcmd;
+       if ( firstCommand.compare( BEGIN_HISTORY_PY ) != 0 ) {
+         removeParagraph( endLine );
+         histLine.append( firstCommand );
+         insertParagraph( histLine, -1 );
+       }
+       moveCursor( QTextEdit::MoveEnd, false );
+      }
+      break;
+    }
+  case Key_PageDown:
+    // <PageDown> key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: last command in history
+    // - with <Ctrl> modifier key pressed:  move cursor one page down without selection
+    // - with <Shift> modifier key pressed: move cursor one page down with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: scroll one page down
+    {
+      if ( ctrlPressed && shftPressed ) {
+       scrollBy( 0, visibleHeight() );
+      }
+      else if ( shftPressed ) {
+       if ( curLine < endLine )
+         moveCursor( QTextEdit::MovePgDown, true );
+      }
+      else if ( ctrlPressed ) {
+       moveCursor( QTextEdit::MovePgDown, false );
+      }
+      else { 
+       if ( _isInHistory ) {
+         QString histLine = _currentPrompt;
+         while ( QString( myInterp->getNext() ).compare( TOP_HISTORY_PY ) != 0 );
+         _isInHistory = false;
+         removeParagraph( endLine );
+         histLine.append( _currentCommand );
+         insertParagraph( histLine, -1 );
+       }
+       moveCursor( QTextEdit::MoveEnd, false );
+      }
+      break;
+    }
+  case Key_Home: 
+    // <Home> key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: move cursor to the beginning of the current line without selection
+    // - with <Ctrl> modifier key pressed:  move cursor to the very first symbol without selection
+    // - with <Shift> modifier key pressed: move cursor to the beginning of the current line with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: move cursor to the very first symbol with selection
+    {
+      if ( ctrlPressed ) { 
+       moveCursor( QTextEdit::MoveHome, shftPressed );
+      }
+      else {
+       if ( isCommand( text( curLine ) ) ) {
+         int ps1, ps2, cs1, cs2;
+         bool hasSelection = hasSelectedText();
+         if ( hasSelection )
+           getSelection( &ps1, &cs1, &ps2, &cs2 );
+         removeSelection();
+         horizontalScrollBar()->setValue( horizontalScrollBar()->minValue() );
+         if ( curCol > PROMPT_SIZE && shftPressed ) 
+           setSelection( curLine, PROMPT_SIZE, curLine, ( hasSelection && ps1 == ps2 && ps1 == curLine && cs2 > PROMPT_SIZE ) ? cs2 : curCol );
+         setCursorPosition( curLine, PROMPT_SIZE );
+       }
+       else {
+         moveCursor( QTextEdit::MoveLineStart, shftPressed );
+       }
+      }
+      break;
+    }
+  case Key_End:
+    // <End> key: process as follows:
+    // - without <Ctrl>, <Shift> modifiers: move cursor to the end of the current line without selection
+    // - with <Ctrl> modifier key pressed:  move cursor to the very last symbol without selection
+    // - with <Shift> modifier key pressed: move cursor to the end of the current line with selection
+    // - with <Ctrl>+<Shift> modifier keys pressed: move cursor to the very last symbol with selection
+    {
+      if ( ctrlPressed ) { 
+       moveCursor( QTextEdit::MoveEnd, shftPressed );
+      }
+      else {
+       moveCursor( QTextEdit::MoveLineEnd, shftPressed );
+      }
+      break;
+    }  
+  case Key_Backspace :
+    // <Backspace> key: process as follows
+    // - without any modifiers : delete symbol before the cursor / selection (taking into account prompt)
+    // - with <Ctrl> modifier key pressed: delete previous word
+    // works only for last (command) line
+    {
+      if ( curLine == endLine && ( curCol > PROMPT_SIZE || curCol >= PROMPT_SIZE && hasSelectedText() ) ) {
+       if ( ctrlPressed && !hasSelectedText() ) {
+         QString txt = text( curLine );
+         int ind = curCol-1;
+         while ( ind > 0 && txt[ ind ] == ' ' ) ind--;
+         ind = txt.findRev( ' ', ind ) + 1;
+         if ( ind > PROMPT_SIZE-1 ) {
+           setSelection( curLine, ind, curLine, curCol );
+           removeSelectedText();
+         }
+         else {
+           QTextEdit::keyPressEvent( e );
+         }
+       }
+       else {
+         QTextEdit::keyPressEvent( e );
+       }
+      }
+      break;
+    }
+  case Key_Delete :
+    // <Delete> key: process as follows
+    // - without any modifiers : delete symbol after the cursor / selection (taking into account prompt)
+    // - with <Ctrl> modifier key pressed: delete next word
+    // works only for last (command) line
+    {
+      if ( curLine == endLine && curCol > PROMPT_SIZE-1 ) {
+       if ( ctrlPressed && !hasSelectedText() ) {
+         QString txt = text( curLine );
+         int ind = curCol;
+         while ( ind < txt.length()-1 && txt[ ind ] == ' ' ) ind++;
+         ind = txt.find( ' ', ind );
+         while ( ind < txt.length()-1 && txt[ ind ] == ' ' ) ind++;
+         if ( ind > PROMPT_SIZE-1 ) {
+           setSelection( curLine, curCol, curLine, ind );
+           removeSelectedText();
+         }
+         else {
+           QTextEdit::keyPressEvent( e );
+         }
+       }
+       else {
+         QTextEdit::keyPressEvent( e );
+       }
+      }
+      break;
+    }
+  case Key_Insert :
+    // <Insert> key: process as follows
+    // - with <Ctrl> modifier key pressed:  copy()
+    // - with <Shift> modifier key pressed: paste() to the command line
+    {
+      if ( ctrlPressed ) {
+       copy();
+      }
+      else if ( shftPressed ) {
+       if ( curLine != endLine || curCol < PROMPT_SIZE )
+         moveCursor( QTextEdit::MoveEnd, false );
+       paste();
+      }
+      else
+       QTextEdit::keyPressEvent( e );
+      break;
+    }
+  }
+}
+
+/*!
+    Handles notifications coming from Python dispatcher
+*/
+void PythonConsole_PyEditor::customEvent(QCustomEvent* e)
+{
+  switch( e->type() ) {
+  case PyInterp_Event::OK:
+  case PyInterp_Event::ERROR:
+    {
+      PyInterp_Event* pe = dynamic_cast<PyInterp_Event*>( e );
+      if ( pe ){
+       ExecCommand* ec = dynamic_cast<ExecCommand*>( pe->GetRequest() );
+       if ( ec ){
+         // The next line has appeared dangerous in case if
+         // Python command execution has produced very large output.
+         // A more clever approach is needed...
+         setText(ec->myOutput);
+         setText(ec->myError);
+       }
+      }
+      _buf.truncate(0);
+      _currentPrompt = READY_PROMPT;
+      setText(_currentPrompt);
+      viewport()->unsetCursor();
+      break;
+    }
+  case PyInterp_Event::INCOMPLETE:
+    {
+      _buf.append("\n");
+      _currentPrompt = DOTS_PROMPT;
+      setText(_currentPrompt);
+      viewport()->unsetCursor();
+      break;
+    }
+  default:
+    QTextEdit::customEvent( e );
+  }
+
+  setReadOnly( false );
+  _isInHistory = false;
+}
+
+/*!
+   Handles Python interpreter change
+*/
+void PythonConsole_PyEditor::onPyInterpChanged( PyInterp_base* interp )
+{
+  if ( myInterp != interp 
+       // Force read-only state and wait cursor when myInterp is NULL
+      || !myInterp ){
+    myInterp = interp;
+    if ( myInterp ){
+      myBanner = myInterp->getbanner().c_str();
+      setText(myBanner);
+      _buf.truncate(0);
+      setReadOnly( false );
+      _isInHistory = false;
+      setText(_currentPrompt);
+      viewport()->unsetCursor();
+    }
+    else {
+      clear();
+      setReadOnly( true );
+      viewport()->setCursor( waitCursor );
+    }
+  }
+}
+
+QPopupMenu* PythonConsole_PyEditor::createPopupMenu( const QPoint& pos )
+{
+  QPopupMenu* popup = QTextEdit::createPopupMenu( pos );
+
+  QValueList<int> ids;
+  for ( int i = 0; popup && i < popup->count(); i++ )
+  {
+    if ( !popup->isItemEnabled( popup->idAt( i ) ) )
+      ids.append( popup->idAt( i ) );
+  }
+
+  for ( QValueList<int>::const_iterator it = ids.begin(); it != ids.end(); ++it )
+    popup->removeItem( *it );
+
+  SUIT_Tools::simplifySeparators( popup );
+
+  if ( !popup->count() )
+  {
+    delete popup;
+    popup = 0;
+  }
+
+  return popup;
+}
diff --git a/src/PythonConsole/PythonConsole_PyInterp.cxx b/src/PythonConsole/PythonConsole_PyInterp.cxx
new file mode 100755 (executable)
index 0000000..5b7d3e5
--- /dev/null
@@ -0,0 +1,121 @@
+//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+//
+//  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : PythonConsole_PyInterp.cxx
+//  Author : Nicolas REJNERI
+//  Module : SALOME
+//  $Header$
+
+#include "PythonConsole_PyInterp.h"
+//#include "utilities.h"
+
+using namespace std;
+
+
+//#ifdef _DEBUG_
+//static int MYDEBUG = 0;
+//#else
+//static int MYDEBUG = 0;
+//#endif
+
+
+/*!
+ * constructor : multi Python interpreter, one per SALOME study.
+ * calls initialize method defined in base class, which calls virtual methods
+ * initstate & initcontext redefined here.
+ */
+PythonConsole_PyInterp::PythonConsole_PyInterp(): PyInterp_base()
+{
+}
+
+PythonConsole_PyInterp::~PythonConsole_PyInterp()
+{
+}
+/*!
+ * EDF-CCAR
+ * When SALOME uses multi Python interpreter feature,
+ * Every study has its own interpreter and thread state (_tstate = Py_NewInterpreter())
+ * This is fine because every study has its own modules (sys.modules) stdout and stderr
+ * BUT some Python modules must be imported only once. In multi interpreter context Python
+ * modules (*.py) are imported several times.
+ * The pyqt module must be imported only once because it registers classes in a C module.
+ * It's quite the same with omniorb modules (internals and generated with omniidl)
+ * This problem is handled with "shared modules" defined in salome_shared_modules.py
+ * These "shared modules" are imported only once and only copied in all the other interpreters
+ * BUT it's not the only problem. Every interpreter has its own __builtin__ module. That's fine
+ * but if we have copied some modules and imported others problems may arise with operations that
+ * are not allowed in restricted execution environment. So we must impose that all interpreters
+ * have identical __builtin__ module.
+ * That's all, for the moment ...
+ */
+
+bool PythonConsole_PyInterp::initState()
+{
+  /*
+   * The GIL is acquired and will be held on initState output
+   * It is the caller responsability to release the lock if needed
+   */
+  PyEval_AcquireLock();
+  _tstate = Py_NewInterpreter(); // create an interpreter and save current state
+  PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv
+//  if(MYDEBUG) MESSAGE("PythonConsole_PyInterp::initState - this = "<<this<<"; _tstate = "<<_tstate);
+
+  /*
+   * If builtinmodule has been initialized all the sub interpreters
+   * will have the same __builtin__ module
+   */
+  if(builtinmodule){ 
+    PyObject *m = PyImport_GetModuleDict();
+    PyDict_SetItemString(m, "__builtin__", builtinmodule);
+//    SCRUTE(builtinmodule->ob_refcnt); // builtinmodule reference counter
+    _tstate->interp->builtins = PyModule_GetDict(builtinmodule);
+    Py_INCREF(_tstate->interp->builtins);
+  }
+  PyEval_ReleaseThread(_tstate);
+  return true;
+}
+
+
+bool PythonConsole_PyInterp::initContext()
+{
+  /*
+   * The GIL is assumed to be held
+   * It is the caller responsability caller to acquire the GIL
+   * It will still be held on initContext output
+   */
+  PyObject *m = PyImport_AddModule("__main__");  // interpreter main module (module context)
+  if(!m){
+//    if(MYDEBUG) MESSAGE("problem...");
+    PyErr_Print();
+//    ASSERT(0);
+    return false;
+  }  
+  _g = PyModule_GetDict(m);          // get interpreter dictionnary context
+//  if(MYDEBUG) MESSAGE("PythonConsole_PyInterp::initContext - this = "<<this<<"; _g = "<<_g);
+
+  if(builtinmodule){
+    PyDict_SetItemString(_g, "__builtins__", builtinmodule); // assign singleton __builtin__ module
+  }
+  return true;
+}
diff --git a/src/QDS/Makefile.in b/src/QDS/Makefile.in
new file mode 100755 (executable)
index 0000000..97b4ae3
--- /dev/null
@@ -0,0 +1,51 @@
+#  File   : Makefile.in
+#  Author : Alexander SOLOVYOV (OCN)
+#  Module : QDS
+#  $Header: /home/server/cvs/GUI/GUI_SRC/src/QDS/Makefile.in
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+@COMMENCE@
+
+# header files 
+EXPORT_HEADERS= QDS.h \
+       QDS_CheckBox.h \
+       QDS_ComboBox.h \
+       QDS_Datum.h \
+       QDS_LineEdit.h \
+       QDS_SpinBox.h \
+       QDS_SpinBoxDbl.h \
+       QDS_TextEdit.h \
+       QDS_Validator.h
+                    
+# Libraries targets
+LIB = libQDS.la
+
+LIB_SRC= QDS.cxx \
+       QDS_CheckBox.cxx \
+       QDS_ComboBox.cxx \
+       QDS_Datum.cxx \
+       QDS_LineEdit.cxx \
+       QDS_SpinBox.cxx \
+       QDS_SpinBoxDbl.cxx \
+       QDS_TextEdit.cxx \
+       QDS_Validator.cxx
+LIB_MOC = QDS_CheckBox.h \
+       QDS_ComboBox.h \
+       QDS_Datum.h \
+       QDS_LineEdit.h \
+       QDS_SpinBox.h \
+       QDS_SpinBoxDbl.h \
+       QDS_TextEdit.h
+
+CPPFLAGS+=$(QT_INCLUDES) $(OCC_INCLUDES)
+
+LDFLAGS+=$(QT_MT_LIBS) $(CAS_KERNEL) -lDDS -lqtx
+
+@CONCLUDE@
+
+
diff --git a/src/QDS/QDS.cxx b/src/QDS/QDS.cxx
new file mode 100644 (file)
index 0000000..e6bdd56
--- /dev/null
@@ -0,0 +1,178 @@
+#include "QDS.h"
+
+#include "QDS_Datum.h"
+
+#include <qtextcodec.h>
+
+#include <DDS_DicItem.h>
+#include <DDS_Dictionary.h>
+
+#include <TCollection_HAsciiString.hxx>
+#include <TCollection_HExtendedString.hxx>
+
+QValueList<QDS_Datum*> QDS::_datumList;
+
+QString QDS::toQString( const TCollection_AsciiString& src )
+{
+  QTextCodec* codec = QTextCodec::codecForLocale();
+  QString res;
+  if ( !src.IsEmpty() )
+    res = codec ? codec->toUnicode( (char*)src.ToCString(), src.Length() ) :
+                  QString( (char*)src.ToCString() );
+  return res;
+}
+
+QString QDS::toQString( const TCollection_ExtendedString& src )
+{
+  if ( src.IsAscii() )
+    return toQString( TCollection_AsciiString( src ) );
+  else
+    return QString( (QChar*)src.ToExtString(), src.Length() );
+}
+
+QString QDS::toQString( const Handle(TCollection_HAsciiString)& src )
+{
+  if ( src.IsNull() )
+    return QString::null;
+  else
+    return toQString( src->String() );
+}
+
+QString QDS::toQString( const Handle(TCollection_HExtendedString)& src )
+{
+  if ( src.IsNull() )
+    return QString::null;
+  else
+    return toQString( src->String() );
+}
+
+TCollection_AsciiString QDS::toAsciiString( const QString& src )
+{
+  TCollection_AsciiString res;
+  if ( src.latin1() )
+  {
+    QTextCodec* codec = QTextCodec::codecForLocale();
+    if ( codec )
+    {
+      int len = -1;
+      QCString str = codec->fromUnicode( src, len );
+      res = TCollection_AsciiString( (Standard_CString)(const char*)str, len );
+    }
+    else
+      res = TCollection_AsciiString( (char*)src.latin1() );
+  }
+  return res;
+}
+
+TCollection_AsciiString QDS::toAsciiString( const TCollection_ExtendedString& src )
+{
+  return TCollection_AsciiString( src );
+}
+
+TCollection_AsciiString QDS::toAsciiString( const Handle(TCollection_HExtendedString)& src )
+{
+  TCollection_AsciiString res;
+  if ( !src.IsNull() )
+    res = toAsciiString( src->String() );
+  return res;
+}
+
+TCollection_ExtendedString QDS::toExtString( const QString& src )
+{
+  if ( src.isEmpty() )
+    return TCollection_ExtendedString();
+
+  Standard_Integer len = src.length();
+  Standard_ExtString extStr = new Standard_ExtCharacter[( len + 1 ) * 2];
+  memcpy( extStr, src.unicode(), len * 2 );
+  extStr[len] = 0;
+
+  TCollection_ExtendedString trg( extStr );
+
+  delete [] extStr;
+
+  return trg;
+}
+
+TCollection_ExtendedString QDS::toExtString( const TCollection_AsciiString& src )
+{
+  return TCollection_ExtendedString( src );
+}
+
+bool QDS::load( const QString& dictPath )
+{
+  if ( dictPath.isEmpty() )
+    return false;
+
+  return DDS_Dictionary::Load( toAsciiString( dictPath ) );
+}
+
+QString QDS::unitSystemLabel( const QString& sys, const QString& comp )
+{
+  QString lab;
+  TCollection_AsciiString system = toAsciiString( sys );
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( !dic.IsNull() )
+    lab = toQString( comp.isEmpty() ? dic->GetUnitSystemLabel( system ) :
+                                      dic->GetUnitSystemLabel( system, toAsciiString( comp ) ) );
+  return lab;
+}
+
+QString QDS::activeUnitSystem( const QString& comp )
+{
+  QString sys;
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( !dic.IsNull() )
+    sys = toQString( comp.isEmpty() ? dic->GetActiveUnitSystem() :
+                                      dic->GetActiveUnitSystem( toAsciiString( comp ) ) );
+  return sys;
+}
+
+void QDS::setActiveUnitSystem( const QString& sys, const QString& comp )
+{
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( dic.IsNull() )
+    return;
+
+  TCollection_AsciiString system = toAsciiString( sys );
+  comp.isEmpty() ? dic->SetActiveUnitSystem( system ) :
+                   dic->SetActiveUnitSystem( system, toAsciiString( comp ) );
+
+  QString unitSys = activeUnitSystem( comp );
+  if ( sys == unitSys )
+    return;
+
+  TCollection_AsciiString aComp = toAsciiString( comp );
+  for ( QValueList<QDS_Datum*>::iterator it = _datumList.begin(); it != _datumList.end(); ++it )
+  {
+    QDS_Datum* datum = *it;
+    if ( !datum )
+      continue;
+
+    bool ok = aComp.IsEmpty();
+    if ( !ok )
+    {
+      Handle(DDS_DicItem) item = datum->dicItem();
+      ok = !item.IsNull() && aComp == item->GetComponent();
+    }
+
+    if ( ok )
+      datum->unitSystemChanged( unitSys );
+  }
+}
+
+void QDS::insertDatum( QDS_Datum* datum )
+{
+  if ( !datum )
+    return;
+
+  _datumList.append( datum );
+}
+
+void QDS::removeDatum( QDS_Datum* datum )
+{
+  if ( !datum )
+    return;
+
+  _datumList.remove( datum );
+}
diff --git a/src/QDS/QDS.h b/src/QDS/QDS.h
new file mode 100644 (file)
index 0000000..c9ff5ed
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef QDS_H
+#define QDS_H
+
+#ifdef WIN32
+#ifdef QDS_EXPORTS
+#define QDS_EXPORT __declspec(dllexport)
+#else
+#define QDS_EXPORT __declspec(dllimport)
+#endif
+#else
+#define QDS_EXPORT
+#endif
+
+#if defined WIN32
+#pragma warning ( disable:4251 )
+#pragma warning ( disable:4786 )
+#endif
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+#include <TCollection_AsciiString.hxx>
+
+#include <TCollection_ExtendedString.hxx>
+
+class QDS_Datum;
+class Handle(TCollection_HAsciiString);
+class Handle(TCollection_HExtendedString);
+
+class QDS_EXPORT QDS
+{
+public:
+  typedef enum { None = 0x00, Label = 0x01, Control = 0x02, Units = 0x04,
+                 NotFormat = 0x08, NotAccel = 0x10, UnitsWithLabel = 0x20,
+                 All = Label | Control | Units } DatumFlags;
+
+public:
+  static bool                       load( const QString& );
+
+  static QString                    unitSystemLabel( const QString&,
+                                                     const QString& = QString::null );
+  static QString                    activeUnitSystem( const QString& = QString::null );
+  static void                       setActiveUnitSystem( const QString&,
+                                                         const QString& = QString::null );
+
+  static QString                    toQString( const TCollection_AsciiString& );
+  static QString                    toQString( const TCollection_ExtendedString& );
+  static QString                    toQString( const Handle(TCollection_HAsciiString)& );
+  static QString                    toQString( const Handle(TCollection_HExtendedString)& );
+
+  static TCollection_AsciiString    toAsciiString( const QString& );
+  static TCollection_AsciiString    toAsciiString( const TCollection_ExtendedString& );
+  static TCollection_AsciiString    toAsciiString( const Handle(TCollection_HExtendedString)& );
+
+  static TCollection_ExtendedString toExtString( const QString& );
+  static TCollection_ExtendedString toExtString( const TCollection_AsciiString& );
+
+protected:
+  static void                       insertDatum( QDS_Datum* );
+  static void                       removeDatum( QDS_Datum* );
+
+private:
+  static QValueList<QDS_Datum*>     _datumList;
+};
+
+#endif
diff --git a/src/QDS/QDS_CheckBox.cxx b/src/QDS/QDS_CheckBox.cxx
new file mode 100644 (file)
index 0000000..7f1924d
--- /dev/null
@@ -0,0 +1,76 @@
+#include "QDS_CheckBox.h"
+
+#include <qcheckbox.h>
+
+/*!
+  Constructor. This method is protected. Object can't be directly constructed.
+  Use static method QDS_CheckBox::Create instead.
+*/
+QDS_CheckBox::QDS_CheckBox( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_CheckBox::~QDS_CheckBox()
+{
+}
+
+/*!
+  Returns string from QCheckBox widget.
+*/
+QString QDS_CheckBox::getString() const
+{
+  return checkBox() && checkBox()->isChecked() ? "1" : "0";
+}
+
+/*!
+  Sets the string into QCheckBox widget.
+*/
+void QDS_CheckBox::setString( const QString& txt )
+{
+  bool isOk;
+  int val = (int)txt.toDouble( &isOk );
+  if ( checkBox() )
+    checkBox()->setChecked( isOk && val != 0 );
+}
+
+/*!
+  Returns pointer to QCheckBox widget.
+*/
+QCheckBox* QDS_CheckBox::checkBox() const
+{
+  return ::qt_cast<QCheckBox*>( controlWidget() );
+}
+
+/*!
+  Create QCheckBox widget as control subwidget.
+*/
+QWidget* QDS_CheckBox::createControl( QWidget* parent )
+{
+  QCheckBox* cb = new QCheckBox( parent );
+  connect( cb, SIGNAL( stateChanged( int ) ), SLOT( onParamChanged() ) );
+  connect( cb, SIGNAL( toggled( bool ) ), SIGNAL( toggled( bool ) ) );
+  return cb;
+}
+
+/*!
+  Notify about shanging of control state
+*/
+void QDS_CheckBox::onParamChanged()
+{
+  emit paramChanged();
+}
+
+void QDS_CheckBox::setChecked( const bool theState )
+{
+  if ( checkBox() )
+    checkBox()->setChecked( theState );
+}
+
+bool QDS_CheckBox::isChecked() const
+{
+  return checkBox() ? checkBox()->isChecked() : false;
+}
diff --git a/src/QDS/QDS_CheckBox.h b/src/QDS/QDS_CheckBox.h
new file mode 100644 (file)
index 0000000..7c04eda
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef QDS_CHECKBOX_H
+#define QDS_CHECKBOX_H
+
+#include "QDS_Datum.h"
+
+class QCheckBox;
+
+class QDS_EXPORT QDS_CheckBox : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_CheckBox( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_CheckBox();
+
+  bool                 isChecked() const;
+  void                 setChecked( const bool );
+
+signals:
+  void                 toggled( bool );
+
+private slots:
+  void                 onParamChanged();
+
+protected:
+  QCheckBox*           checkBox() const;
+  virtual QWidget*     createControl( QWidget* );
+
+  virtual QString      getString() const;
+  virtual void         setString( const QString& );
+};
+
+#endif
diff --git a/src/QDS/QDS_ComboBox.cxx b/src/QDS/QDS_ComboBox.cxx
new file mode 100644 (file)
index 0000000..f5e9ef8
--- /dev/null
@@ -0,0 +1,563 @@
+#include "QDS_ComboBox.h"
+
+#include <DDS_Dictionary.h>
+
+#include <TCollection_AsciiString.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_HArray1OfExtendedString.hxx>
+
+#include <qlineedit.h>
+
+/*!
+  Constructor.
+*/
+QDS_ComboBox::QDS_ComboBox( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_ComboBox::~QDS_ComboBox()
+{
+}
+
+/*!
+  Returns true if ComboBox allow to edit current Text.
+*/
+bool QDS_ComboBox::editable() const
+{
+  if ( comboBox() && comboBox()->lineEdit() )
+    return !comboBox()->lineEdit()->isReadOnly();
+  else
+    return false;
+}
+
+/*!
+  Sets the possibily of current text editing.
+*/
+void QDS_ComboBox::setEditable( const bool on )
+{
+  QComboBox* aCombo = comboBox();
+  if ( aCombo )
+    aCombo->setEditable( on );
+  if ( aCombo && aCombo->lineEdit() )
+  {
+    aCombo->lineEdit()->setReadOnly( !on );
+    aCombo->clearValidator();
+    if ( on )
+      aCombo->setValidator( validator() );
+  }
+}
+
+/*!
+  Returns number of items in ComboBox. If total is 'false' then only
+  visible items are taken into account otherwise all items.
+*/
+int QDS_ComboBox::count( bool total ) const
+{
+  if ( total )
+    return myValue.count();
+  else if ( comboBox() )
+    return comboBox()->count();
+  else
+    return 0;
+}
+
+/*!
+  Returns list of ids. If total is 'false' then only visible items
+  are taken into account otherwise all items.
+*/
+void QDS_ComboBox::values( QValueList<int>& ids, bool total ) const
+{
+  ids.clear();
+  for ( QIntList::const_iterator it = myDataIds.begin(); it != myDataIds.end(); ++it )
+    if ( total || ( myState.contains( *it ) && myState[*it] ) )
+      ids.append( *it );
+}
+
+/*!
+  Returns the current id as integer.
+*/
+int QDS_ComboBox::integerValue() const
+{
+  QComboBox* cb = comboBox();
+  QString cur = getString();
+  if ( cb && cb->count() > 0 && cb->currentItem() >= 0 )
+    cur = cb->text( cb->currentItem() );
+
+  if ( cb && cur == getString() )
+    return getId( cb->currentItem() );
+  else
+    return getId( getString() );
+}
+
+/*!
+  Returns the current id as double.
+*/
+double QDS_ComboBox::doubleValue() const
+{
+  QComboBox* cb = comboBox();
+  QString cur = getString();
+  if ( cb && cb->count() > 0 && cb->currentItem() >= 0 )
+    cur = cb->text( cb->currentItem() );
+
+  if ( cb && cur == getString() )
+    return getId( cb->currentItem() );
+  else
+    return getId( getString() );
+}
+
+/*!
+  Set the current item acording to specified id.
+*/
+void QDS_ComboBox::setIntegerValue( const int id )
+{
+  if ( myValue.contains( id ) )
+    setString( myValue[id] );
+  else 
+    setString( "" );
+}
+
+/*!
+  Get the integer part of specified value and use it as new current identifier.
+*/
+void QDS_ComboBox::setDoubleValue( const double val )
+{
+  int id = (int)val;
+  if ( myValue.contains( id ) )
+    setString( myValue[id] );
+  else if ( id == -1 )
+    setString( "" );
+}
+
+/*!
+  Returns visible state of identificator.
+*/
+bool QDS_ComboBox::state( const int id ) const
+{
+  bool state = false;
+  if ( myState.contains( id ) )
+    state = myState[id];
+  return state;
+}
+
+/*!
+  Sets the visible state of identificator. If 'id' is -1 then specified
+  state will be set to all ids.
+*/
+void QDS_ComboBox::setState( const bool on, const int id, const bool append )
+{
+  QValueList<int> lst;
+  if ( id < 0 )
+  {
+    for ( IdStateMap::Iterator it = myState.begin(); it != myState.end(); ++it )
+      lst.append( it.key() );
+  }
+  else
+    lst.append( id );
+
+  setState( on, lst, append );
+}
+
+/*!
+  Sets the visible state of identificator from the specified list.
+*/
+void QDS_ComboBox::setState( const bool on, const QValueList<int>& ids, const bool append )
+{
+  if ( ids.isEmpty() && append )
+    return;
+
+  bool changed = false;
+
+  QMap<int, int> aMap;
+  for ( uint i = 0; i < ids.count(); i++ )
+    aMap.insert( *ids.at( i ), 0 );
+
+  for ( IdStateMap::Iterator it = myState.begin(); it != myState.end(); ++it )
+  {
+    if ( aMap.contains( it.key() ) )
+    {
+      if ( it.data() != on )
+      {
+        it.data() = on;
+        changed = true;
+      }
+    }
+    else if ( !append && it.data() == on )
+    {
+      it.data() = !on;
+      changed = true;
+    }
+  }
+  if ( changed )
+    updateComboBox();
+}
+
+/*!
+  Sets the user items into the combo box.
+*/
+void QDS_ComboBox::setValues( const QValueList<int>& ids, const QStringList& names )
+{
+  if ( ids.count() != names.count() )
+    return;
+
+  myUserIds = ids;
+  myUserNames = names;
+}
+
+/*!
+  This is an overloaded member function, provided for convenience.
+  It behaves essentially like the above function. It creates
+  QValueList (0, 1, 2 ... ) and call previous method
+*/
+void QDS_ComboBox::setValues( const QStringList& names )
+{
+  QValueList< int > ids;
+  for ( int i = 0, n = names.count(); i < n; i++ )
+    ids.append( i );
+  setValues( ids, names );
+}
+
+/*!
+  Sets the active item as item with default id. If default
+  not defined then first item will be used.
+*/
+void QDS_ComboBox::reset()
+{
+  int id = -1;
+  QString aDefValue = defaultValue();
+  if ( !aDefValue.isEmpty() )
+    id = aDefValue.toInt();
+
+  if ( id == -1 )
+    id = getId( 0 );
+
+  setIntegerValue( id );
+}
+
+/*!
+  Returns identifier from given ComboBox string item.
+*/
+int QDS_ComboBox::stringToValue( const QString& str ) const
+{
+  return getId( str );
+}
+
+/*!
+  Returns ComboBox string item from given identifier.
+*/
+QString QDS_ComboBox::valueToString( const int val ) const
+{
+  QString str;
+  if ( myValue.contains( val ) )
+    str = myValue[val];
+  return str;
+}
+
+/*!
+  Returns string from QLineEdit widget.
+*/
+QString QDS_ComboBox::getString() const
+{
+  QString res;
+  QtxComboBox* cb = comboBox();
+  if ( cb )
+  {
+    if ( !cb->editable() )
+    {
+      if ( !cb->isCleared() )
+        res = cb->currentText(); 
+    }
+    else
+      res = cb->lineEdit()->text();
+  }
+  return res;
+}
+
+/*!
+  Sets the string into QLineEdit widget.
+*/
+void QDS_ComboBox::setString( const QString& txt )
+{
+  QtxComboBox* cb = comboBox();
+  if ( !cb )
+    return;
+
+  bool isClear = cb->isCleared();
+  
+  int idx = -1;
+  for ( int i = 0; i < cb->count() && idx == -1; i++ )
+    if ( cb->text( i ) == txt )
+      idx = i;
+
+  int old = cb->currentItem();
+  if ( idx != -1 )
+    cb->setCurrentItem( idx );
+  else if ( txt.isEmpty() )
+  {
+    if ( !cb->editable() )
+      cb->setCurrentText( txt );
+    else
+      cb->lineEdit()->setText( txt );
+  }
+  if ( isClear != txt.isEmpty() || ( !isClear && old != cb->currentItem() ) )
+  {
+    onParamChanged();
+    QString str = getString();
+    emit activated( integerValue() );
+    emit activated( str );
+    emit paramChanged();
+    emit paramChanged( str );
+  }
+}
+
+/*!
+  Returns pointer to QtxComboBox widget.
+*/
+QtxComboBox* QDS_ComboBox::comboBox() const
+{
+  return ::qt_cast<QtxComboBox*>( controlWidget() );
+}
+
+/*!
+  Create QComboBox widget as control subwidget.
+*/
+QWidget* QDS_ComboBox::createControl( QWidget* parent )
+{
+  QtxComboBox* cb = new QtxComboBox( parent );
+  cb->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ) );
+  connect( cb, SIGNAL( textChanged( const QString& ) ), this,
+           SLOT( onTextChanged( const QString& ) ) );
+  connect( cb, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
+  return cb;
+}
+
+void QDS_ComboBox::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  Handle(TColStd_HArray1OfInteger) anIds;
+  Handle(TColStd_HArray1OfExtendedString) aValues, anIcons;
+
+  Handle(DDS_DicItem) aDicItem = dicItem();
+  if ( !aDicItem.IsNull() )
+    aDicItem->GetListOfValues( aValues, anIds, anIcons );
+
+  myValue.clear();
+  myIcons.clear();
+  myDataIds.clear();
+
+  QMap<int, QString> userMap;
+  QIntList::iterator iIt = myUserIds.begin();
+  QStringList::iterator sIt = myUserNames.begin();
+  for ( ; iIt != myUserIds.end() && sIt != myUserNames.end(); ++iIt, ++sIt )
+    userMap.insert( *iIt, *sIt );
+
+  if ( !anIds.IsNull() && !aValues.IsNull() &&
+       anIds->Length() == aValues->Length() )
+  {
+    for ( int i = anIds->Lower(); i <= anIds->Upper(); i++ )
+    {
+      QString aValue;
+      QPixmap aPixmap;
+      int id = anIds->Value( i );
+      if ( userMap.contains( id  ) )
+        aValue = userMap[id];
+      else
+      {
+        aValue = toQString( aValues->Value( i ) );
+        if ( !anIcons.IsNull() && i <= anIcons->Upper() )
+        {
+          QString anIconId = toQString( anIcons->Value( i ) );
+          if ( anIconId != "" )
+            aPixmap = QPixmap( anIconId );
+        }
+      }
+
+      myDataIds.append( id );
+      myValue.insert( id, aValue );
+      myState.insert( id, true );
+      if ( !aPixmap.isNull() )
+        myIcons.insert( id, aPixmap );
+    }
+  }
+
+  for ( iIt = myUserIds.begin(); iIt != myUserIds.end(); ++iIt )
+  {
+    int id = *iIt;
+    if ( !myValue.contains( id  ) )
+    {
+      myDataIds.append( id );
+      myValue.insert( id, userMap[id] );
+    }
+  }
+
+  QIntList del, add;
+  for ( IdStateMap::Iterator it1 = myState.begin(); it1 != myState.end(); ++it1 )
+    if ( !myValue.contains( it1.key() ) )
+      del.append( it1.key() );
+
+  for ( IdValueMap::Iterator it2 = myValue.begin(); it2 != myValue.end(); ++it2 )
+    if ( !myState.contains( it2.key() ) )
+      add.append( it2.key() );
+
+  for ( QIntList::iterator iter1 = del.begin(); iter1 != del.end(); ++iter1 )
+    myState.remove( *iter1 );
+
+  for ( QIntList::iterator iter2 = add.begin(); iter2 != add.end(); ++iter2 )
+    myState.insert( *iter2, true );
+
+  updateComboBox();
+}
+
+/*!
+  Notify about text changing in line edit of ComboBox.
+*/
+void QDS_ComboBox::onTextChanged( const QString& )
+{
+  onParamChanged();
+  emit paramChanged();
+  QString str = getString();
+  emit paramChanged( str );
+}
+
+/*!
+  Notify about activation new item.
+*/
+void QDS_ComboBox::onActivated( int idx )
+{
+  if ( comboBox() )
+    comboBox()->setCurrentItem( comboBox()->currentItem() );
+
+  int id = getId( idx );
+  if ( id != -1 )
+  {
+    onParamChanged();
+    QString str = getString();
+    emit activated( id );
+    emit activated( str );
+    emit paramChanged();
+    emit paramChanged( str );
+  }
+}
+
+/*!
+  Updates ComboBox after have change of visible state or items have been inserted / removed.
+*/
+void QDS_ComboBox::updateComboBox()
+{
+  QtxComboBox* cb = comboBox();
+
+  int curId = -1;
+
+  bool isClear = false;
+
+  if ( cb )
+  {
+    isClear = cb->isCleared();
+
+    curId = getId( cb->currentItem() );
+    cb->clear();
+  }
+
+  myIndex.clear();
+
+  int idx = 0;
+  for ( QIntList::const_iterator it = myDataIds.begin(); it != myDataIds.end(); ++it )
+  {
+    int id = *it;
+    if ( !myValue.contains( id ) || !myState.contains( id ) || !myState[id] )
+      continue;
+
+    myIndex.insert( id, idx++ );
+    if ( cb )
+    {
+      if ( myIcons.contains( id ) )
+        cb->insertItem( myIcons[id], myValue[id] );
+      else
+        cb->insertItem( myValue[id] );
+    }
+  }
+
+  if ( cb && cb->count() )
+  {
+    cb->setFont( cb->font() );
+    cb->updateGeometry();
+
+    if ( isClear )
+      cb->setCurrentText( "" );
+    else
+    {
+      if ( getIndex( curId ) != -1 )
+        cb->setCurrentItem( getIndex( curId ) );
+      if ( curId != getId( cb->currentItem() ) )
+        onActivated( cb->currentItem() );
+    }
+  }
+}
+
+/*!
+  Returns index of ComboBox item according to id.
+*/
+int QDS_ComboBox::getIndex( const int id ) const
+{
+  int idx = -1;
+  if ( myIndex.contains( id ) )
+    idx = myIndex[id];
+  return idx;
+}
+
+/*!
+  Returns index of ComboBox item according to string.
+*/
+int QDS_ComboBox::getIndex( const QString& str ) const
+{
+  int idx = -1;
+  QComboBox* cb = comboBox();
+  if ( cb )
+  {
+    for ( int i = 0; i < cb->count() && idx == -1; i++ )
+      if ( cb->text( i ) == str )
+        idx = i;
+  }
+  return idx;
+}
+
+/*!
+  Returns id according to ComboBox item index.
+*/
+int QDS_ComboBox::getId( const int idx ) const
+{
+  int id = -1;
+  IdIndexMap::ConstIterator it = myIndex.begin();
+  for (; it != myIndex.end() && id == -1; ++it )
+    if ( it.data() == idx )
+      id = it.key();
+  return id;
+}
+
+/*!
+  Returns id according to ComboBox item string.
+*/
+int QDS_ComboBox::getId( const QString& str ) const
+{
+  int id = -1;
+  int candidate = -1;
+  IdValueMap::ConstIterator it = myValue.begin();
+  for (; it != myValue.end() && id == -1; ++it )
+  {
+    if ( it.data() == str )
+    {
+      if ( state( it.key() ) )
+        id = it.key();
+      else
+        candidate = it.key();
+    }
+  }
+  if ( id == -1 )
+    id = candidate;
+
+  return id;
+}
diff --git a/src/QDS/QDS_ComboBox.h b/src/QDS/QDS_ComboBox.h
new file mode 100644 (file)
index 0000000..9650f4c
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef QDS_COMBOBOX_H
+#define QDS_COMBOBOX_H
+
+#include "QDS_Datum.h"
+
+#include <qmap.h>
+#include <qpixmap.h>
+#include <qstringlist.h>
+
+#include <QtxComboBox.h>
+
+#ifdef WNT
+#pragma warning( disable:4251 )
+#endif
+
+class QDS_EXPORT QDS_ComboBox : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_ComboBox( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_ComboBox();
+
+  bool                       editable() const;
+  void                       setEditable( const bool );
+
+  int                        count( bool = false ) const;
+  void                       values( QValueList<int>&, bool = false ) const;
+
+  virtual int                integerValue() const;
+  virtual double             doubleValue() const;
+  virtual void               setIntegerValue( const int );
+  virtual void               setDoubleValue( const double );
+
+  bool                       state( const int ) const;
+  void                       setState( const bool, const int, const bool = true );
+  void                       setState( const bool, const QValueList<int>&, const bool = true );
+  void                       setValues( const QValueList<int>&, const QStringList& );
+  void                       setValues( const QStringList& );
+
+  virtual void               reset();
+
+  int                        stringToValue( const QString& ) const;
+  QString                    valueToString( const int ) const;
+
+signals:
+  void                       activated( int );
+  void                       activated( const QString& );
+
+protected slots:
+  virtual void               onActivated( int );
+  virtual void               onTextChanged( const QString& );
+
+protected:
+  QtxComboBox*               comboBox() const;
+  virtual QWidget*           createControl( QWidget* );
+
+  virtual QString            getString() const;
+  virtual void               setString( const QString& );
+
+  virtual void               unitSystemChanged( const QString& );
+
+private:
+  int                        getId( const int ) const;
+  int                        getId( const QString& ) const;
+  int                        getIndex( const int ) const;
+  int                        getIndex( const QString& ) const;
+
+  void                       updateComboBox();
+
+private:
+  typedef QMap<int, QPixmap> IdIconsMap;
+  typedef QMap<int, QString> IdValueMap;
+  typedef QMap<int, bool>    IdStateMap;
+  typedef QMap<int, int>     IdIndexMap;
+
+private:
+  IdValueMap                 myValue;
+  IdStateMap                 myState;
+  IdIndexMap                 myIndex;
+  IdIconsMap                 myIcons;
+
+  QIntList                   myDataIds;
+  QIntList                   myUserIds;
+  QStringList                myUserNames;
+};
+
+#ifdef WNT
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/QDS/QDS_Datum.cxx b/src/QDS/QDS_Datum.cxx
new file mode 100644 (file)
index 0000000..ff3ed8a
--- /dev/null
@@ -0,0 +1,1383 @@
+#include "QDS_Datum.h"
+
+#include "QDS_Validator.h"
+
+#include <DDS_Dictionary.h>
+
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qvalidator.h>
+#include <qmessagebox.h>
+
+/*!
+  Class: QDS_Datum::Wrapper
+  Descr: Wrapper widget for sub widgets. [internal]
+*/
+
+class QDS_Datum::Wrapper : public QWidget
+{
+public:
+  Wrapper( QWidget* = 0 );
+  virtual ~Wrapper();
+
+  QWidget*      widget() const;
+  void          setWidget( QWidget* );
+
+  virtual bool  eventFilter( QObject*, QEvent* );
+
+protected:
+  virtual void  resizeEvent( QResizeEvent* );
+
+private:
+  QWidget*      myWid;
+};
+
+
+QDS_Datum::Wrapper::Wrapper( QWidget* parent )
+: QWidget( parent ),
+myWid( 0 )
+{
+  QHBoxLayout* base = new QHBoxLayout( this );
+  base->setAutoAdd( true );
+}
+
+QDS_Datum::Wrapper::~Wrapper()
+{
+}
+
+QWidget* QDS_Datum::Wrapper::widget() const
+{
+  return myWid;
+}
+
+void QDS_Datum::Wrapper::setWidget( QWidget* wid )
+{
+  if ( myWid == wid )
+    return;
+
+  if ( myWid )
+    myWid->removeEventFilter( this );
+
+  myWid = wid;
+
+  if ( !myWid )
+    return;
+
+  if ( myWid->parent() != this )
+    myWid->reparent( this, QPoint( 0, 0 ) );
+
+  setFocusProxy( myWid );
+
+  myWid->updateGeometry();
+  updateGeometry();
+
+  myWid->installEventFilter( this );
+}
+
+bool QDS_Datum::Wrapper::eventFilter( QObject* o, QEvent* e )
+{
+  if ( e->type() == QEvent::Resize && o == widget() )
+  {
+    QResizeEvent* re = (QResizeEvent*)e;
+    if ( re->size() != size() )
+      resize( re->size() );
+  }
+  return QWidget::eventFilter( o, e );
+}
+
+void QDS_Datum::Wrapper::resizeEvent( QResizeEvent* e )
+{
+  QWidget::resizeEvent( e );
+
+  if ( widget() && widget()->size() != size() )
+    widget()->resize( size() );
+}
+
+/*!
+  Class: QDS_Datum
+  Descr: Base class for control used data dictionary. [public]
+*/
+
+QDS_Datum::QDS_Datum( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QObject( parent ),
+myId( id ),
+myLabel( 0 ),
+myUnits( 0 ),
+myControl( 0 ),
+myFlags( flags ),
+myInitialised( false )
+{
+  if ( myFlags & Label )
+    myWrapper.insert( Label, new Wrapper( parent ) );
+  if ( myFlags & Control )
+    myWrapper.insert( Control, new Wrapper( parent ) );
+  if ( myFlags & Units )
+    myWrapper.insert( Units, new Wrapper( parent ) );
+
+  for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
+    connect( it.data(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( aDict.IsNull() )
+    return;
+
+  TCollection_AsciiString anId = toAsciiString( id );
+  TCollection_AsciiString aComp = toAsciiString( comp );
+
+  if ( aComp.IsEmpty() )
+    setDicItem( aDict->GetDicItem( anId ) );
+  else
+    setDicItem( aDict->GetDicItem( anId, aComp ) );
+
+  QTimer::singleShot( 0, this, SLOT( onInitDatum() ) );
+
+  if ( parent )
+    parent->installEventFilter( this );
+
+  insertDatum( this );
+}
+
+QDS_Datum::~QDS_Datum()
+{
+  removeDatum( this );
+
+  delete myLabel;
+  delete myUnits;
+  delete myControl;
+/*
+  for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
+    delete it.data();
+*/
+}
+
+QString QDS_Datum::id() const
+{
+  initDatum();
+
+  return myId;
+}
+
+int QDS_Datum::type() const
+{
+  initDatum();
+
+  int res = DDS_DicItem::Unknown;
+  if ( !myDicItem.IsNull() )
+    res = myDicItem->GetType();
+  return res;
+}
+
+QString QDS_Datum::label() const
+{
+  initDatum();
+
+  QString labStr;
+  if ( !myDicItem.IsNull() )
+    labStr = toQString( myDicItem->GetLabel() );
+
+  if ( flags() & NotAccel )
+    labStr = removeAccel( labStr );
+
+  return labStr;
+}
+
+QString QDS_Datum::units() const
+{
+  initDatum();
+
+  QString unitStr;
+  if ( !myDicItem.IsNull() )
+    unitStr = toQString( myDicItem->GetUnits() );
+  return unitStr;
+}
+
+QString QDS_Datum::filter() const
+{
+  initDatum();
+
+  QString fltr;
+  if ( !myDicItem.IsNull() )
+    fltr = toQString( myDicItem->GetFilter() );
+  return fltr;
+}
+
+QString QDS_Datum::format() const
+{
+  initDatum();
+
+  QString fmtStr;
+  if ( !myDicItem.IsNull() )
+    fmtStr = toQString( myDicItem->GetFormat( false ) );
+  return fmtStr;
+}
+
+QString QDS_Datum::defaultValue() const
+{
+  initDatum();
+
+  QString pref = prefix();
+  QString suff = suffix();
+
+  QString def;
+  if ( !myDicItem.IsNull() )
+    def = toQString( myDicItem->GetDefaultValue() );
+
+  QString aDef = def.stripWhiteSpace();
+  if ( !pref.isEmpty() && aDef.left( pref.length() ) == pref )
+    aDef = aDef.mid( pref.length() );
+
+  if ( !suff.isEmpty() && aDef.right( suff.length() ) == suff )
+    aDef = aDef.mid( 0, aDef.length() - suff.length() );
+
+  return aDef;
+}
+
+QString QDS_Datum::minimumValue() const
+{
+  initDatum();
+
+  QString min;
+  if ( !myDicItem.IsNull() )
+    min = format( format(), type(), myDicItem->GetMinValue() );
+  return min;
+}
+
+QString QDS_Datum::maximumValue() const
+{
+  initDatum();
+
+  QString max;
+  if ( !myDicItem.IsNull() )
+    max = format( format(), type(), myDicItem->GetMaxValue() );
+  return max;
+}
+
+QString QDS_Datum::longDescription() const
+{
+  initDatum();
+
+  QString ldStr;
+  if ( !myDicItem.IsNull() )
+    ldStr = toQString( myDicItem->GetLongDescription() );
+  return ldStr;
+}
+
+QString QDS_Datum::shortDescription() const
+{
+  initDatum();
+
+  QString sdStr;
+  if ( !myDicItem.IsNull() )
+    sdStr = toQString( myDicItem->GetLongDescription() );
+  return sdStr;
+}
+
+QString QDS_Datum::stringValue() const
+{
+  initDatum();
+
+  if ( getString() == myTargetValue )
+    return mySourceValue;
+  else
+    return getString();
+}
+
+double QDS_Datum::doubleValue() const
+{
+  initDatum();
+
+  double res = 0;
+  if ( !myTargetValue.isNull() && myTargetValue == getString() )
+    res = mySourceValue.toDouble();
+  else
+  {
+    res = getString().toDouble();
+    if ( !myDicItem.IsNull() )
+      res = myDicItem->ToSI( res );
+  }
+
+  return res;
+}
+
+int QDS_Datum::integerValue() const
+{
+  initDatum();
+
+  int res = 0;
+  if ( !myTargetValue.isNull() && myTargetValue == getString() )
+    res = mySourceValue.toInt();
+  else
+  {
+    double val = getString().toDouble();
+    if ( !myDicItem.IsNull() )
+      res = (int)myDicItem->ToSI( val );
+  }
+
+  return res;
+}
+
+QString QDS_Datum::text() const
+{
+  initDatum();
+
+  QString aLabel = label();
+  QString aData  = stringValue();
+  QString aUnits = units();
+
+  QString res = aLabel;
+  if ( !res.isEmpty() && !aData.isEmpty() )
+    res += QString( ": " );
+
+  res += aData;
+  if ( !aUnits.isEmpty() )
+    res += QString( " " ) + aUnits;
+
+  return res;
+}
+
+bool QDS_Datum::isEmpty() const
+{
+  return stringValue().isEmpty();
+}
+
+void QDS_Datum::reset()
+{
+  initDatum();
+
+  mySourceValue = defaultValue();
+  setString( format( ( myFlags & NotFormat ) ? (QString) "" : format(), type(), mySourceValue ) );
+  invalidateCache();
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+void QDS_Datum::clear()
+{
+  initDatum();
+
+  if ( !getString().isEmpty() )
+  {
+    mySourceValue = "";
+    setString( mySourceValue );
+    invalidateCache();
+
+    onParamChanged();
+    QString str = getString();
+    emit paramChanged();
+    emit paramChanged( str );
+  }
+}
+
+void QDS_Datum::setStringValue( const QString& txt )
+{
+  initDatum();
+
+  mySourceValue = txt;
+  QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), txt );
+  setString( aStr );
+  myTargetValue = aStr;
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+void QDS_Datum::setDoubleValue( const double num )
+{
+  initDatum();
+
+  mySourceValue = QString().setNum( num, 'g', 16 );
+  double val = num;
+  if ( !myDicItem.IsNull() )
+    val = myDicItem->FromSI( val );
+
+  QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
+  setString( aStr );
+  myTargetValue = aStr;
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+void QDS_Datum::setIntegerValue( const int num )
+{
+  initDatum();
+
+  mySourceValue = QString().setNum( num );
+  double val = num;
+  if ( !myDicItem.IsNull() )
+    val = myDicItem->FromSI( val );
+
+  QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
+  setString( aStr );
+  myTargetValue = aStr;
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Returns true if all subwidgets specified by 'element' enabled.
+*/
+bool QDS_Datum::isEnabled( const int element ) const
+{
+  initDatum();
+
+  bool res = true;
+  if ( element & Label )
+    res = res && labelWidget() && labelWidget()->isEnabled();
+  if ( element & Units )
+    res = res && unitsWidget() && unitsWidget()->isEnabled();
+  if ( element & Control )
+    res = res && controlWidget() && controlWidget()->isEnabled();
+  return res;
+}
+
+/*!
+  Enable/Disable subwidgets specified by 'element'.
+  Values: Label, Control, Units or their combinations.
+*/
+void QDS_Datum::setEnabled( const bool on, const int element )
+{
+  initDatum();
+
+  if ( element & Label && labelWidget() )
+    labelWidget()->setEnabled( on );
+  if ( element & Units && unitsWidget() )
+    unitsWidget()->setEnabled( on );
+  if ( element & Control && controlWidget() )
+    controlWidget()->setEnabled( on );
+}
+
+/*!
+  Enable/Disable control.
+*/
+void QDS_Datum::setEnabled( bool on )
+{
+  setEnabled( on, Control );
+}
+
+void QDS_Datum::setShown( const bool visible, const int flags )
+{
+  if ( visible )
+    show( flags );
+  else
+    hide( flags );
+}
+
+/*!
+  Show subwidgets specified by 'element'.
+  Values: Label, Control, Units or their combinations.
+*/
+void QDS_Datum::show( const int element )
+{
+  initDatum();
+
+  if ( ( element & Label ) && labelWidget() )
+    labelWidget()->show();
+  if ( ( element & Units ) && unitsWidget() )
+    unitsWidget()->show();
+  if ( ( element & Control ) && controlWidget() )
+    controlWidget()->show();
+}
+
+/*!
+  Hide subwidgets specified by 'element'.
+  Values: Label, Control, Units or their combinations.
+*/
+void QDS_Datum::hide( const int element )
+{
+  initDatum();
+
+  if ( ( element & Label ) && labelWidget() )
+    labelWidget()->hide();
+  if ( ( element & Units ) && unitsWidget() )
+    unitsWidget()->hide();
+  if ( ( element & Control ) && controlWidget() )
+    controlWidget()->hide();
+}
+
+/*!
+  Returns subwidget specified by 'element'.
+  Possible values: Label, Control, Units.
+*/
+QWidget* QDS_Datum::widget( const int element ) const
+{
+  initDatum();
+  return wrapper( element );
+}
+
+/*!
+  Set the input focus on the control widget.
+*/
+void QDS_Datum::setFocus()
+{
+  initDatum();
+
+  if ( controlWidget() )
+    controlWidget()->setFocus();
+}
+
+/*!
+  Returns true if control contains valid value otherwise returns false
+  and display warning message box if parameter msgBox is set.
+*/
+bool QDS_Datum::isValid( const bool msgBox, const QString& extMsg, const QString& extLabel ) const
+{
+  initDatum();
+
+  if ( type() == DDS_DicItem::String && isDoubleFormat( format() ) )
+    return true;
+
+  bool aState = true;
+  QString aStr = getString();
+  if ( aStr.isEmpty() )
+    aState = false;
+  else
+    aState = validate( aStr );
+
+  if ( msgBox && !aState )
+  {
+    QString info;
+    if ( !label().isEmpty() )
+      info += tr( "DATA_INCORRECT_VALUE" ).arg( label() );
+    else if ( !extLabel.isEmpty() )
+      info += tr( "DATA_INCORRECT_VALUE" ).arg( extLabel );
+
+    QString typeStr;
+    switch ( type() )
+    {
+    case DDS_DicItem::String:
+      typeStr = tr( "DATA_STRING" );
+      break;
+    case DDS_DicItem::Integer:
+      typeStr = tr( "DATA_INTEGER" );
+      break;
+    case DDS_DicItem::Float:
+      typeStr = tr( "DATA_FLOAT" );
+      break;
+    default:
+      typeStr = tr( "DATA_NON_EMPTY" );
+      break;
+    }
+    info += ( info.isEmpty() ? (QString) "" : QString( "\n" ) ) + 
+            tr( "DATA_SHOULD_BE_VALUE" ).arg( typeStr );
+    QString limit;
+    if ( type() == DDS_DicItem::Float || type() == DDS_DicItem::Integer )
+    {
+      QString aMinValue = minValue();
+      QString aMaxValue = maxValue();
+      if ( !aMinValue.isEmpty() && !aMaxValue.isEmpty() )
+        limit = tr( "DATA_RANGE" ).arg( aMinValue ).arg( aMaxValue );
+      else if ( !aMinValue.isEmpty() )
+        limit = tr( "DATA_MIN_LIMIT" ).arg( aMinValue );
+      else if ( !aMaxValue.isEmpty() )
+        limit = tr( "DATA_MAX_LIMIT" ).arg( aMaxValue );
+    }
+    if ( !limit.isEmpty() )
+      info += limit;
+
+    info += QString( ".\n" ) + tr( "DATA_INPUT_VALUE" );
+
+    if ( !extMsg.isEmpty() )
+      info += QString( "\n" ) + extMsg;
+
+    QString msg;
+    for ( uint i = 0; i < info.length(); i++ )
+      if ( info.at( i ) == '\n' )
+        msg += QString( "<br>" );
+      else
+        msg += info.at( i );
+
+    info = QString( "<p><nobr>%1</nobr></p>" ).arg( msg );
+
+    QMessageBox::critical( controlWidget() ? controlWidget()->topLevelWidget() : 0,
+                           tr( "DATA_ERR_TITLE" ), info, tr( "BUT_OK" ) );
+    if ( controlWidget() )
+      controlWidget()->setFocus();
+  }
+  return aState;
+}
+
+/*!
+  Add widgets to the vertical layout.
+*/
+void QDS_Datum::addTo( QVBoxLayout* l )
+{
+  initDatum();
+
+  if ( !l )
+    return;
+
+  if ( wrapper( Label ) )
+    l->addWidget( wrapper( Label ) );
+  if ( wrapper( Control ) )
+    l->addWidget( wrapper( Control ) );
+  if ( wrapper( Units ) )
+    l->addWidget( wrapper( Units ) );
+}
+
+/*!
+  Add widgets to the horizaontal layout.
+*/
+void QDS_Datum::addTo( QHBoxLayout* l )
+{
+  initDatum();
+
+  if ( !l )
+    return;
+
+  if ( wrapper( Label ) )
+    l->addWidget( wrapper( Label ) );
+  if ( wrapper( Control ) )
+    l->addWidget( wrapper( Control ) );
+  if ( wrapper( Units ) )
+    l->addWidget( unitsWidget() );
+}
+
+/*!
+  Add widgets to the grid layout.
+*/
+void QDS_Datum::addTo( QGridLayout* theLay, const int theRow, const int theCol, bool vertical )
+{
+  initDatum();
+
+  if ( !theLay )
+    return;
+
+  int row = theRow;
+  int col = theCol;
+  if ( wrapper( Label ) )
+  {
+    theLay->addWidget( wrapper( Label ), row, col );
+    vertical ? row++ : col++;
+  }
+  if ( wrapper( Control ) )
+  {
+    theLay->addWidget( wrapper( Control ), row, col );
+    vertical ? row++ : col++;
+  }
+  if ( wrapper( Units ) )
+    theLay->addWidget( wrapper( Units ), row, col );
+}
+
+/*!
+  Set the aligment of Label or Units. For Control nothing happens.
+*/
+void QDS_Datum::setAlignment( const int align, const int type )
+{
+  initDatum();
+
+  if ( ( type & Label ) && labelWidget() )
+    labelWidget()->setAlignment( align );
+  if ( ( type & Units ) && unitsWidget() )
+    unitsWidget()->setAlignment( align );
+}
+
+bool QDS_Datum::eventFilter( QObject* o, QEvent* e )
+{
+  if ( o == parent() )
+  {
+    if ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
+         ( e->type() == QEvent::ChildInserted && ((QChildEvent*)e)->child() == this ) )
+      initDatum();
+  }
+  return QObject::eventFilter( o, e );
+}
+
+/*!
+  Notify about parameter changing.
+*/
+void QDS_Datum::onParamChanged()
+{
+}
+
+/*!
+  Delayed initialization.
+*/
+void QDS_Datum::onInitDatum()
+{
+  initDatum();
+}
+
+/*!
+  Notify about subwidgets destroying. Allow to avoid repeated deleting in destructor.
+*/
+void QDS_Datum::onDestroyed( QObject* obj )
+{
+  myWrapper.remove( wrapperType( (Wrapper*)obj ) );
+}
+
+/*!
+  Returns QLabel instance which contains data dictionary label.
+*/
+QLabel* QDS_Datum::labelWidget() const
+{
+  initDatum();
+  return myLabel;
+}
+
+/*!
+  Returns QLabel instance which contains data dictionary units.
+*/
+QLabel* QDS_Datum::unitsWidget() const
+{
+  initDatum();
+  return myUnits;
+}
+
+/*!
+  Returns QWidget which contains user input data.
+*/
+QWidget* QDS_Datum::controlWidget() const
+{
+  initDatum();
+  return myControl;
+}
+
+/*!
+  Returns the dictionary item from the datum.
+*/
+Handle(DDS_DicItem) QDS_Datum::dicItem() const
+{
+  return myDicItem;
+}
+
+/*!
+  Set the dictionary item in to the datum.
+*/
+void QDS_Datum::setDicItem( const Handle(DDS_DicItem)& item )
+{
+  myDicItem = item;
+}
+
+/*!
+  Creates QLabel widget for data label.
+*/
+QLabel* QDS_Datum::createLabel( QWidget* parent )
+{
+  return new QLabel( parent );
+}
+
+/*!
+  Creates QLabel widget for data units.
+*/
+QLabel* QDS_Datum::createUnits( QWidget* parent )
+{
+  return new QLabel( parent );
+}
+
+/*!
+  Returns validator accordance to data type.
+*/
+QValidator* QDS_Datum::validator( const bool limits ) const
+{
+  QValidator* aValidator = 0;
+
+  QString fltr = filter();
+
+  if ( type() == DDS_DicItem::String )
+  {
+    QString aFlags;
+    QString aFormat = canonicalFormat( format(), aFlags );
+
+    int len = -1;
+    int pos = aFormat.find( "." );
+    if ( pos != -1 )
+    {
+      QString numStr = aFormat.mid( pos + 1, aFormat.length() - pos - 2 );
+      bool ok;
+      int numVal = numStr.toInt( &ok );
+      if ( ok )
+        len = numVal;
+    }
+
+    QDS_StringValidator* aStrVal = new QDS_StringValidator( fltr, aFlags, (QObject*)this );
+    aStrVal->setLength( len );
+
+    aValidator = aStrVal;
+  }
+  else if ( type() == DDS_DicItem::Integer )
+  {
+    QDS_IntegerValidator* aIntVal = new QDS_IntegerValidator( fltr, (QObject*)this );
+
+    bool ok;
+    int limit;
+    limit = minValue().toInt( &ok );
+    if ( ok && limits )
+      aIntVal->setBottom( limit );
+    limit = maxValue().toInt( &ok );
+    if ( ok && limits )
+      aIntVal->setTop( limit );
+
+    aValidator = aIntVal;
+  }
+  else if ( type() == DDS_DicItem::Float )
+  {
+    QDS_DoubleValidator* aFloatVal = new QDS_DoubleValidator( fltr, (QObject*)this );
+
+    bool ok;
+    double limit;
+    limit = minValue().toDouble( &ok );
+    if ( ok && limits )
+      aFloatVal->setBottom( limit );
+    limit = maxValue().toDouble( &ok );
+    if ( ok && limits )
+      aFloatVal->setTop( limit );
+
+    aValidator = aFloatVal;
+  }
+
+  return aValidator;
+}
+
+/*!
+  Checks the given string are valid or not.
+*/
+bool QDS_Datum::validate( const QString& txt ) const
+{
+  if ( type() == DDS_DicItem::Unknown ||
+       type() == DDS_DicItem::String && isDoubleFormat( format() ) )
+    return true;
+
+  QValidator* aValidator = validator( true );
+
+  if ( !aValidator )
+    return true;
+
+  int pos = 0;
+  QString str( txt );
+  bool res = aValidator->validate( str, pos ) == QValidator::Acceptable;
+
+  delete aValidator;
+
+  return res;
+}
+
+/*!
+  Retrieves information from data dictionary and create subwidgets using virtual mechanism.
+  Virtual mechanism doesn't work in constructor and destructor, therefore this method should
+  be called outside the constructor.
+*/
+void QDS_Datum::initialize()
+{
+  if ( wrapper( Label ) )
+    wrapper( Label )->setWidget( myLabel = createLabel( wrapper( Label ) ) );
+  if ( wrapper( Control ) )
+    wrapper( Control )->setWidget( myControl = createControl( wrapper( Control ) ) );
+  if ( wrapper( Units ) )
+    wrapper( Units )->setWidget( myUnits = createUnits( wrapper( Units ) ) );
+
+  TCollection_AsciiString comp;
+  Handle(DDS_DicItem) item = dicItem();
+  if ( !item.IsNull() )
+    comp = item->GetComponent();
+
+  QString unitSystem;
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( !dic.IsNull() )
+    unitSystem = toQString( comp.IsEmpty() ? dic->GetActiveUnitSystem() :
+                                             dic->GetActiveUnitSystem( comp ) );
+
+  unitSystemChanged( unitSystem );
+
+  QWidget* ctrl = controlWidget();
+  if ( ctrl )
+  {
+    QString lDescr = longDescription();
+    QString sDescr = shortDescription();
+    if ( !sDescr.isEmpty() )
+      QToolTip::add( ctrl, sDescr );
+    if ( !lDescr.isEmpty() )
+      QWhatsThis::add( ctrl, lDescr );
+  }
+
+  if ( labelWidget() && ctrl && !( flags() & NotAccel ) )
+    labelWidget()->setBuddy( ctrl );
+}
+
+void QDS_Datum::unitSystemChanged( const QString& unitSystem )
+{
+  QString labText = label();
+  QString unitText = unitsToText( units() );
+
+  if ( flags() & UnitsWithLabel )
+  {
+    if ( labText.isEmpty() )
+      labText = unitText;
+    else if ( !unitText.isEmpty() )
+      labText = QString( "%1 (%2)" ).arg( labText ).arg( unitText );
+    unitText = QString::null;
+  }
+
+  if ( labelWidget() )
+    labelWidget()->setText( labText );
+
+  if ( unitsWidget() )
+    unitsWidget()->setText( unitText );
+
+  reset();
+}
+
+/*!
+  Covert units into text presentation.
+*/
+QString QDS_Datum::unitsToText( const QString& uni )
+{
+  int pos = -1;
+  QString aUnits = uni;
+  while ( ( pos = aUnits.find( "**" ) ) != -1 )
+  {
+    aUnits = aUnits.mid( 0, pos ) + QString( "<tt><font size=+2><sup>" ) +
+             aUnits.mid( pos + 2, 1 ) + QString( "</sup></font></tt>" ) +
+             aUnits.mid( pos + 3 );
+  }
+  return aUnits;
+}
+
+/*!
+  Covert text presentation into internal units format.
+*/
+QString QDS_Datum::textToUnits( const QString& txt )
+{
+  int pos = -1;
+  QString aUnits = txt;
+  while ( ( pos = aUnits.find( "<sup>" ) ) != -1 )
+  {
+    aUnits.remove( pos, 5 );
+    aUnits.insert( pos, "**" );
+  }
+  while ( ( pos = aUnits.find( "</sup>" ) ) != -1 )
+    aUnits.remove( pos, 6 );
+  return aUnits;
+}
+
+/*!
+  Format the specified integer as data dictionary value.
+*/
+QString QDS_Datum::format( const int num, const QString& id, const bool convert )
+{
+  Handle(DDS_DicItem) anItem;
+  int aNum = num;
+  QString anUnit;
+  
+  QString aFormat;
+  int aType = DDS_DicItem::Unknown;
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+    {
+      aType = anItem->GetType();
+      aFormat = toQString( anItem->GetFormat( false ) );
+      if ( convert )
+        aNum = ( int )anItem->FromSI( aNum );
+    }
+  }
+
+  return format( aFormat, aType, aNum );
+}
+
+/*!
+  Format the specified double as data dictionary value.
+*/
+QString QDS_Datum::format( const double num, const QString& id, const bool convert )
+{
+  Handle(DDS_DicItem) anItem;
+  double aNum = num;
+  QString anUnit;
+  
+  QString aFormat;
+  int aType = DDS_DicItem::Unknown;
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+    {
+      aType = anItem->GetType();
+      aFormat = toQString( anItem->GetFormat( false ) );
+      if ( convert )
+        aNum = anItem->FromSI( aNum );
+    }
+  }
+
+  return format( aFormat, aType, aNum );
+}
+
+/*!
+  Format the specified string as data dictionary value.
+*/
+QString QDS_Datum::format( const QString& str, const QString& id, const bool convert )
+{
+  Handle(DDS_DicItem) anItem;
+  QString aStr = str;
+  QString anUnit;
+
+  QString aFormat;
+  int aType = DDS_DicItem::Unknown;
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+    {
+      aType = anItem->GetType();
+      aFormat = toQString( anItem->GetFormat( false ) );
+      if ( convert )
+        aStr = QString::number( anItem->FromSI( aStr.toDouble() ), 'f', 16 );
+    }
+  }
+
+  return format( aFormat, aType, aStr );
+}
+
+/*!
+  Format the given string accordance to data format.
+*/
+QString QDS_Datum::format( const QString& aFormat, const int aType, const int aValue )
+{
+  QString txt;
+
+  if ( !aFormat.isEmpty() )
+  {
+    switch ( aType )
+    {
+    case DDS_DicItem::Float:
+      txt = sprintf( aFormat, (double)aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::Integer:
+      txt = sprintf( aFormat, aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::String:
+    default:
+      txt = sprintf( aFormat, aValue );
+      break;
+    }
+  }
+  else
+    txt = QString().setNum( aValue );
+
+  return txt;
+}
+
+/*!
+  Format the given string accordance to data format.
+*/
+QString QDS_Datum::format( const QString& aFormat, const int aType, const double aValue )
+{
+  QString txt;
+
+  if ( !aFormat.isEmpty() )
+  {
+    switch ( aType )
+    {
+    case DDS_DicItem::Float:
+      txt = QString().sprintf( aFormat, aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::Integer:
+      txt = QString().sprintf( aFormat, (int)aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::String:
+    default:
+      txt = QString().sprintf( aFormat, aValue );
+      break;
+    }
+  }
+  else
+    txt = QString().setNum( aValue, 'g', 16 );
+
+  return txt;
+}
+
+/*!
+  Format the given string accordance to data format.
+*/
+QString QDS_Datum::format( const QString& aFormat, const int aType, const QString& aValue )
+{
+  QString txt = aValue;
+
+  if ( aType != DDS_DicItem::String )
+    txt = txt.stripWhiteSpace();
+
+  if ( aFormat.isEmpty() || txt.isEmpty() )
+    return txt;
+
+  switch ( aType )
+  {
+  case DDS_DicItem::Float:
+    txt = txt.replace( 'd', 'e' ).replace( 'D', 'E' );
+    txt = sprintf( aFormat, txt.toDouble() );
+    txt = txt.stripWhiteSpace();
+    break;
+  case DDS_DicItem::Integer:
+    txt = sprintf( aFormat, txt.toInt() );
+    txt = txt.stripWhiteSpace();
+    break;
+  case DDS_DicItem::String:
+    txt = sprintf( aFormat, txt );
+    break;
+  }
+
+  return txt;
+}
+
+/*!
+  Wrapper around the standard sprintf function.
+  Process some non standard flags from format string.
+*/
+QString QDS_Datum::sprintf( const QString& fmt, const int val )
+{
+  return QString().sprintf( canonicalFormat( fmt ), val );
+}
+
+/*!
+  Wrapper around the standard sprintf function.
+  Process some non standard flags from format string.
+*/
+QString QDS_Datum::sprintf( const QString& fmt, const double val )
+{
+  return QString().sprintf( canonicalFormat( fmt ), val );
+}
+
+/*!
+  Wrapper around the standard sprintf function.
+  Process some non standard flags from format string.
+*/
+QString QDS_Datum::sprintf( const QString& fmt, const QString& val )
+{
+  QString aFlags;
+  QString aFormat = canonicalFormat( fmt, aFlags );
+
+  QString txt = val;
+
+  QRegExp rx( "^(%[0-9]*.?[0-9]*s)$" );
+  if ( aFormat.find( rx ) != -1 )
+  {
+    // QString().sprintf() always expects string in UTF8 encoding, so we cannot use it here
+    char* buf = new char[txt.length() + 1];
+    ::sprintf( buf, aFormat.latin1(), (const char*)(txt.local8Bit()) );
+    txt = QString::fromLocal8Bit( buf );
+
+    delete[] buf;
+  }
+
+  if ( isDoubleFormat( aFormat ) )
+  {
+    /*bool isOk;
+    double aVal = txt.toDouble( &isOk );
+    if ( isOk )
+    {
+      txt = sprintf( aFormat, aVal );
+      txt = txt.replace( 'e', 'D' );
+    }*/
+  }
+
+  if ( aFlags.contains( "u", false ) )
+    txt = txt.upper();
+  if ( aFlags.contains( "l", false ) )
+    txt = txt.lower();
+
+  return txt;
+}
+
+/*!
+  Returns the canonical sprintf format.
+*/
+QString QDS_Datum::canonicalFormat( const QString& fmt )
+{
+  QString flags;
+  return canonicalFormat( fmt, flags );
+}
+
+/*!
+  Returns the canonical sprintf format and non standard flags.
+*/
+QString QDS_Datum::canonicalFormat( const QString& fmt, QString& flags )
+{
+  QString newFmt = fmt;
+  flags = QString::null;
+
+  QRegExp rx( "^(%[0-9]*.?[0-9]*)([a-z,A-Z]+)[g|c|d|i|o|u|x|e|f|n|p|s|X|E|G]$" );
+  if ( rx.search( newFmt ) >= 0 )
+  {
+    flags = rx.cap( 2 );
+    newFmt.remove( rx.pos( 2 ), flags.length() );
+  }
+  return newFmt;
+}
+
+/*!
+  Returns displayable units string for given DD ID
+*/
+QString QDS_Datum::units( const QString& id )
+{
+  QString anUnit;
+  Handle(DDS_DicItem) anItem;
+
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+      anUnit = unitsToText( toQString( anItem->GetUnits() ) );
+  }
+  return anUnit;
+}
+
+/*!
+  Get prefix string from format.
+*/
+QString QDS_Datum::prefix() const
+{
+  return QString::null;
+}
+
+/*!
+  Get suffix string from format.
+*/
+QString QDS_Datum::suffix() const
+{
+  return QString::null;
+}
+
+/*!
+  Get min value.
+*/
+QString QDS_Datum::minValue() const
+{
+  QString pref = prefix();
+  QString suff = suffix();
+
+  QString aMin = minimumValue().stripWhiteSpace();
+
+  if ( !pref.isEmpty() && aMin.left( pref.length() ) == pref )
+    aMin = aMin.mid( pref.length() );
+
+  if ( !suff.isEmpty() && aMin.right( suff.length() ) == suff )
+    aMin = aMin.mid( 0, aMin.length() - suff.length() );
+
+  return aMin;
+}
+
+/*!
+  Get max value.
+*/
+QString QDS_Datum::maxValue() const
+{
+  QString pref = prefix();
+  QString suff = suffix();
+
+  QString aMax = maximumValue().stripWhiteSpace();
+
+  if ( !pref.isEmpty() && aMax.left( pref.length() ) == pref )
+    aMax = aMax.mid( pref.length() );
+
+  if ( !suff.isEmpty() && aMax.right( suff.length() ) == suff )
+    aMax = aMax.mid( 0, aMax.length() - suff.length() );
+
+  return aMax;
+}
+
+/*!
+  Reset the numeric value cache.
+*/
+void QDS_Datum::invalidateCache()
+{
+  myTargetValue = QString::null;
+}
+
+QString QDS_Datum::removeAccel( const QString& src )
+{
+  QString trg = src;
+
+  for ( uint i = 0; i < trg.length(); )
+  {
+    if ( trg.mid( i, 2 ) == QString( "&&" ) )
+      i += 2;
+    else if ( trg.at( i ) == '&' )
+      trg.remove( i, 1 );
+    else
+      i++;
+  }
+  return trg;
+}
+
+bool QDS_Datum::isDoubleFormat( const QString& theFormat )
+{
+  if ( theFormat.length() > 0 )
+  {
+    QChar c = theFormat[ (int)( theFormat.length() - 1 ) ];
+      return c == 'f' || c == 'g' || c == 'e' || c == 'G' || c == 'E';
+  }
+  else
+    return false;
+}
+
+int QDS_Datum::flags() const
+{
+  return myFlags;
+}
+
+void QDS_Datum::initDatum() const
+{
+  if ( myInitialised )
+    return;
+
+  QDS_Datum* that = (QDS_Datum*)this;
+  that->myInitialised = true;
+  that->initialize();
+
+  if ( parent() )
+    parent()->removeEventFilter( this );
+}
+
+QDS_Datum::Wrapper* QDS_Datum::wrapper( QWidget* wid ) const
+{
+  if ( !wid )
+    return 0;
+
+  Wrapper* wrap = 0;
+  for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && !wrap; ++it )
+  {
+    if ( it.data() && it.data()->widget() == wid )
+      wrap = it.data();
+  }
+  return wrap;
+}
+
+QDS_Datum::Wrapper* QDS_Datum::wrapper( const int id ) const
+{
+  Wrapper* wrap = 0;
+  if ( myWrapper.contains( id ) )
+    wrap = myWrapper[id];
+  return wrap;
+}
+
+int QDS_Datum::wrapperType( QDS_Datum::Wrapper* wrap ) const
+{
+  int id = -1;
+  for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && id == -1; ++it )
+  {
+    if ( it.data() == wrap )
+      id = it.key();
+  }
+  return id;
+}
diff --git a/src/QDS/QDS_Datum.h b/src/QDS/QDS_Datum.h
new file mode 100644 (file)
index 0000000..be02474
--- /dev/null
@@ -0,0 +1,175 @@
+#ifndef QDS_DATUM_H
+#define QDS_DATUM_H
+
+#include "QDS.h"
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qguardedptr.h>
+
+#include <DDS_DicItem.h>
+
+class QLabel;
+class QWidget;
+class QValidator;
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+
+class Handle(DDS_Dictionary);
+
+class QDS_EXPORT QDS_Datum : public QObject, public QDS
+{
+  Q_OBJECT
+
+  class Wrapper;
+
+public:
+  QDS_Datum( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_Datum();
+
+  QString                   id() const;
+  int                       type() const;
+  QString                   label() const;
+  QString                   units() const;
+  QString                   filter() const;
+  QString                   format() const;
+  QString                   longDescription() const;
+  QString                   shortDescription() const;
+
+  QString                   defaultValue() const;
+  QString                   minimumValue() const;
+  QString                   maximumValue() const;
+
+  virtual QString           stringValue() const;
+  virtual double            doubleValue() const;
+  virtual int               integerValue() const;
+
+  QString                   text() const;
+
+  virtual bool              isEmpty() const;
+
+  virtual void              reset();
+  virtual void              clear();
+
+  virtual void              setStringValue( const QString& );
+  virtual void              setDoubleValue( const double );
+  virtual void              setIntegerValue( const int );
+
+  virtual bool              isEnabled( const int = Control ) const;
+  virtual void              setEnabled( const bool, const int );
+
+  void                      show( const int = -1 );
+  void                      hide( const int = -1 );
+  void                      setShown( const bool, const int = -1 );
+
+  QWidget*                  widget( const int ) const;
+  void                      setFocus();
+
+  virtual bool              isValid( const bool = true, 
+                                     const QString& = QString::null,
+                                     const QString& = QString::null ) const;
+  virtual QValidator*       validator( const bool = false ) const;
+
+  void                      addTo( QVBoxLayout* );
+  void                      addTo( QHBoxLayout* );
+  void                      addTo( QGridLayout*, const int, const int, const bool = false );
+
+  virtual void              setAlignment( const int, const int = Label );
+
+  static QString            unitsToText( const QString& );
+  static QString            textToUnits( const QString& );
+
+  static QString            format( const QString&, const QString&, const bool = false );
+  static QString            format( const int, const QString&, const bool = false );
+  static QString            format( const double, const QString&, const bool = false );
+  static QString            units( const QString& );
+
+  virtual bool              eventFilter( QObject*, QEvent* );
+
+signals:
+  void                      paramChanged();
+  void                      paramChanged( QString& );
+
+public slots:
+  void                      setEnabled( bool );
+
+protected slots:
+  virtual void              onParamChanged();
+
+private slots:
+  void                      onInitDatum();
+  void                      onDestroyed( QObject* );
+
+protected:
+  QLabel*                   labelWidget() const;
+  QLabel*                   unitsWidget() const;
+  QWidget*                  controlWidget() const;
+
+  Handle(DDS_DicItem)       dicItem() const;
+  void                      setDicItem( const Handle(DDS_DicItem)& );
+
+  int                       flags() const;
+
+  void                      invalidateCache();
+
+  virtual QLabel*           createLabel( QWidget* );
+  virtual QLabel*           createUnits( QWidget* );
+  virtual QWidget*          createControl( QWidget* ) = 0;
+
+  virtual QString           getString() const = 0;
+  virtual void              setString( const QString& ) = 0;
+
+  virtual bool              validate( const QString& ) const;
+
+  QString                   prefix() const;
+  QString                   suffix() const;
+  virtual QString           minValue() const;
+  virtual QString           maxValue() const;
+
+  static QString            format( const QString&, const int, const int );
+  static QString            format( const QString&, const int, const double );
+  static QString            format( const QString&, const int, const QString& );
+
+  static QString            sprintf( const QString&, const int );
+  static QString            sprintf( const QString&, const double );
+  static QString            sprintf( const QString&, const QString& );
+
+  virtual void              unitSystemChanged( const QString& );
+
+private:
+  void                      initialize();
+  void                      initDatum() const;
+
+  Wrapper*                  wrapper( QWidget* ) const;
+  Wrapper*                  wrapper( const int ) const;
+  int                       wrapperType( Wrapper* ) const;
+
+  static QString            removeAccel( const QString& );
+  static bool               isDoubleFormat( const QString& );
+  static QString            canonicalFormat( const QString& );
+  static QString            canonicalFormat( const QString&, QString& );
+
+private:
+  typedef QGuardedPtr<QLabel>  GuardedLabel;
+  typedef QGuardedPtr<QWidget> GuardedWidget;
+
+private:
+  QString                   myId;
+  int                       myFlags;
+  Handle(DDS_DicItem)       myDicItem;
+  QMap<int, Wrapper*>       myWrapper;
+
+  GuardedLabel              myLabel;
+  GuardedLabel              myUnits;
+  GuardedWidget             myControl;
+
+  QString                   mySourceValue;
+  QString                   myTargetValue;
+
+  bool                      myInitialised;
+
+  friend class QDS;
+};
+
+#endif 
diff --git a/src/QDS/QDS_LineEdit.cxx b/src/QDS/QDS_LineEdit.cxx
new file mode 100644 (file)
index 0000000..15cc3f0
--- /dev/null
@@ -0,0 +1,172 @@
+#include "QDS_LineEdit.h"
+
+#include <qlineedit.h>
+#include <qvalidator.h>
+
+/*
+  Class: QDS_LineEdit::Editor
+  Descr: Internal class inherited from line edit
+*/
+
+class QDS_LineEdit::Editor : public QLineEdit
+{
+public:
+  Editor( QWidget* parent = 0 ) : QLineEdit( parent ), myNumber( 2 ) {};
+  virtual ~Editor() {};
+
+  void setNumber( const int num ) { myNumber = num; };
+
+  virtual QSize minimumSizeHint() const
+  {
+    return QLineEdit::minimumSizeHint().
+      expandedTo( QSize( fontMetrics().width( "0" ) * myNumber, 0 ) );
+  }
+  
+  virtual QSize sizeHint() const
+  {
+    return minimumSizeHint();
+  }
+
+private:
+  int           myNumber;
+};
+
+/*
+  Class: QDS_LineEdit
+  Descr: Data control corresponding to line edit
+*/
+
+/*!
+  Constructor.
+*/
+QDS_LineEdit::QDS_LineEdit( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_LineEdit::~QDS_LineEdit()
+{
+}
+
+void QDS_LineEdit::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  QLineEdit* le = lineEdit();
+  if ( !le )
+    return;
+  
+  delete le->validator();
+  le->clearValidator();
+  QValidator* valid = validator();
+  if ( valid )
+    le->setValidator( valid );
+
+  QString aFormat = format();
+  int num = 0;
+  int pos = aFormat.find( '%' );
+  if ( pos != -1 )
+  {
+    pos++;
+    QString aLen;
+    while ( pos < (int)aFormat.length() && aFormat.at( pos ).isDigit() )
+      aLen += aFormat.at( pos++ );
+    if ( pos < (int)aFormat.length() && aFormat.at( pos ) == '.' )
+      num += 1;
+    if ( !aLen.isEmpty() )
+      num += aLen.toInt();
+  }
+  
+  int zeroLen = format( format(), type(), 0 ).length();
+  int minLen  = format( format(), type(), minValue() ).length();
+  int maxLen  = format( format(), type(), maxValue() ).length();
+
+  num = QMAX( QMAX( num, zeroLen ), QMAX( minLen, maxLen ) );
+  ((Editor*)le)->setNumber( num );
+}
+
+/*!
+  Set the aligment of line edit.
+*/
+void QDS_LineEdit::setAlignment( const int align, const int type )
+{
+  if ( ( type & Control ) && lineEdit() )
+    lineEdit()->setAlignment( align );
+
+  QDS_Datum::setAlignment( align, type );
+}
+
+/*!
+  Returns string from QLineEdit widget.
+*/
+QString QDS_LineEdit::getString() const
+{
+  QString res;
+  if ( lineEdit() )
+    res = lineEdit()->text();
+  return res;
+}
+
+/*!
+  Sets the string into QLineEdit widget.
+*/
+void QDS_LineEdit::setString( const QString& txt )
+{
+  if ( lineEdit() )
+    lineEdit()->setText( txt );
+}
+
+/*!
+  Returns pointer to QLineEdit widget.
+*/
+QLineEdit* QDS_LineEdit::lineEdit() const
+{
+  return ::qt_cast<QLineEdit*>( controlWidget() );
+}
+
+/*!
+  Create QLineEdit widget as control subwidget.
+*/
+QWidget* QDS_LineEdit::createControl( QWidget* parent )
+{
+  Editor* le = new Editor( parent );
+  connect( le, SIGNAL( returnPressed() ), this, SIGNAL( returnPressed() ) );
+  connect( le, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
+  return le;
+}
+
+/*!
+  Notify about text changing in line edit.
+*/
+void QDS_LineEdit::onTextChanged( const QString& )
+{
+  invalidateCache();
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Checks the current parameter value on validity.
+*/
+void QDS_LineEdit::onParamChanged()
+{
+  QLineEdit* anEdit = lineEdit();
+  if ( !anEdit )
+    return;
+
+  bool aValid = isValid( false );
+
+  QPalette aPal = anEdit->palette();
+  if ( !aValid )
+    aPal.setColor( QPalette::Active, QColorGroup::Text, QColor( 255, 0, 0 ) );
+  else
+    aPal.setColor( QPalette::Active, QColorGroup::Text, QColor( 0, 0, 0 ) );
+
+  anEdit->setPalette( aPal );
+}
diff --git a/src/QDS/QDS_LineEdit.h b/src/QDS/QDS_LineEdit.h
new file mode 100644 (file)
index 0000000..883d38c
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef QDS_LINEEDIT_H
+#define QDS_LINEEDIT_H
+
+#include "QDS_Datum.h"
+
+class QLineEdit;
+
+class QDS_EXPORT QDS_LineEdit : public QDS_Datum
+{
+  Q_OBJECT
+
+protected:
+  class Editor;
+
+public:
+  QDS_LineEdit( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_LineEdit();
+
+  virtual void         setAlignment( const int, const int = Label );
+
+signals:
+  void                 returnPressed();
+
+protected slots:
+  virtual void         onParamChanged();
+
+private slots:
+  void                 onTextChanged( const QString& );
+
+protected:
+  QLineEdit*           lineEdit() const;
+  virtual QWidget*     createControl( QWidget* );
+
+  virtual QString      getString() const;
+  virtual void         setString( const QString& );
+
+  virtual void         unitSystemChanged( const QString& );
+};
+
+#endif
diff --git a/src/QDS/QDS_SpinBox.cxx b/src/QDS/QDS_SpinBox.cxx
new file mode 100644 (file)
index 0000000..d25322c
--- /dev/null
@@ -0,0 +1,117 @@
+#include "QDS_SpinBox.h"
+
+#include <qspinbox.h>
+#include <qvalidator.h>
+
+/*!
+  Constructor.
+*/
+QDS_SpinBox::QDS_SpinBox( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_SpinBox::~QDS_SpinBox()
+{
+}
+
+/*!
+  Returns string from QSpinBox widget.
+*/
+QString QDS_SpinBox::getString() const
+{
+  QString res;
+  QSpinBox* aSpinBox = spinBox();
+  if ( aSpinBox )
+  {
+    res = aSpinBox->text();
+    if ( !aSpinBox->suffix().isEmpty() )
+      res.remove( res.find( aSpinBox->suffix() ), aSpinBox->suffix().length() );
+    if ( !aSpinBox->prefix().isEmpty() )
+      res.remove( res.find( aSpinBox->prefix() ), aSpinBox->prefix().length() );
+  }
+  return res;
+}
+
+/*!
+  Sets the string into QSpinBox widget.
+*/
+void QDS_SpinBox::setString( const QString& txt )
+{
+  if ( spinBox() )
+    spinBox()->setValue( txt.toInt() );
+}
+
+/*!
+  Returns pointer to QSpinBox widget.
+*/
+QSpinBox* QDS_SpinBox::spinBox() const
+{
+  return ::qt_cast<QSpinBox*>( controlWidget() );
+}
+
+/*!
+  Create QSpinBox widget as control subwidget.
+*/
+QWidget* QDS_SpinBox::createControl( QWidget* parent )
+{
+  QSpinBox* aSpinBox = new QSpinBox( parent );
+  aSpinBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  connect( aSpinBox, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged( int ) ) );
+  return aSpinBox;
+}
+
+/*!
+  Notify about text changing in spin box.
+*/
+void QDS_SpinBox::onValueChanged( int val )
+{
+  onParamChanged();
+  QString str = QString::number( val );
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Sets the increment step.
+*/
+void QDS_SpinBox::setStep( const int step )
+{
+  if ( spinBox() )
+    spinBox()->setLineStep( step );
+}
+
+/*!
+  Returns the increment step.
+*/
+int QDS_SpinBox::step() const
+{
+  int s = 0;
+  if ( spinBox() )
+    s = spinBox()->lineStep();
+  return s;
+}
+
+/*!
+  This method is redefined from ancestor class to perform own initialization ( suffix, prefix, etc ).
+*/
+void QDS_SpinBox::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  QSpinBox* sb = spinBox();
+  if ( sb )
+  {
+    delete sb->validator();
+    QValidator* valid = validator();
+    sb->setValidator( valid );
+
+    sb->setSuffix( suffix() );
+    sb->setPrefix( prefix() );
+    sb->setMinValue( minValue().toInt() );
+    sb->setMaxValue( maxValue().toInt() );
+  }
+}
diff --git a/src/QDS/QDS_SpinBox.h b/src/QDS/QDS_SpinBox.h
new file mode 100644 (file)
index 0000000..d6490ed
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef QDS_SPINBOX_H
+#define QDS_SPINBOX_H
+
+#include "QDS_Datum.h"
+
+class QSpinBox;
+
+class QDS_EXPORT QDS_SpinBox : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_SpinBox( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_SpinBox();
+
+  int              step() const;
+  void             setStep( const int );
+
+private slots:
+  void             onValueChanged( int );
+
+protected:
+  QSpinBox*        spinBox() const;
+
+  virtual QWidget* createControl( QWidget* );
+
+  virtual QString  getString() const;
+  virtual void     setString( const QString& );
+
+  virtual void     unitSystemChanged( const QString& );
+};
+
+#endif 
diff --git a/src/QDS/QDS_SpinBoxDbl.cxx b/src/QDS/QDS_SpinBoxDbl.cxx
new file mode 100644 (file)
index 0000000..42d1e2f
--- /dev/null
@@ -0,0 +1,135 @@
+#include "QDS_SpinBoxDbl.h"
+
+#include <DDS_Dictionary.h>
+
+#include <qvalidator.h>
+
+#include <QtxDblSpinBox.h>
+
+/*!
+  Constructor.
+*/
+QDS_SpinBoxDbl::QDS_SpinBoxDbl( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_SpinBoxDbl::~QDS_SpinBoxDbl()
+{
+}
+
+/*!
+  Returns string from QSpinBox widget.
+*/
+QString QDS_SpinBoxDbl::getString() const
+{
+  QString res;
+  QtxDblSpinBox* sb = spinBox();
+  if ( sb )
+  {
+    bool hasFocus = sb->hasFocus();
+    if ( hasFocus )
+      sb->clearFocus();
+    
+    res = sb->text();
+    if ( !sb->suffix().isEmpty() )
+      res.remove( res.find( sb->suffix() ), sb->suffix().length() );
+    if ( !sb->prefix().isEmpty() )
+      res.remove( res.find( sb->prefix() ), sb->prefix().length() );
+    
+    if ( hasFocus )
+      sb->setFocus();
+  }
+
+  return res;
+}
+
+/*!
+  Sets the string into QSpinBox widget.
+*/
+void QDS_SpinBoxDbl::setString( const QString& txt )
+{
+  if ( spinBox() )
+    spinBox()->setValue( txt.toDouble() );
+}
+
+/*!
+  Returns pointer to XMLGUI_SpinBoxDbl widget.
+*/
+QtxDblSpinBox* QDS_SpinBoxDbl::spinBox() const
+{
+  return ::qt_cast<QtxDblSpinBox*>( controlWidget() );
+}
+
+/*!
+  Create QSpinBox widget as control subwidget.
+*/
+QWidget* QDS_SpinBoxDbl::createControl( QWidget* parent )
+{
+  QtxDblSpinBox* aSpinBox = new QtxDblSpinBox( parent );
+  aSpinBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  connect( aSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged( double ) ) );
+  return aSpinBox;
+}
+
+/*!
+  Notify about text changing in spin box.
+*/
+void QDS_SpinBoxDbl::onValueChanged( double )
+{
+  onParamChanged();
+  QString str = getString();
+
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Returns the increment step.
+*/
+double QDS_SpinBoxDbl::step() const
+{
+  double s = 0;
+  if ( spinBox() )
+    s = spinBox()->lineStep();
+  return s;
+}
+
+/*!
+  Sets the increment step.
+*/
+void QDS_SpinBoxDbl::setStep( const double step )
+{
+  if ( spinBox() )
+    spinBox()->setLineStep( step );
+}
+
+void QDS_SpinBoxDbl::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  QtxDblSpinBox* sb = spinBox();
+  if ( !sb )
+    return;
+
+  delete sb->validator();
+  QValidator* valid = validator();
+  sb->setValidator( valid );
+
+  sb->setSuffix( suffix() );
+  sb->setPrefix( prefix() );
+
+  Standard_Integer aPreci = 1;
+  Handle(DDS_DicItem) aDicItem = dicItem();
+  if ( !aDicItem.IsNull() )
+    aPreci = aDicItem->GetPrecision();
+
+  sb->setPrecision( aPreci );
+
+  sb->setLineStep( .1 );
+  sb->setMinValue( minValue().toDouble() );
+  sb->setMaxValue( maxValue().toDouble() );
+}
diff --git a/src/QDS/QDS_SpinBoxDbl.h b/src/QDS/QDS_SpinBoxDbl.h
new file mode 100644 (file)
index 0000000..a0c5e30
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef QDS_PINBOXDBL_H
+#define QDS_PINBOXDBL_H
+
+#include "QDS_Datum.h"
+
+class QtxDblSpinBox;
+
+class QDS_EXPORT QDS_SpinBoxDbl : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_SpinBoxDbl( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_SpinBoxDbl();
+
+  double           step() const;
+  void             setStep( const double );
+
+private slots:
+  void             onValueChanged( double );
+
+protected:
+  QtxDblSpinBox*   spinBox() const;
+  virtual QWidget* createControl( QWidget* );
+
+  virtual QString  getString() const;
+  virtual void     setString( const QString& );
+
+  virtual void     unitSystemChanged( const QString& );
+};
+
+#endif 
diff --git a/src/QDS/QDS_TextEdit.cxx b/src/QDS/QDS_TextEdit.cxx
new file mode 100644 (file)
index 0000000..65fbcb2
--- /dev/null
@@ -0,0 +1,71 @@
+#include "QDS_TextEdit.h"
+
+#include <qtextedit.h>
+
+/*!
+  Constructor.
+*/
+QDS_TextEdit::QDS_TextEdit( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_TextEdit::~QDS_TextEdit()
+{
+}
+
+/*!
+  Returns string from QTextEdit widget.
+*/
+QString QDS_TextEdit::getString() const
+{
+  QString res;
+  if ( textEdit() )
+    res = textEdit()->text();
+  return res;
+}
+
+/*!
+  Sets the string into QTextEdit widget.
+*/
+void QDS_TextEdit::setString( const QString& txt )
+{
+  if ( textEdit() )
+    textEdit()->setText( txt );
+}
+
+/*!
+  Returns pointer to QTextEdit widget.
+*/
+QTextEdit* QDS_TextEdit::textEdit() const
+{
+  return ::qt_cast<QTextEdit*>( controlWidget() );
+}
+
+/*!
+  Create QTextEdit widget as control subwidget.
+*/
+QWidget* QDS_TextEdit::createControl( QWidget* parent )
+{
+  QTextEdit* te = new QTextEdit( parent );
+  connect( te, SIGNAL( textChanged() ), this, SLOT( onTextChanged() ) );
+  return te;
+}
+
+/*!
+  Notify about text changing in line edit.
+*/
+void QDS_TextEdit::onTextChanged()
+{
+  invalidateCache();
+
+  onParamChanged();
+
+  QString str = getString();
+
+  emit paramChanged();
+  emit paramChanged( str );
+}
diff --git a/src/QDS/QDS_TextEdit.h b/src/QDS/QDS_TextEdit.h
new file mode 100644 (file)
index 0000000..917ff13
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef QDS_TEXTEEDIT_H
+#define QDS_TEXTEEDIT_H
+
+#include "QDS_Datum.h"
+
+class QTextEdit;
+
+class QDS_EXPORT QDS_TextEdit : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_TextEdit( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_TextEdit();
+
+signals:
+  void                            returnPressed();
+
+private slots:
+  void                            onTextChanged();
+
+protected:
+  QTextEdit*                      textEdit() const;
+  virtual QWidget*                createControl( QWidget* );
+
+  virtual QString                 getString() const;
+  virtual void                    setString( const QString& );
+};
+
+#endif 
diff --git a/src/QDS/QDS_Validator.cxx b/src/QDS/QDS_Validator.cxx
new file mode 100644 (file)
index 0000000..d83463e
--- /dev/null
@@ -0,0 +1,127 @@
+#include "QDS_Validator.h"
+
+/*!
+    Class: QDS_IntegerValidator
+*/
+
+QDS_IntegerValidator::QDS_IntegerValidator( QObject* p )
+: QIntValidator( p )
+{
+}
+
+QDS_IntegerValidator::QDS_IntegerValidator( const QString& f, QObject* p )
+: QIntValidator( p ),
+myFilter( f )
+{
+}
+
+QDS_IntegerValidator::~QDS_IntegerValidator()
+{
+}
+
+QValidator::State QDS_IntegerValidator::validate( QString& input, int& pos ) const
+{
+  State rgState = Acceptable;
+  State ivState = QIntValidator::validate( input, pos );
+  if ( ivState != Invalid && !myFilter.isEmpty() )
+    rgState = QRegExpValidator( QRegExp( myFilter ), 0 ).validate( input, pos );
+
+  ivState = QMIN( ivState, rgState );
+
+  return ivState;
+}
+
+/*!
+    Class: QDS_DoubleValidator
+*/
+
+QDS_DoubleValidator::QDS_DoubleValidator( QObject* p )
+: QDoubleValidator( p )
+{
+}
+
+QDS_DoubleValidator::QDS_DoubleValidator( const QString& f, QObject* p )
+: QDoubleValidator( p ),
+myFilter( f )
+{
+}
+
+QDS_DoubleValidator::~QDS_DoubleValidator()
+{
+}
+
+QValidator::State QDS_DoubleValidator::validate( QString& input, int& pos ) const
+{
+  State rgState = Acceptable;
+  State dvState = QDoubleValidator::validate( input, pos );
+  if ( dvState != Invalid && !myFilter.isEmpty() )
+    rgState = QRegExpValidator( QRegExp( myFilter ), 0 ).validate( input, pos );
+
+  dvState = QMIN( dvState, rgState );
+
+  return dvState;
+}
+
+/*!
+    Class: QDS_StringValidator
+*/
+
+QDS_StringValidator::QDS_StringValidator( QObject* p ) 
+: QValidator( p ), 
+myLen( -1 ) 
+{
+}
+
+QDS_StringValidator::QDS_StringValidator( const QString& f, QObject* p ) 
+: QValidator( p ), 
+myFlags( f ), 
+myLen( -1 ) 
+{
+}
+
+QDS_StringValidator::QDS_StringValidator( const QString& ft, const QString& fg, QObject* p ) 
+: QValidator( p ), 
+myLen( -1 ), 
+myFilter( ft ), 
+myFlags( fg ) 
+{
+}
+
+QDS_StringValidator::~QDS_StringValidator() 
+{
+}
+
+int QDS_StringValidator::length() const 
+{ 
+  return myLen; 
+}
+
+void QDS_StringValidator::setLength( const int l ) 
+{ 
+  myLen = l; 
+}
+
+QValidator::State QDS_StringValidator::validate( QString& input, int& pos ) const
+{
+  if ( input.isEmpty() )
+    return Acceptable;
+
+  QString orig = input;
+  if ( myFlags.contains( 'u', false ) )
+    input = input.upper();
+  if ( myFlags.contains( 'l', false ) )
+    input = input.lower();
+
+  State rgState = Acceptable;
+  State svState = orig == input ? Acceptable : Intermediate;
+
+  if ( myLen >= 0 && (int)input.length() > myLen )
+      svState = Intermediate;
+
+  if ( !myFilter.isEmpty() )
+    rgState = QRegExpValidator( QRegExp( myFilter ), 0 ).validate( input, pos );
+
+  svState = QMIN( svState, rgState );
+
+  return svState;
+}
diff --git a/src/QDS/QDS_Validator.h b/src/QDS/QDS_Validator.h
new file mode 100644 (file)
index 0000000..bc966c0
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef QDS_VALIDATOR_H
+#define QDS_VALIDATOR_H
+
+#include "QDS.h"
+
+#include <qvalidator.h>
+
+/*!
+    Class: QDS_IntegerValidator
+*/
+
+class QDS_EXPORT QDS_IntegerValidator : public QIntValidator
+{
+public:
+  QDS_IntegerValidator( QObject* p = 0 );
+  QDS_IntegerValidator( const QString& f, QObject* p = 0 );
+  virtual ~QDS_IntegerValidator();
+
+  virtual State validate( QString&, int& ) const;
+
+private:
+  QString myFilter;
+};
+
+/*!
+    Class: QDS_DoubleValidator
+*/
+
+class QDS_DoubleValidator : public QDoubleValidator
+{
+public:
+  QDS_DoubleValidator( QObject* p = 0 );
+  QDS_DoubleValidator( const QString& f, QObject* p = 0 );
+  virtual ~QDS_DoubleValidator();
+
+  virtual State validate( QString&, int& ) const;
+
+private:
+  QString myFilter;
+};
+
+/*!
+    Class: QDS_StringValidator
+*/
+
+class QDS_EXPORT QDS_StringValidator : public QValidator
+{
+public:
+
+  QDS_StringValidator( QObject* p = 0 );
+  QDS_StringValidator( const QString& f, QObject* p = 0 );
+  QDS_StringValidator( const QString& ft, const QString& fg, QObject* p = 0 );
+  virtual ~QDS_StringValidator();
+
+  virtual State validate( QString&, int& ) const;
+
+  int           length() const;
+  void          setLength( const int );
+
+private:
+  int           myLen;
+  QString       myFlags;
+  QString       myFilter;
+};
+
+#endif
diff --git a/src/Qtx/QtxColorScale.cxx b/src/Qtx/QtxColorScale.cxx
new file mode 100755 (executable)
index 0000000..7be7ba4
--- /dev/null
@@ -0,0 +1,1313 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxColorScale.cxx
+// Author:    Sergey TELKOV
+
+#include "QtxColorScale.h"
+
+#include <qmap.h>
+#include <qimage.h>
+#include <qregexp.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qpainter.h>
+#include <qmainwindow.h>
+#include <qstringlist.h>
+#include <qstylesheet.h>
+#include <qsimplerichtext.h>
+
+#include <math.h>
+
+/*********************************************************************
+**  Class:  QtxColorScale
+**  Descr:  Color Scale widget.
+**  Level:  Public
+*********************************************************************/
+
+QtxColorScale::QtxColorScale( QWidget* parent, const char* name, WFlags f )
+: QFrame( parent, name, f | WResizeNoErase | WRepaintNoErase ),
+myDock( 0 ),
+myMin( 0.0 ),
+myMax( 1.0 ),
+myTitle( "" ),
+myInterval( 10 ),
+myStyleSheet( 0 ),
+myFormat( "%.4g" ),
+myColorMode( Auto ),
+myLabelMode( Auto ),
+myLabelPos( Right ),
+myTitlePos( Center ),
+myDumpMode( NoDump ),
+myFlags( AtBorder | WrapTitle )
+{
+       setCaption( tr ( "Color scale" ) );
+}
+
+QtxColorScale::QtxColorScale( const int num, QWidget* parent, const char* name, WFlags f )
+: QFrame( parent, name, f | WResizeNoErase | WRepaintNoErase ),
+myDock( 0 ),
+myMin( 0.0 ),
+myMax( 1.0 ),
+myTitle( "" ),
+myInterval( num ),
+myStyleSheet( 0 ),
+myFormat( "%.4g" ),
+myColorMode( Auto ),
+myLabelMode( Auto ),
+myLabelPos( Right ),
+myTitlePos( Center ),
+myDumpMode( NoDump ),
+myFlags( AtBorder | WrapTitle )
+{
+       setCaption( tr ( "Color scale" ) );
+}
+
+#if QT_VER == 3
+
+QtxColorScale::QtxColorScale( Dock* dock, const char* name, WFlags f )
+: QFrame( dock, name, f | WResizeNoErase | WRepaintNoErase ),
+myMin( 0.0 ),
+myMax( 1.0 ),
+myTitle( "" ),
+myDock( dock ),
+myInterval( 10 ),
+myStyleSheet( 0 ),
+myFormat( "%.4g" ),
+myColorMode( Auto ),
+myLabelMode( Auto ),
+myLabelPos( Right ),
+myTitlePos( Center ),
+myDumpMode( NoDump ),
+myFlags( AtBorder | WrapTitle )
+{
+       setCaption( tr ( "Color scale" ) );
+}
+
+#endif
+
+QtxColorScale::~QtxColorScale()
+{
+}
+
+//================================================================
+// Function : minimum
+// Purpose  : Returns minimal limit of scale.
+//================================================================
+
+double QtxColorScale::minimum() const
+{
+       return myMin;
+}
+
+//================================================================
+// Function : maximum
+// Purpose  : Returns maximal limit of scale.
+//================================================================
+
+double QtxColorScale::maximum() const
+{
+       return myMax;
+}
+
+//================================================================
+// Function : range
+// Purpose  : Returns range (minimal and maximal limits) of scale.
+//================================================================
+
+void QtxColorScale::range( double& min, double& max ) const
+{
+       min = myMin;
+       max = myMax;
+}
+
+//================================================================
+// Function : title
+// Purpose  : Returns the current title string.
+//================================================================
+
+QString QtxColorScale::title() const
+{
+       return myTitle;
+}
+
+//================================================================
+// Function : format
+// Purpose  : Returns the current format of number presentation in
+//            labels for Auto label mode (sprintf specification).
+//================================================================
+
+QString QtxColorScale::format() const
+{
+       return myFormat;
+}
+
+//================================================================
+// Function : dumpMode
+// Purpose  : Returns dump mode.
+//================================================================
+
+int QtxColorScale::dumpMode() const
+{
+       return myDumpMode;
+}
+
+//================================================================
+// Function : labelMode
+// Purpose  : Returns label mode.
+//================================================================
+
+int QtxColorScale::labelMode() const
+{
+       return myLabelMode;
+}
+
+//================================================================
+// Function : colorMode
+// Purpose  : Returns color mode.
+//================================================================
+
+int QtxColorScale::colorMode() const
+{
+       return myColorMode;
+}
+
+//================================================================
+// Function : intervalsNumber
+// Purpose  : Returns intervals number of color scale.
+//================================================================
+
+int QtxColorScale::intervalsNumber() const
+{
+       return myInterval;
+}
+
+//================================================================
+// Function : label
+// Purpose  : Returns the user label of specified interval.
+//================================================================
+
+QString QtxColorScale::label( const int idx ) const
+{
+       QString res;
+       if ( idx >= 0 && idx < (int)myLabels.count() )
+               res = *myLabels.at( idx );
+       return res;
+}
+
+//================================================================
+// Function : color
+// Purpose  : Returns the user color of specified interval.
+//================================================================
+
+QColor QtxColorScale::color( const int idx ) const
+{
+       QColor res;
+       if ( idx >= 0 && idx < (int)myColors.count() )
+               res = *myColors.at( idx );
+       return res;
+}
+
+//================================================================
+// Function : labels
+// Purpose  : Returns the user labels.
+//================================================================
+
+void QtxColorScale::labels( QStringList& list ) const
+{
+       list = myLabels;
+}
+
+//================================================================
+// Function : colors
+// Purpose  : Returns the user color.
+//================================================================
+
+void QtxColorScale::colors( QValueList<QColor>& list ) const
+{
+       list = myColors;
+}
+
+//================================================================
+// Function : labelPosition
+// Purpose  : Returns the label position.
+//================================================================
+
+int QtxColorScale::labelPosition() const
+{
+       return myLabelPos;
+}
+
+//================================================================
+// Function : titlePosition
+// Purpose  : Returns the title position.
+//================================================================
+
+int QtxColorScale::titlePosition() const
+{
+       return myTitlePos;
+}
+
+//================================================================
+// Function : setMinimum
+// Purpose  : Sets the minimum limit.
+//================================================================
+
+void QtxColorScale::setMinimum( const double val )
+{
+       setRange( val, maximum() );
+}
+
+//================================================================
+// Function : setMaximum
+// Purpose  : Sets the maximum limit.
+//================================================================
+
+void QtxColorScale::setMaximum( const double val )
+{
+       setRange( minimum(), val );
+}
+
+//================================================================
+// Function : setRange
+// Purpose  : Sets the minimum and maximum limits.
+//================================================================
+
+void QtxColorScale::setRange( const double min, const double max )
+{
+       if ( myMin == min && myMax == max )
+               return;
+
+       myMin = min;
+       myMax = max;
+
+       myPrecise = QString::null;
+
+       if ( colorMode() == Auto || labelMode() == Auto )
+               updateScale();
+}
+
+//================================================================
+// Function : setTitle
+// Purpose  : Sets the title string.
+//================================================================
+
+void QtxColorScale::setTitle( const QString& str )
+{
+       if ( myTitle == str )
+               return;
+
+       myTitle = str;
+       updateScale();
+}
+
+//================================================================
+// Function : setFormat
+// Purpose  : Sets the format of number presentation in labels for
+//            Auto label mode (sprintf specification).
+//================================================================
+
+void QtxColorScale::setFormat( const QString& format )
+{
+       if ( myFormat == format )
+               return;
+
+       myFormat = format;
+       myPrecise = QString::null;
+       if ( colorMode() == Auto )
+               updateScale();
+}
+
+//================================================================
+// Function : setIntervalsNumber
+// Purpose  : Sets the number of intervals.
+//================================================================
+
+void QtxColorScale::setIntervalsNumber( const int num )
+{
+       if ( myInterval == num || num < 1 )
+               return;
+
+       myInterval = num;
+       myPrecise = QString::null;
+
+       updateScale();
+}
+
+//================================================================
+// Function : setLabel
+// Purpose  : Sets the user label for specified interval. If number
+//            of interval is negative then user label will be added
+//            as new at the end of list.
+//================================================================
+
+void QtxColorScale::setLabel( const QString& txt, const int idx )
+{
+       bool changed = false;
+       uint i = idx < 0 ? myLabels.count() : idx;
+       if ( i < myLabels.count() )
+       {
+               changed = *myLabels.at( i ) != txt;
+               myLabels[i] = txt;
+       }
+       else
+       {
+               changed = true;
+               while ( i >= myLabels.count() )
+                   myLabels.append( "" );
+               myLabels[i] = txt;
+       }
+       if ( changed )
+               updateScale();
+}
+
+//================================================================
+// Function : setColor
+// Purpose  : Sets the user color for specified interval. If number
+//            of interval is negative then user color will be added
+//            as new at the end of list.
+//================================================================
+
+void QtxColorScale::setColor( const QColor& clr, const int idx )
+{
+       bool changed = false;
+       uint i = idx < 0 ? myColors.count() : idx;
+       if ( i < myColors.count() )
+       {
+               changed = *myColors.at( i ) != clr;
+               myColors[i] = clr;
+       }
+       else
+       {
+               changed = true;
+        while ( i >= myColors.count() )
+            myColors.append( QColor() );
+               myColors[i] = clr;
+       }
+       if ( changed )
+               updateScale();
+}
+
+//================================================================
+// Function : setLabels
+// Purpose  : Replace the all user label with specified list.
+//================================================================
+
+void QtxColorScale::setLabels( const QStringList& list )
+{
+       if ( list.isEmpty() )
+               return;
+
+       myLabels = list;
+       updateScale();
+}
+
+//================================================================
+// Function : setColors
+// Purpose  : Replace the all user colors with specified list.
+//================================================================
+
+void QtxColorScale::setColors( const QValueList<QColor>& list )
+{
+       if ( list.isEmpty() )
+           return;
+
+       myColors = list;
+       updateScale();
+}
+
+//================================================================
+// Function : setColorMode
+// Purpose  : Sets the color mode (Auto or User).
+//================================================================
+
+void QtxColorScale::setColorMode( const int mode )
+{
+       if ( myColorMode == mode )
+               return;
+
+       myColorMode = mode;
+       updateScale();
+}
+
+//================================================================
+// Function : setDumpMode
+// Purpose  : Sets the dump mode.
+//================================================================
+
+void QtxColorScale::setDumpMode( const int mode )
+{
+       myDumpMode = mode;
+}
+
+//================================================================
+// Function : setLabelMode
+// Purpose  : Sets the label mode (Auto or User).
+//================================================================
+
+void QtxColorScale::setLabelMode( const int mode )
+{
+       if ( myLabelMode != mode )
+       {
+               myLabelMode = mode;
+               updateScale();
+       }
+}
+
+//================================================================
+// Function : setLabelPosition
+// Purpose  : Sets the label position.
+//================================================================
+
+void QtxColorScale::setLabelPosition( const int pos )
+{
+       if ( myLabelPos != pos && pos >= None && pos <= Center )
+       {
+               myLabelPos = pos;
+               updateScale();
+       }
+}
+
+//================================================================
+// Function : setTitlePosition
+// Purpose  : Sets the title position.
+//================================================================
+
+void QtxColorScale::setTitlePosition( const int pos )
+{
+       if ( myTitlePos != pos && pos >= None && pos <= Center )
+       {
+               myTitlePos = pos;
+               updateScale();
+       }
+}
+
+//================================================================
+// Function : setFlags
+// Purpose  : Set the specified flags.
+//================================================================
+
+void QtxColorScale::setFlags( const int flags )
+{
+       int prev = myFlags;
+       myFlags |= flags;
+       if ( prev != myFlags )
+               updateScale();
+}
+
+//================================================================
+// Function : testFlags
+// Purpose  : Returns true if specified flags are setted.
+//================================================================
+
+bool QtxColorScale::testFlags( const int flags ) const
+{
+       return ( myFlags & flags ) == flags;
+}
+
+//================================================================
+// Function : clearFlags
+// Purpose  : Clear (reset) the specified flags.
+//================================================================
+
+void QtxColorScale::clearFlags( const int flags )
+{
+       int prev = myFlags;
+       myFlags &= ~flags;
+       if ( prev != myFlags )
+               updateScale();
+}
+
+//================================================================
+// Function : minimumSizeHint
+// Purpose  : 
+//================================================================
+
+QSize QtxColorScale::minimumSizeHint() const
+{
+  QSize sz = calculateSize( true, myFlags, titlePosition() != None, labelPosition() != None, true );
+       return sz + QSize( frameWidth(), frameWidth() );
+}
+
+//================================================================
+// Function : sizeHint
+// Purpose  : 
+//================================================================
+
+QSize QtxColorScale::sizeHint() const
+{
+  QSize sz = calculateSize( false, myFlags, titlePosition() != None, labelPosition() != None, true );
+       return sz + QSize( frameWidth(), frameWidth() );
+}
+
+//================================================================
+// Function : calculateSize
+// Purpose  : Dump color scale into pixmap with current size.
+//================================================================
+
+QSize QtxColorScale::calculateSize( const bool min, const int flags, const bool title,
+                                                                                   const bool labels, const bool colors ) const
+{
+       int num = intervalsNumber();
+
+       int spacer = 5;
+       int textWidth = 0;
+       int textHeight = fontMetrics().height();
+       int colorWidth = 20;
+
+       if ( labels && colors )
+  {
+    QtxColorScale* that = (QtxColorScale*)this;
+    QString fmt = that->myFormat;
+
+               for ( int idx = 0; idx < num; idx++ )
+                       textWidth = QMAX( textWidth, fontMetrics().width( getLabel( idx ) ) );
+
+    if ( !min )
+      that->myFormat = that->myFormat.replace( QRegExp( "g" ), "f" );
+
+               for ( int index = 0; index < num; index++ )
+                       textWidth = QMAX( textWidth, fontMetrics().width( getLabel( index ) ) );
+
+    that->myFormat = fmt;
+  }
+
+       int scaleWidth = 0;
+       int scaleHeight = 0;
+
+       int titleWidth = 0;
+       int titleHeight = 0;
+
+       if ( flags & AtBorder )
+       {
+               num++;
+               if ( min && title && !myTitle.isEmpty() )
+                       titleHeight += 10;
+       }
+
+       if ( colors )
+       {
+               scaleWidth = colorWidth + textWidth + ( textWidth ? 3 : 2 ) * spacer;
+               if ( min )
+                       scaleHeight = QMAX( 2 * num, 3 * textHeight );
+               else
+                       scaleHeight = (int)( 1.5 * ( num + 1 ) * textHeight );
+       }
+
+       if ( title )
+       {
+               QSimpleRichText* srt = simpleRichText( flags );
+               if ( srt )
+               {
+                       QPainter p( this );
+                       if ( scaleWidth )
+                               srt->setWidth( &p, scaleWidth );
+
+                       titleHeight = srt->height() + spacer;
+                       titleWidth = srt->widthUsed() + 10;
+
+                       delete srt;
+               }
+       }
+
+       int W = QMAX( titleWidth, scaleWidth ) + width() - contentsRect().width();
+       int H = scaleHeight + titleHeight + height() - contentsRect().height();
+
+       return QSize( W, H );
+}
+
+//================================================================
+// Function : dump
+// Purpose  : Dump color scale into pixmap with current size.
+//================================================================
+
+QPixmap QtxColorScale::dump() const
+{
+       QPixmap aPix;
+  
+       if ( dumpMode() != NoDump )
+       {
+               aPix = QPixmap( size() );
+               if ( !aPix.isNull() )
+               {
+                       bool scale = ( myDumpMode == ScaleDump || myDumpMode == FullDump );
+                       bool label = ( myDumpMode == ScaleDump || myDumpMode == FullDump ) &&
+                                                labelPosition() != None;
+                       bool title = ( myDumpMode == TitleDump || myDumpMode == FullDump ) &&
+                                                titlePosition() != None;
+
+#if QT_VER < 3
+            QColor bgc = backgroundColor();
+#else
+            QColor bgc = paletteBackgroundColor();
+#endif
+                       QPainter p;
+                       p.begin( &aPix );
+                       p.fillRect( 0, 0, aPix.width(), aPix.height(), bgc );
+                       drawScale( &p, bgc, false, 0, 0, aPix.width(), aPix.height(), title, label, scale );
+                       p.end();
+               }
+       }
+
+       return aPix;
+}
+
+//================================================================
+// Function : dump
+// Purpose  : Dump color scale into pixmap with specified size.
+//================================================================
+
+QPixmap QtxColorScale::dump( const int w, const int h ) const
+{
+#if QT_VER < 3
+       return dump( backgroundColor(), w, h );
+#else
+       return dump( paletteBackgroundColor(), w, h );
+#endif
+}
+
+//================================================================
+// Function : dump
+// Purpose  : Dump color scale into pixmap with specified size
+//            and background color.
+//================================================================
+
+QPixmap QtxColorScale::dump( const QColor& bg, const int w, const int h ) const
+{
+       QPixmap aPix;
+       if ( dumpMode() != NoDump )
+       {
+               bool scale = ( myDumpMode == ScaleDump || myDumpMode == FullDump );
+               bool label = ( myDumpMode == ScaleDump || myDumpMode == FullDump ) &&
+                                        labelPosition() != None;
+               bool title = ( myDumpMode == TitleDump || myDumpMode == FullDump ) &&
+                                        titlePosition() != None;
+
+               int W = w;
+               int H = h;
+               if ( W < 0 || H < 0 )
+               {
+                       QSize sz = calculateSize( false, myFlags & ~WrapTitle, title, label, scale );
+
+                       if ( W < 0 )
+                               W = sz.width();
+                       if ( H < 0 )
+                               H = sz.height();
+               }
+
+               aPix = QPixmap( W, H );
+               if ( !aPix.isNull() )
+               {
+                       QPainter p;
+                       p.begin( &aPix );
+                       p.fillRect( 0, 0, aPix.width(), aPix.height(), bg );
+                       drawScale( &p, bg, false, 0, 0, aPix.width(), aPix.height(), title, label, scale );
+                       p.end();
+               }
+       }
+
+       return aPix;
+}
+
+//================================================================
+// Function : show
+// Purpose  : Show the color scale. [Reimplemented]
+//================================================================
+
+void QtxColorScale::show()
+{
+#if QT_VER == 3
+       if ( myDock )
+               myDock->activate();
+       else
+#endif
+       QFrame::show();
+}
+
+//================================================================
+// Function : hide
+// Purpose  : Hides the color scale. [Reimplemented]
+//================================================================
+
+void QtxColorScale::hide()
+{
+#if QT_VER == 3
+       if ( myDock )
+               myDock->deactivate();
+       else
+#endif
+       QFrame::hide();
+}
+
+//================================================================
+// Function : drawContents
+// Purpose  : Draw color scale contents. [Reimplemented]
+//================================================================
+
+void QtxColorScale::drawContents( QPainter* p )
+{
+       if ( !isUpdatesEnabled() )
+               return;
+
+       QRect aDrawRect = contentsRect();
+
+       drawScale( p, false/*testFlags( Transparent )*/, aDrawRect.x(),
+                          aDrawRect.y(), aDrawRect.width(), aDrawRect.height(),
+                          titlePosition() != None, labelPosition() != None, true );
+}
+
+//================================================================
+// Function : drawScale
+// Purpose  : Draw color scale contents.
+//================================================================
+
+void QtxColorScale::drawScale( QPainter* p, const bool transp, const int X, const int Y,
+                               const int W, const int H, const bool title,
+                               const bool label, const bool scale ) const
+{
+       QPixmap cache( W, H );
+       QPainter cp( &cache );
+
+#if QT_VER < 3
+       drawScale( &cp, backgroundColor(), transp, 0, 0, W, H, title, label, scale );
+#else
+       drawScale( &cp, paletteBackgroundColor(), transp, 0, 0, W, H, title, label, scale );
+#endif
+       cp.end();
+
+       p->drawPixmap( X, Y, cache );
+}
+
+//================================================================
+// Function : drawScale
+// Purpose  : Draw color scale contents.
+//================================================================
+
+void QtxColorScale::drawScale( QPainter* p, const QColor& bg, const bool transp,
+                               const int X, const int Y, const int W, const int H,
+                               const bool drawTitle, const bool drawLabel, const bool drawColors ) const
+{
+       if ( !transp )
+               p->fillRect( X, Y, W, H, bg );
+
+       int num = intervalsNumber();
+
+       int labPos = labelPosition();
+
+       int spacer = 5;
+       int textWidth = 0;
+       int textHeight = p->fontMetrics().height();
+
+       QString aTitle = title();
+
+       int titleWidth = 0;
+       int titleHeight = 0;
+
+       if ( qGray( bg.rgb() ) < 128 )
+               p->setPen( QColor( 255, 255, 255 ) );
+       else
+           p->setPen( QColor( 0, 0, 0 ) );
+
+       // Draw title
+       if ( drawTitle )
+       {
+               QSimpleRichText* srt = simpleRichText( myFlags );
+               if ( srt )
+               {
+                       srt->setWidth( p, W - 10 );
+                       titleHeight = srt->height() + spacer;
+                       titleWidth = srt->widthUsed();
+                       QColorGroup cg = colorGroup();
+                       cg.setColor( QColorGroup::Text, p->pen().color() );
+                       srt->draw( p, X + 5, Y, QRect( 0, 0, srt->width(), srt->height() ), cg );
+
+                       delete srt;
+               }
+       }
+
+       bool reverse = testFlags( Reverse );
+
+       QValueList<QColor>  colors;
+       QValueList<QString> labels;
+       for ( int idx = 0; idx < num; idx++ )
+       {
+               if ( reverse )
+               {
+                       colors.append( getColor( idx ) );
+                       labels.append( getLabel( idx ) );
+               }
+               else
+               {
+                       colors.prepend( getColor( idx ) );
+                       labels.prepend( getLabel( idx ) );
+               }
+       }
+
+       if ( testFlags( AtBorder ) )
+       {
+               if ( reverse )
+                       labels.append( getLabel( num ) );
+               else
+                       labels.prepend( getLabel( num ) );
+               if ( drawLabel )
+                       textWidth = QMAX( textWidth, p->fontMetrics().width( labels.last() ) );
+       }
+
+       if ( drawLabel )
+       {
+               const QFontMetrics& fm = p->fontMetrics();
+               for ( QStringList::ConstIterator it = labels.begin(); it != labels.end(); ++it )
+                       textWidth = QMAX( textWidth, fm.width( *it) );
+       }
+
+       int lab = labels.count();
+
+       double spc = ( H - ( ( QMIN( lab, 2 ) + QABS( lab - num - 1 ) ) * textHeight ) - titleHeight );
+       double val = spc != 0 ? 1.0 * ( lab - QMIN( lab, 2 ) ) * textHeight / spc : 0;
+       double iPart;
+       double fPart = modf( val, &iPart );
+       int filter = (int)iPart + ( fPart != 0 ? 1 : 0 );
+       filter = QMAX( filter, 1 );
+
+       double step = 1.0 * ( H - ( lab - num + QABS( lab - num - 1 ) ) * textHeight - titleHeight ) / num;
+
+       int ascent = p->fontMetrics().ascent();
+       int colorWidth = QMAX( 5, QMIN( 20, W - textWidth - 3 * spacer ) );
+       if ( labPos == Center || !drawLabel )
+               colorWidth = W - 2 * spacer;
+
+       // Draw colors
+       int x = X + spacer;
+       switch ( labPos )
+       {
+       case Left:
+           x += textWidth + ( textWidth ? 1 : 0 ) * spacer;
+               break;
+       }
+
+       double offset = 1.0 * textHeight / 2 * ( lab - num + QABS( lab - num - 1 ) ) + titleHeight;
+       QValueList<QColor>::Iterator cit = colors.begin();
+  uint ci = 0;
+       for ( ci = 0; cit != colors.end() && drawColors; ++cit, ci++ )
+       {
+               int y = (int)( Y + ci * step + offset );
+               int h = (int)( Y + ( ci + 1 ) * step + offset ) - y;
+               p->fillRect( x, y, colorWidth, h, *cit );
+       }
+
+       if ( drawColors )
+               p->drawRect( int( x - 1 ), int( Y + offset - 1 ), int( colorWidth + 2 ), int( ci * step + 2 ) );
+
+       // Draw labels
+       offset = 1.0 * QABS( lab - num - 1 ) * ( step - textHeight ) / 2 +
+                                                1.0 * QABS( lab - num - 1 ) * textHeight / 2;
+       offset += titleHeight;
+       if ( drawLabel && !labels.isEmpty() )
+       {
+               int i1 = 0;
+               int i2 = lab - 1;
+               int last1( i1 ), last2( i2 );
+               int x = X + spacer;
+               switch ( labPos )
+               {
+               case Center:
+                       x += ( colorWidth - textWidth ) / 2;
+                       break;
+               case Right:
+                       x += colorWidth + spacer;
+                       break;
+               }
+               while ( i2 - i1 >= filter || ( i2 == 0 && i1 == 0 ) )
+               {
+                       int pos1 = i1;
+                       int pos2 = lab - 1 - i2;
+                       if ( filter && !( pos1 % filter ) )
+                       {
+                               p->drawText( x, (int)( Y + i1 * step + ascent + offset ), *labels.at( i1 ) );
+                               last1 = i1;
+                       }
+                       if ( filter && !( pos2 % filter ) )
+                       {
+                               p->drawText( x, (int)( Y + i2 * step + ascent + offset ), *labels.at( i2 ) );
+                               last2 = i2;
+                       }
+                       i1++;
+                       i2--;
+               }
+               int pos = i1;
+               int i0 = -1;
+               while ( pos <= i2 && i0 == -1 )
+               {
+                       if ( filter && !( pos % filter ) &&
+                                QABS( pos - last1 ) >= filter && QABS( pos - last2 ) >= filter )
+                               i0 = pos;
+                       pos++;
+               }
+
+               if ( i0 != -1 )
+                       p->drawText( x, (int)( Y + i0 * step + ascent + offset ), *labels.at( i0 ) );
+       }
+}
+
+//================================================================
+// Function : getFormat
+// Purpose  : Returns the format for number labels.
+//================================================================
+
+QString QtxColorScale::getFormat() const
+{
+       QString aFormat = format();
+
+       if ( !testFlags( PreciseFormat ) || testFlags( Integer ) )
+               return aFormat;
+
+       if ( !myPrecise.isEmpty() )
+               return myPrecise;
+
+       if ( aFormat.find( QRegExp( "^(%[0-9]*.?[0-9]*[fegFEG])$" ) ) != 0 )
+               return aFormat;
+
+       int pos1 = aFormat.find( '.' );
+       int pos2 = aFormat.find( QRegExp( "[fegFEG]") );
+
+       QString aLocFormat;
+       int precision = 1;
+       if ( pos1 > 0 )
+       {
+               aLocFormat = aFormat.mid( 0, pos1 + 1 );
+               precision = aFormat.mid( pos1 + 1, pos2 - pos1 - 1 ).toInt();
+               if ( precision < 1 )
+                       precision = 1;
+       }
+       else
+               return aFormat;
+  
+       QtxColorScale* that = (QtxColorScale*)this;
+
+       // calculate format, maximum precision limited
+       // to 7 digits after the decimal point.
+       while ( myPrecise.isEmpty() && precision < 7 )
+       {
+               QString aTmpFormat = aLocFormat;
+               aTmpFormat += QString( "%1" ).arg( precision );
+               aTmpFormat += aFormat.mid( pos2 );
+
+               QMap<QString, int> map;
+               bool isHasTwinz = false;
+
+               for ( int idx = 0; idx < intervalsNumber() && !isHasTwinz; idx++ )
+               {
+                       double val = getNumber( idx );
+                       QString tmpname = QString().sprintf( aTmpFormat, val );
+                       isHasTwinz = map.contains( tmpname );
+                       map.insert( tmpname, 1 );
+               }
+
+               if ( !isHasTwinz )
+                       that->myPrecise = aTmpFormat;
+               precision++;
+       }
+
+       if ( !myPrecise.isEmpty() )
+               aFormat = myPrecise;
+
+       return aFormat;
+}
+
+//================================================================
+// Function : getNumber
+// Purpose  : Returns the number for specified interval.
+//================================================================
+
+double QtxColorScale::getNumber( const int idx ) const
+{
+       double val = 0;
+       if ( intervalsNumber() > 0 )
+               val = minimum() + idx * ( QABS( maximum() - minimum() ) / intervalsNumber() );
+       return val;
+}
+
+//================================================================
+// Function : getLabel
+// Purpose  : Returns the label for specified interval according
+//            to the current label mode.
+//================================================================
+
+QString QtxColorScale::getLabel( const int idx ) const
+{
+       QString res;
+       if ( labelMode() == User )
+               res = label( idx );
+       else
+       {
+               double val = getNumber( idx );
+               res = QString().sprintf( getFormat(), testFlags( Integer ) ? (int)val : val );
+       }
+       return res;
+}
+
+//================================================================
+// Function : getColor
+// Purpose  : Returns the color for specified interval according
+//            to the current color mode.
+//================================================================
+
+QColor QtxColorScale::getColor( const int idx ) const
+{
+       QColor res;
+       if ( colorMode() == User )
+               res = color( idx );
+       else
+    res = Qtx::scaleColor( idx, 0, intervalsNumber() - 1 );
+       return res;
+}
+
+//================================================================
+// Function : updateScale
+// Purpose  : Update color scale if it required.
+//================================================================
+
+void QtxColorScale::updateScale()
+{
+  update();
+       updateGeometry();
+}
+
+//================================================================
+// Function : simpleRichText
+// Purpose  : Return QSimpleRichText object for title. If title
+//            not defined (empty string) then return null pointer.
+//            Object should be deleted by caller function.
+//================================================================
+
+QSimpleRichText* QtxColorScale::simpleRichText( const int flags ) const
+{
+       QSimpleRichText* srt = 0;
+
+       QString aTitle;
+       switch ( titlePosition() )
+       {
+       case Left:
+               aTitle = QString( "<p align=\"left\">%1</p>" );
+               break;
+       case Right:
+               aTitle = QString( "<p align=\"right\">%1</p>" );
+               break;
+       case Center:
+               aTitle = QString( "<p align=\"center\">%1</p>" );
+               break;
+       case None:
+       default:
+               break;
+       }
+
+       if ( !aTitle.isEmpty() && !title().isEmpty() )
+       {
+               if ( !myStyleSheet )
+               {
+                       QtxColorScale* that = (QtxColorScale*)this;
+                       that->myStyleSheet = new QStyleSheet( that );
+               }
+
+               if ( myStyleSheet )
+               {
+                       QStyleSheetItem* item = myStyleSheet->item( "p" );
+                       if ( item )
+                               item->setWhiteSpaceMode( flags & WrapTitle ? QStyleSheetItem::WhiteSpaceNormal :
+                                                                                                                    QStyleSheetItem::WhiteSpaceNoWrap );
+               }
+
+               aTitle = aTitle.arg( title() );
+               srt = new QSimpleRichText( aTitle, font(), QString::null, myStyleSheet );
+       }
+
+       return srt;
+}
+
+#if QT_VER == 3
+
+/*********************************************************************
+**  Class:  QtxColorScale::Dock
+**  Descr:  Dockable window contains the color scale.
+**  Level:  Public
+*********************************************************************/
+
+//================================================================
+// Function : Dock
+// Purpose  : Constructor.
+//================================================================
+
+QtxColorScale::Dock::Dock( Place p, QWidget* parent, const char* name, WFlags f )
+: QDockWindow( p, parent, name, f ),
+myBlockShow( false ),
+myBlockResize( false )
+{
+       myScale = new QtxColorScale( this );
+
+       setWidget( myScale );
+
+       setCloseMode( Always );
+       setMovingEnabled( true );
+       setResizeEnabled( true );
+       setHorizontalStretchable( false );
+
+       setCaption( tr ( "Color scale" ) );
+}
+
+//================================================================
+// Function : ~Dock
+// Purpose  : Destructor.
+//================================================================
+
+QtxColorScale::Dock::~Dock()
+{
+}
+
+//================================================================
+// Function : colorScale
+// Purpose  : Returns color scale widget.
+//================================================================
+
+QtxColorScale* QtxColorScale::Dock::colorScale() const
+{
+       return myScale;
+}
+
+//================================================================
+// Function : activate
+// Purpose  : Set the dockable window is visible for main window.
+//================================================================
+
+void QtxColorScale::Dock::activate()
+{
+       if ( myBlockShow )
+               return;
+
+       QMainWindow* mw = 0;
+       QWidget* p = parentWidget();
+       while ( !mw && p )
+       {
+               if ( p->inherits( "QMainWindow" ) )
+                       mw = (QMainWindow*)p;
+               p = p->parentWidget();
+       }
+       if ( mw )
+               mw->setAppropriate( this, true );
+}
+
+//================================================================
+// Function : deactivate
+// Purpose  : Set the dockable window is hidden for main window.
+//================================================================
+
+void QtxColorScale::Dock::deactivate()
+{
+       if ( myBlockShow )
+               return;
+
+       QMainWindow* mw = 0;
+       QWidget* p = parentWidget();
+       while ( !mw && p )
+       {
+               if ( p->inherits( "QMainWindow" ) )
+                       mw = (QMainWindow*)p;
+               p = p->parentWidget();
+       }
+       if ( mw )
+               mw->setAppropriate( this, false );
+}
+
+//================================================================
+// Function : isActive
+// Purpose  : Returns true if the dockable window is visible.
+//================================================================
+
+bool QtxColorScale::Dock::isActive() const
+{
+       QMainWindow* mw = 0;
+       QWidget* p = parentWidget();
+       while ( !mw && p )
+       {
+               if ( p->inherits( "QMainWindow" ) )
+                       mw = (QMainWindow*)p;
+               p = p->parentWidget();
+       }
+       if ( mw )
+               return mw->appropriate( (QDockWindow*)this );
+       else
+               return false;
+}
+
+//================================================================
+// Function : show
+// Purpose  : Reimplemented for internal reasons.
+//================================================================
+
+void QtxColorScale::Dock::show()
+{
+       bool f = myBlockShow;
+       myBlockShow = true;
+       QDockWindow::show();
+       myBlockShow = f;
+}
+
+//================================================================
+// Function : hide
+// Purpose  : Reimplemented for internal reasons.
+//================================================================
+
+void QtxColorScale::Dock::hide()
+{
+       bool f = myBlockShow;
+       myBlockShow = false;
+       QDockWindow::hide();
+       myBlockShow = f;
+}
+
+//================================================================
+// Function : resize
+// Purpose  : Make extent width as maximum value of widget width.
+//================================================================
+
+void QtxColorScale::Dock::resize( int w, int h )
+{
+       QDockWindow::resize( w, h );
+
+       if ( myBlockResize )
+               return;
+
+       if ( orientation() == Qt::Vertical )
+               setFixedExtentWidth( QMAX( fixedExtent().width(), w ) );
+       else if ( orientation() == Qt::Horizontal )
+               setFixedExtentHeight( QMAX( fixedExtent().height(), h ) );
+}
+
+//================================================================
+// Function : setOrientation
+// Purpose  : 
+//================================================================
+
+void QtxColorScale::Dock::setOrientation( Orientation o )
+{
+       bool b = myBlockResize;
+       myBlockResize = true;
+       QDockWindow::setOrientation( o );
+       myBlockResize = b;
+}
+
+#endif
diff --git a/src/Qtx/QtxDblSpinBox.cxx b/src/Qtx/QtxDblSpinBox.cxx
new file mode 100755 (executable)
index 0000000..0812592
--- /dev/null
@@ -0,0 +1,473 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxDblSpinBox.cxx
+// Author:    Sergey TELKOV
+
+#include "QtxDblSpinBox.h"
+
+#include <qlineedit.h>
+#include <qvalidator.h>
+#include <qapplication.h>
+
+/*
+       Class: QtxDblSpinBox::Validator [internal]
+       Descr: Validator for QtxDblSpinBox (getted from Trolltech Qt - SpinBoxValidator)
+*/
+
+class QtxDblSpinBox::Validator : public QDoubleValidator
+{
+public:
+    Validator( QtxDblSpinBox* sb, const char* name )
+       : QDoubleValidator( sb, name ), spinBox( sb ) {}
+
+    virtual State validate( QString& str, int& pos ) const;
+
+private:
+    QtxDblSpinBox* spinBox;
+};
+
+QValidator::State QtxDblSpinBox::Validator::validate( QString& str, int& pos ) const
+{
+  QString pref = spinBox->prefix();
+  QString suff = spinBox->suffix();
+  uint overhead = pref.length() + suff.length();
+  State state = Invalid;
+
+  if ( overhead == 0 )
+         state = QDoubleValidator::validate( str, pos );
+  else
+       {
+               if ( str.length() >= overhead && str.startsWith( pref ) &&
+         str.right( suff.length() ) == suff )
+               {
+                       QString core = str.mid( pref.length(), str.length() - overhead );
+                       int corePos = pos - pref.length();
+                       state = QDoubleValidator::validate( core, corePos );
+                       pos = corePos + pref.length();
+                       str.replace( pref.length(), str.length() - overhead, core );
+               }
+               else
+               {
+                       state = QDoubleValidator::validate( str, pos );
+                       if ( state == Invalid )
+                       {
+                               QString special = spinBox->specialValueText().stripWhiteSpace();
+                               QString candidate = str.stripWhiteSpace();
+                               if ( special.startsWith( candidate ) )
+                               {
+                                       if ( candidate.length() == special.length() )
+                                               state = Acceptable;
+                                       else
+                                               state = Intermediate;
+                               }
+                       }
+               }
+  }
+  return state;
+}
+
+/*
+       Class: QtxDblSpinBox
+       Descr: Spin box for real numbers.
+*/
+
+QtxDblSpinBox::QtxDblSpinBox( QWidget* parent, const char* name )
+: QSpinBox( parent, name ),
+myCleared( false ),
+myBlocked( false ),
+myPrecision( 0 )
+{
+  myMin = QRangeControl::minValue();
+  myMax = QRangeControl::maxValue();
+  myStep = QRangeControl::lineStep();
+       myValue = myMin;
+  setValidator( new Validator( this, "double_spinbox_validator" ) );
+  rangeChange();
+  updateDisplay();
+
+  connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
+}
+
+QtxDblSpinBox::QtxDblSpinBox( double min, double max, double step, QWidget* parent, const char* name )
+: QSpinBox( parent, name ),
+myMin( min ),
+myMax( max ),
+myStep( step ),
+myCleared( false ),
+myBlocked( false ),
+myPrecision( 0 )
+{
+       myValue = myMin;
+  setValidator( new Validator( this, "double_spinbox_validator" ) );
+  rangeChange();
+  updateDisplay();
+
+  connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
+}
+
+QtxDblSpinBox::~QtxDblSpinBox()
+{
+}
+
+double QtxDblSpinBox::minValue() const
+{
+  return myMin;
+}
+
+double QtxDblSpinBox::maxValue() const
+{
+  return myMax;
+}
+
+void QtxDblSpinBox::setMinValue( int min )
+{
+       setMinValue( (double)min );
+}
+
+void QtxDblSpinBox::setMinValue( double min )
+{
+  if ( myMin != min )
+  {
+    myMin = min;
+    rangeChange();
+  }
+}
+
+void QtxDblSpinBox::setMaxValue( int max )
+{
+       setMaxValue( (double)max );
+}
+
+void QtxDblSpinBox::setMaxValue( double max )
+{
+  if ( myMax != max )
+  {
+    myMax = max;
+    rangeChange();
+  }
+}
+
+void QtxDblSpinBox::setRange( int min, int max )
+{
+       setRange( (double)min, (double)max );
+}
+
+void QtxDblSpinBox::setRange( double min, double max )
+{
+  if ( myMin != min || myMax != max )
+  {
+    myMin = min;
+    myMax = max;
+    rangeChange();
+  }
+}
+
+double QtxDblSpinBox::lineStep() const
+{
+  return myStep;
+}
+
+void QtxDblSpinBox::setLineStep( int step )
+{
+  setLineStep( (double)step );
+}
+
+void QtxDblSpinBox::setLineStep( double step )
+{
+  myStep = step;
+}
+
+double QtxDblSpinBox::value() const
+{
+  QSpinBox::value();
+
+  return myValue;
+}
+
+void QtxDblSpinBox::setValue( int val )
+{
+       setValue( (double)val );
+}
+
+void QtxDblSpinBox::setValue( double val )
+{
+       myCleared = false;
+  double prevVal = myValue;
+  myValue = bound( val );
+  if ( prevVal != myValue )
+    valueChange();
+}
+
+void QtxDblSpinBox::stepUp()
+{
+       interpretText();
+       if ( wrapping() && myValue + myStep > myMax )
+               setValue( myMin );
+       else
+               setValue( myValue + myStep );
+}
+
+void QtxDblSpinBox::stepDown()
+{
+       interpretText();
+       if ( wrapping() && myValue - myStep < myMin )
+               setValue( myMax );
+       else
+               setValue( myValue - myStep );
+}
+
+int QtxDblSpinBox::precision() const
+{
+       return myPrecision;
+}
+
+void QtxDblSpinBox::setPrecision( const int prec )
+{
+       int newPrec = QMAX( prec, 0 );
+       int oldPrec = QMAX( myPrecision, 0 );
+       myPrecision = prec;
+       if ( newPrec != oldPrec )
+               updateDisplay();
+}
+
+bool QtxDblSpinBox::isCleared() const
+{
+       return myCleared;
+}
+
+void QtxDblSpinBox::setCleared( const bool on )
+{
+       if ( myCleared == on )
+               return;
+
+       myCleared = on;
+       updateDisplay();
+}
+
+void QtxDblSpinBox::selectAll()
+{
+#if QT_VER >= 3
+       QSpinBox::selectAll();
+#else
+  editor()->selectAll();
+#endif
+}
+
+bool QtxDblSpinBox::eventFilter( QObject* o, QEvent* e )
+{
+  if ( !myCleared || o != editor() || !editor()->text().stripWhiteSpace().isEmpty() )
+  {
+    bool state = QSpinBox::eventFilter( o, e );
+    if ( e->type() == QEvent::FocusOut && o == editor() )
+      updateDisplay();
+    return state;
+  }
+
+  if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Leave || e->type() == QEvent::Hide )
+    return false;
+
+  if ( e->type() == QEvent::KeyPress &&
+         ( ((QKeyEvent*)e)->key() == Key_Tab || ((QKeyEvent*)e)->key() == Key_BackTab ) )
+  {
+    QApplication::sendEvent( this, e );
+    return true;
+  }
+
+  return QSpinBox::eventFilter( o, e );
+}
+
+void QtxDblSpinBox::updateDisplay()
+{
+  if ( myBlocked )
+    return;
+
+  bool upd = editor()->isUpdatesEnabled();
+  editor()->setUpdatesEnabled( false );
+
+  bool isBlock = myBlocked;
+  myBlocked = true;
+    
+  QString txt = currentValueText();
+    
+  if ( myValue >= myMax )
+    QSpinBox::setValue( QSpinBox::maxValue() );
+  else if ( myValue <= myMin )
+    QSpinBox::setValue( QSpinBox::minValue() );
+  else
+    QSpinBox::setValue( ( QSpinBox::minValue() + QSpinBox::maxValue() ) / 2 );
+  
+  QSpinBox::updateDisplay();
+
+  editor()->setUpdatesEnabled( upd );
+
+  editor()->setText( myCleared ? QString::null : txt );
+  if ( !myCleared && editor()->hasFocus() )
+  {
+    if ( editor()->text() == specialValueText() )
+      editor()->selectAll();
+    else
+      editor()->setSelection( prefix().length(), editor()->text().length() - prefix().length() - suffix().length() );
+  }
+  else
+    editor()->setCursorPosition( 0 );
+
+  myBlocked = isBlock;
+}
+
+void QtxDblSpinBox::interpretText()
+{
+  myCleared = false;
+
+  bool ok = true;
+  bool done = false;
+  double newVal = 0;
+  if ( !specialValueText().isEmpty() )
+  {
+         QString s = QString( text() ).stripWhiteSpace();
+         QString t = QString( specialValueText() ).stripWhiteSpace();
+         if ( s == t )
+    {
+      newVal = minValue();
+           done = true;
+    }
+  }
+  if ( !done )
+         newVal = mapTextToDoubleValue( &ok );
+  if ( ok )
+         setValue( newVal );
+  updateDisplay();
+}
+
+void QtxDblSpinBox::valueChange()
+{
+  updateDisplay();
+  emit valueChanged( myValue );
+  emit valueChanged( currentValueText() );
+}
+
+void QtxDblSpinBox::rangeChange()
+{
+  double min = QMIN( myMin, myMax );
+  double max = QMAX( myMin, myMax );
+  myMin = min;
+  myMax = max;
+  QDoubleValidator* v = ::qt_cast<QDoubleValidator*>( validator() );
+  if ( v )
+    v->setRange( myMin, myMax );
+
+       if ( myMin == myMax )
+               QSpinBox::setRange( 0, 0 );
+       else
+               QSpinBox::setRange( 0, 2 );
+
+  setValue( myValue );
+  updateDisplay();
+}
+
+QString QtxDblSpinBox::currentValueText()
+{
+  QString s;
+  if ( (myValue == minValue()) && !specialValueText().isEmpty() )
+         s = specialValueText();
+  else
+       {
+         s = prefix();
+               s.append( mapValueToText( myValue ) );
+               s.append( suffix() );
+       }
+  return s;
+}
+
+QString QtxDblSpinBox::mapValueToText( double v )
+{
+       QString s;
+  s.setNum( v, myPrecision >= 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
+  return removeTrailingZeroes( s );
+}
+
+QString QtxDblSpinBox::mapValueToText( int )
+{
+  QString s;
+  s.setNum( myValue, myPrecision >= 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
+  return removeTrailingZeroes( s );
+}
+
+double QtxDblSpinBox::mapTextToDoubleValue( bool* ok )
+{
+  QString s = text();
+  double newVal = s.toDouble( ok );
+  if ( !(*ok) && !( !prefix() && !suffix() ) )
+  {
+         s = cleanText();
+         newVal = s.toDouble( ok );
+  }
+  return newVal;
+}
+
+double QtxDblSpinBox::bound( double val )
+{
+  double newVal = val;
+  if ( newVal > myMax )
+    newVal = myMax;
+  if ( newVal < myMin )
+    newVal = myMin;
+  return newVal;
+}
+
+void QtxDblSpinBox::leaveEvent( QEvent* e )
+{
+       if ( !myCleared )
+               QSpinBox::leaveEvent( e );
+}
+
+void QtxDblSpinBox::wheelEvent( QWheelEvent* e )
+{
+  if ( !isEnabled() )
+    return;
+
+  QSpinBox::wheelEvent( e );
+  updateDisplay();
+}
+
+void QtxDblSpinBox::onTextChanged( const QString& str )
+{
+  if ( !myBlocked )
+    myCleared = false;
+}
+
+QString QtxDblSpinBox::removeTrailingZeroes( const QString& src ) const
+{
+  QString delim( "." );
+
+  int idx = src.findRev( delim );
+  if ( idx == -1 )
+    return src;
+
+  QString iPart = src.left( idx );
+  QString fPart = src.mid( idx + 1 );
+
+  while ( !fPart.isEmpty() && fPart.at( fPart.length() - 1 ) == '0' )
+    fPart.remove( fPart.length() - 1, 1 );
+
+  QString res = iPart;
+  if ( !fPart.isEmpty() )
+    res += delim + fPart;
+
+  return res;
+}
diff --git a/src/Qtx/QtxListResourceEdit.cxx b/src/Qtx/QtxListResourceEdit.cxx
new file mode 100644 (file)
index 0000000..75e74e9
--- /dev/null
@@ -0,0 +1,1424 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxListResourceEdit.cxx
+// Author:    Sergey TELKOV
+
+#include "QtxListResourceEdit.h"
+
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qcombobox.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qtabwidget.h>
+#include <qvalidator.h>
+#include <qobjectlist.h>
+#include <qcolordialog.h>
+#include <qwidgetstack.h>
+#include <qtoolbutton.h>
+#include <qfontdialog.h>
+#include <qfontdatabase.h>
+#include <qfileinfo.h>
+#include <qfiledialog.h>
+
+#include "QtxIntSpinBox.h"
+#include "QtxDblSpinBox.h"
+#include "QtxComboBox.h"
+#include "QtxDirListEditor.h"
+
+/*
+  Class: QtxListResourceEdit
+  Descr: GUI implementation of QtxResourceEdit - manager of resources
+*/
+
+QtxListResourceEdit::QtxListResourceEdit( QtxResourceMgr* mgr, QWidget* parent )
+: QFrame( parent ),
+QtxResourceEdit( mgr )
+{
+  QVBoxLayout* main = new QVBoxLayout( this, 0, 5 );
+  QGroupBox* base = new QGroupBox( 1, Qt::Vertical, "", this );
+  base->setFrameStyle( QFrame::NoFrame );
+  base->setInsideMargin( 0 );
+  main->addWidget( base );
+
+  myList  = new QListBox( base );
+  myStack = new QWidgetStack( base );
+
+  myList->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
+  myStack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+
+  myList->setSelectionMode( QListBox::Single );
+
+  connect( myList, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) );
+
+  setFocusProxy( myList );
+
+  updateState();
+}
+
+QtxListResourceEdit::~QtxListResourceEdit()
+{
+}
+
+void QtxListResourceEdit::setItemProperty( const int id, const QString& prop, const QVariant& val )
+{
+  Item* i = item( id );
+  if ( !i )
+    return;
+
+  bool prev = i->isEmpty();
+
+  QtxResourceEdit::setItemProperty( id, prop, val );
+
+  bool next = i->isEmpty();
+
+  if ( prev != next )
+    updateVisible();
+}
+
+void QtxListResourceEdit::onSelectionChanged()
+{
+  QString title = myList->text( myList->index( myList->selectedItem() ) );
+  if ( title.isEmpty() )
+    return;
+
+  Item* i = 0;
+  QPtrList<Item> lst;
+  childItems( lst );
+  for ( QPtrListIterator<Item> it( lst ); it.current() && !i; ++it )
+  {
+    if ( it.current()->title() == title )
+      i = it.current();
+  }
+
+  if ( i )
+    myStack->raiseWidget( i->id() );
+}
+
+void QtxListResourceEdit::itemAdded( QtxResourceEdit::Item* i )
+{
+  if ( !i )
+    return;
+
+  QPtrList<Item> items;
+  childItems( items );
+
+  if ( items.contains( i ) || items.contains( i->parentItem() ) )
+    updateVisible();
+}
+
+QtxResourceEdit::Item* QtxListResourceEdit::createItem( const QString& title, const int )
+{
+  Item* i = item( title, -1 );
+  if ( i )
+    return i;
+
+  Category* category = new Category( this, myStack );
+  myStack->addWidget( category, category->id() );
+
+  updateVisible();
+
+  if ( !myList->selectedItem() )
+    myList->setSelected( 0, true );
+
+  updateState();
+
+  return category;
+}
+
+void QtxListResourceEdit::changedResources( const QMap<Item*, QString>& map )
+{
+  QMap<int, QString> idMap;
+  for ( QMap<Item*, QString>::ConstIterator it = map.begin(); it != map.end(); ++it )
+  {
+    idMap.insert( it.key()->id(), it.data() );
+
+    emit resourceChanged( it.key()->id() );
+
+    QString sec, param;
+    it.key()->resource( sec, param );
+    emit resourceChanged( sec, param );
+  }
+
+  emit resourcesChanged( idMap );
+}
+
+void QtxListResourceEdit::updateState()
+{
+  if ( myList->selectedItem() &&  myStack->visibleWidget() )
+    myStack->show();
+  else
+    myStack->hide();
+}
+
+void QtxListResourceEdit::updateVisible()
+{
+  QPtrList<Item> items;
+  childItems( items );
+
+  QString name = myList->text( myList->index( myList->selectedItem() ) );
+
+  myList->clear();
+  for ( QPtrListIterator<Item> it( items ); it.current(); ++it )
+  {
+    if ( it.current()->isEmpty() )
+      continue;
+
+    myList->insertItem( it.current()->title() );
+  }
+
+  int idx = -1;
+  for ( int i = 0; i < (int)myList->count() && idx == -1; i++ )
+  {
+    if ( myList->text( i ) == name )
+      idx = i;
+  }
+
+  myList->setSelected( QMAX( idx, 0 ), true );
+
+  updateState();
+}
+
+/*
+  Class: QtxListResourceEdit::Category
+  Descr: GUI implementation of preferences category.
+*/
+
+QtxListResourceEdit::Category::Category( QtxListResourceEdit* edit, QWidget* parent )
+: QFrame( parent ),
+Item( edit )
+{
+  QVBoxLayout* main = new QVBoxLayout( this );
+  QGroupBox* base = new QGroupBox( 1, Qt::Horizontal, "", this );
+  base->setFrameStyle( QFrame::NoFrame );
+  base->setInsideMargin( 0 );
+  main->addWidget( base, 1 );
+
+  myTabs = new QTabWidget( base );
+  myInfo = new QLabel( base );
+
+  myInfo->setAlignment( Qt::AlignCenter );
+  myInfo->setFrameStyle( QFrame::WinPanel | QFrame::Raised );
+  myInfo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+
+  updateState();
+}
+
+QtxListResourceEdit::Category::~Category()
+{
+}
+
+bool QtxListResourceEdit::Category::isEmpty() const
+{
+  return Item::isEmpty() && myInfo->text().isEmpty();
+}
+
+int QtxListResourceEdit::Category::type() const
+{
+  return -1;
+}
+
+void QtxListResourceEdit::Category::store()
+{
+}
+
+void QtxListResourceEdit::Category::retrieve()
+{
+}
+
+QVariant QtxListResourceEdit::Category::property( const QString& prop ) const
+{
+  QVariant var;
+  if ( prop == QString( "information" ) || prop == QString( "info" ) )
+    var = myInfo->text();
+  return var;
+}
+
+void QtxListResourceEdit::Category::setProperty( const QString& name, const QVariant& var )
+{
+  QVariant prop = var;
+  if ( !prop.cast( QVariant::String ) )
+    return;
+
+  if ( name == QString( "information" ) || name == QString( "info" ) )
+    myInfo->setText( prop.toString() );
+
+  updateState();
+}
+
+QtxResourceEdit::Item* QtxListResourceEdit::Category::createItem( const QString& title, const int )
+{
+  Item* i = item( title, id() );
+  if ( i )
+    return i;
+
+  Tab* tab = new Tab( resourceEdit(), this, this );
+  myTabs->addTab( tab, title );
+
+  updateState();
+
+  return tab;
+}
+
+void QtxListResourceEdit::Category::updateState()
+{
+  if ( myTabs->count() )
+    myTabs->show();
+  else
+    myTabs->hide();
+
+  if ( !myTabs->count() && !myInfo->text().isEmpty() )
+    myInfo->show();
+  else
+    myInfo->hide();
+}
+
+/*
+  Class: QtxListResourceEdit::Tab
+  Descr: GUI implementation of resources tab.
+*/
+
+QtxListResourceEdit::Tab::Tab( QtxResourceEdit* edit, Item* pItem, QWidget* parent )
+: QFrame( parent ),
+Item( edit, pItem )
+{
+  QVBoxLayout* main = new QVBoxLayout( this );
+  QVBox* vbox = new QVBox( this );
+  vbox->setMargin( 5 );
+  myMainFrame = vbox;
+  main->addWidget( myMainFrame );
+  main->addStretch( 1 );
+}
+
+QtxListResourceEdit::Tab::~Tab()
+{
+}
+
+int QtxListResourceEdit::Tab::type() const
+{
+  return -1;
+}
+
+void QtxListResourceEdit::Tab::store()
+{
+}
+
+void QtxListResourceEdit::Tab::retrieve()
+{
+}
+
+void QtxListResourceEdit::Tab::polish()
+{
+  QFrame::polish();
+
+  adjustLabels();
+}
+
+QtxResourceEdit::Item* QtxListResourceEdit::Tab::createItem( const QString& title, const int )
+{
+  Item* i = item( title, id() );
+  if ( i )
+    return i;
+
+  Group* group = new Group( title, resourceEdit(), this, myMainFrame );
+
+  return group;
+}
+
+void QtxListResourceEdit::Tab::adjustLabels()
+{
+  QObjectList* labels = queryList( "QLabel" );
+  if ( labels )
+  {
+    int w = 0;
+    for ( QObjectListIt it1( *labels ); it1.current(); ++it1 )
+    {
+      if ( it1.current()->isWidgetType() )
+      {
+        QWidget* wid = (QWidget*)it1.current();
+        w = QMAX( w, wid->sizeHint().width() );
+      }
+    }
+    for ( QObjectListIt it2( *labels ); it2.current(); ++it2 )
+    {
+      if ( it2.current()->isWidgetType() )
+      {
+        QWidget* wid = (QWidget*)it2.current();
+        wid->setMinimumWidth( w );
+      }
+    }
+    delete labels;
+  }
+}
+
+/*
+  Class: QtxListResourceEdit::Group
+  Descr: GUI implementation of resources group.
+*/
+
+QtxListResourceEdit::Group::Group( const QString& title, QtxResourceEdit* edit, Item* pItem, QWidget* parent )
+: QGroupBox( 2, Qt::Horizontal, title, parent ),
+Item( edit, pItem )
+{
+}
+
+QtxListResourceEdit::Group::~Group()
+{
+}
+
+int QtxListResourceEdit::Group::type() const
+{
+  return -1;
+}
+
+void QtxListResourceEdit::Group::store()
+{
+}
+
+void QtxListResourceEdit::Group::retrieve()
+{
+}
+
+QVariant QtxListResourceEdit::Group::property( const QString& prop ) const
+{
+  QVariant var;
+  if ( prop == "columns" )
+    var = QVariant( columns() );
+  else if ( prop == "orientation" )
+    var = QVariant( orientation() );
+  else if ( prop == "frame" )
+    var = QVariant( frameStyle() != QFrame::NoFrame );
+  return var;
+}
+
+void QtxListResourceEdit::Group::setProperty( const QString& name, const QVariant& var )
+{
+  QVariant prop = var;
+  if ( !prop.cast( QVariant::Int ) )
+    return;
+
+  if ( name == QString( "columns" ) && prop.cast( QVariant::Int ) && prop.toInt() > 0 )
+    setColumns( prop.toInt() );
+  else if ( name == QString( "orientation" ) && prop.cast( QVariant::Int ) )
+  {
+    int o = prop.toInt();
+    if ( o == Qt::Horizontal || o == Qt::Vertical )
+      setOrientation( (Orientation)o );
+  }
+  else if ( name == "frame" && prop.cast( QVariant::Bool ) )
+  {
+    setInsideMargin( prop.toBool() ? 5 : 0 );
+    QGroupBox::setTitle( prop.toBool() ? Item::title() : QString::null );
+    setFrameStyle( prop.toBool() ? QFrame::Box | QFrame::Sunken : QFrame::NoFrame );
+  }
+}
+
+void QtxListResourceEdit::Group::setTitle( const QString& title )
+{
+  Item::setTitle( title );
+  QGroupBox::setTitle( title );
+}
+
+QtxResourceEdit::Item* QtxListResourceEdit::Group::createItem( const QString& title, const int type )
+{
+  Item* item = 0;
+
+  switch ( type )
+  {
+  case Color:
+    item = new ColorItem( title, resourceEdit(), this, this );
+    break;
+  case Bool:
+    item = new StateItem( title, resourceEdit(), this, this );
+    break;
+  case String:
+    item = new StringItem( title, resourceEdit(), this, this );
+    break;
+  case Selector:
+    item = new SelectItem( title, resourceEdit(), this, this );
+    break;
+  case DblSpin:
+    item = new DoubleSpinItem( title, resourceEdit(), this, this );
+    break;
+  case IntSpin:
+    item = new IntegerSpinItem( title, resourceEdit(), this, this );
+    break;
+  case Double:
+    item = new DoubleEditItem( title, resourceEdit(), this, this );
+    break;
+  case Integer:
+    item = new IntegerEditItem( title, resourceEdit(), this, this );
+    break;
+  case Space:
+    item = new Spacer( resourceEdit(), this, this );
+    break;
+  case GroupBox:
+    item = new Group( title, resourceEdit(), this, this );
+    break;
+  case Font:
+    item = new FontItem( title, resourceEdit(), this, this );
+    break;
+  case DirList:
+    item = new DirListItem( title, resourceEdit(), this, this );
+    break;
+  case File:
+    item = new FileItem( title, resourceEdit(), this, this );
+    break;
+  }
+
+  return item;
+}
+
+/*
+  Class: QtxListResourceEdit::PrefItem
+  Descr: Base class for preferences items.
+*/
+
+QtxListResourceEdit::PrefItem::PrefItem( const int type, QtxResourceEdit* edit, Item* pi, QWidget* parent )
+: QHBox( parent ),
+Item( edit, pi ),
+myType( type )
+{
+  setSpacing( 5 );
+}
+
+QtxListResourceEdit::PrefItem::~PrefItem()
+{
+}
+
+int QtxListResourceEdit::PrefItem::type() const
+{
+  return myType;
+}
+
+QtxResourceEdit::Item* QtxListResourceEdit::PrefItem::createItem( const QString&, const int )
+{
+  return 0;
+}
+
+/*
+  Class: QtxListResourceEdit::Spacer
+  Descr: GUI implementation of resources spacer.
+*/
+
+QtxListResourceEdit::Spacer::Spacer( QtxResourceEdit* edit, Item* pItem, QWidget* parent )
+: PrefItem( Space, edit, pItem, parent )
+{
+  setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::Spacer::~Spacer()
+{
+}
+
+void QtxListResourceEdit::Spacer::store()
+{
+}
+
+void QtxListResourceEdit::Spacer::retrieve()
+{
+}
+
+/*
+  Class: QtxListResourceEdit::SelectItem
+  Descr: GUI implementation of resources list item.
+*/
+
+QtxListResourceEdit::SelectItem::SelectItem( const QString& title, QtxResourceEdit* edit,
+                                            Item* pItem, QWidget* parent )
+: PrefItem( Selector, edit, pItem, parent )
+{
+  new QLabel( title, this );
+  myList = new QComboBox( false, this );
+  myList->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::SelectItem::~SelectItem()
+{
+}
+
+void QtxListResourceEdit::SelectItem::store()
+{
+  int idx = myList->currentItem();
+  if ( myIndex.contains( idx ) )
+    setInteger( myIndex[idx] );
+}
+
+void QtxListResourceEdit::SelectItem::retrieve()
+{
+  int id = getInteger( -1 );
+
+  int idx = -1;
+  for ( QMap<int, int>::ConstIterator it = myIndex.begin(); it != myIndex.end() && idx == -1; ++it )
+  {
+    if ( it.data() == id )
+      idx = it.key();
+  }
+
+  myList->setCurrentItem( idx );
+}
+
+QVariant QtxListResourceEdit::SelectItem::property( const QString& name ) const
+{
+  QVariant val;
+  if ( name == QString( "strings" ) )
+  {
+    QStringList lst;
+    for ( int i = 0; i < (int)myList->count(); i++ )
+      lst.append( myList->text( i ) );
+    val = QVariant( lst );
+  }
+  else if ( name == QString( "indexes" ) )
+  {
+    QValueList<QVariant> lst;
+    for ( int i = 0; i < (int)myList->count(); i++ )
+      lst.append( myIndex.contains( i ) ? myIndex[i] : 0 );
+    val = QVariant( lst );
+  }
+  return val;
+}
+
+void QtxListResourceEdit::SelectItem::setProperty( const QString& name, const QVariant& val )
+{
+  if ( name == QString( "strings" ) )
+    setStrings( val );
+  else if ( name == QString( "indexes" ) )
+    setIndexes( val );
+}
+
+void QtxListResourceEdit::SelectItem::setStrings( const QVariant& var )
+{
+  if ( var.type() != QVariant::StringList )
+    return;
+
+  setStrings( var.toStringList() );
+}
+
+void QtxListResourceEdit::SelectItem::setIndexes( const QVariant& var )
+{
+  if ( var.type() != QVariant::List )
+    return;
+
+  QValueList<QVariant> varList = var.toList();
+  QValueList<int> lst;
+  for ( QValueList<QVariant>::const_iterator it = varList.begin(); it != varList.end(); ++it )
+  {
+    if ( (*it).canCast( QVariant::Int ) )
+      lst.append( (*it).toInt() );
+  }
+  setIndexes( lst );
+}
+
+void QtxListResourceEdit::SelectItem::setStrings( const QStringList& lst )
+{
+  myList->clear();
+  myList->insertStringList( lst );
+}
+
+void QtxListResourceEdit::SelectItem::setIndexes( const QValueList<int>& lst )
+{
+  myIndex.clear();
+
+  int idx = 0;
+  for ( QValueList<int>::const_iterator it = lst.begin(); it != lst.end(); ++it, idx++ )
+    myIndex.insert( idx, *it );
+}
+
+/*
+  Class: QtxListResourceEdit::StateItem
+  Descr: GUI implementation of resources bool item.
+*/
+
+QtxListResourceEdit::StateItem::StateItem( const QString& title, QtxResourceEdit* edit,
+                                           Item* pItem, QWidget* parent )
+: PrefItem( Bool, edit, pItem, parent )
+{
+  myState = new QCheckBox( title, this );
+  myState->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::StateItem::~StateItem()
+{
+}
+
+void QtxListResourceEdit::StateItem::store()
+{
+  setBoolean( myState->isChecked() );
+}
+
+void QtxListResourceEdit::StateItem::retrieve()
+{
+  myState->setChecked( getBoolean() );
+}
+
+/*
+  Class: QtxListResourceEdit::StringItem
+  Descr: GUI implementation of resources string item.
+*/
+
+QtxListResourceEdit::StringItem::StringItem( const QString& title, QtxResourceEdit* edit,
+                                             Item* pItem, QWidget* parent )
+: PrefItem( String, edit, pItem, parent )
+{
+  new QLabel( title, this );
+  myString = new QLineEdit( this );
+  myString->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::StringItem::~StringItem()
+{
+}
+
+void QtxListResourceEdit::StringItem::store()
+{
+  setString( myString->text() );
+}
+
+void QtxListResourceEdit::StringItem::retrieve()
+{
+  myString->setText( getString() );
+}
+
+/*
+  Class: QtxListResourceEdit::IntegerEditItem
+  Descr: GUI implementation of resources integer item.
+*/
+
+QtxListResourceEdit::IntegerEditItem::IntegerEditItem( const QString& title, QtxResourceEdit* edit, Item* pItem, QWidget* parent )
+: PrefItem( Integer, edit, pItem, parent )
+{
+  new QLabel( title, this );
+  myInteger = new QLineEdit( this );
+  myInteger->setValidator( new QIntValidator( myInteger ) );
+  myInteger->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::IntegerEditItem::~IntegerEditItem()
+{
+}
+
+void QtxListResourceEdit::IntegerEditItem::store()
+{
+  setString( myInteger->text() );
+}
+
+void QtxListResourceEdit::IntegerEditItem::retrieve()
+{
+  myInteger->setText( getString() );
+}
+
+/*
+  Class: QtxListResourceEdit::IntegerSpinItem
+  Descr: GUI implementation of resources integer item.
+*/
+
+QtxListResourceEdit::IntegerSpinItem::IntegerSpinItem( const QString& title, QtxResourceEdit* edit, Item* pItem, QWidget* parent )
+: PrefItem( IntSpin, edit, pItem, parent )
+{
+  new QLabel( title, this );
+  myInteger = new QtxIntSpinBox( this );
+  myInteger->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::IntegerSpinItem::~IntegerSpinItem()
+{
+}
+
+void QtxListResourceEdit::IntegerSpinItem::store()
+{
+  setInteger( myInteger->value() );
+}
+
+void QtxListResourceEdit::IntegerSpinItem::retrieve()
+{
+  myInteger->setValue( getInteger() );
+}
+
+QVariant QtxListResourceEdit::IntegerSpinItem::property( const QString& name ) const
+{
+  QVariant var;
+  if ( name == QString( "minimum" ) || name == QString( "min" ) )
+    var = QVariant( myInteger->minValue() );
+  else if ( name == QString( "maximum" ) || name == QString( "max" ) )
+    var = QVariant( myInteger->maxValue() );
+  else if ( name == QString( "step" ) )
+    var = QVariant( myInteger->lineStep() );
+  else if ( name == QString( "special" ) )
+    var = QVariant( myInteger->specialValueText() );
+  else if ( name == QString( "prefix" ) )
+    var = QVariant( myInteger->prefix() );
+  else if ( name == QString( "suffix" ) )
+    var = QVariant( myInteger->suffix() );
+  return var;
+}
+
+void QtxListResourceEdit::IntegerSpinItem::setProperty( const QString& name, const QVariant& var )
+{
+  QVariant prop = var;
+
+  if ( ( name == QString( "minimum" ) || name == QString( "min" ) ) && prop.cast( QVariant::Int ) )
+    myInteger->setMinValue( prop.toInt() );
+  else if ( ( name == QString( "maximum" ) || name == QString( "max" ) ) && prop.cast( QVariant::Int ) )
+    myInteger->setMaxValue( prop.toInt() );
+  else if ( name == QString( "step" ) && prop.cast( QVariant::Int ) && prop.toInt() > 0 )
+    myInteger->setLineStep( prop.toInt() );
+  else if ( name == QString( "special" ) && prop.cast( QVariant::String ) )
+    myInteger->setSpecialValueText( prop.toString() );
+  else if ( name == QString( "prefix" ) && prop.cast( QVariant::String ) )
+    myInteger->setPrefix( prop.toString() );
+  else if ( name == QString( "suffix" ) && prop.cast( QVariant::String ) )
+    myInteger->setSuffix( prop.toString() );
+}
+
+/*
+  Class: QtxListResourceEdit::DoubleEditItem
+  Descr: GUI implementation of resources string item.
+*/
+
+QtxListResourceEdit::DoubleEditItem::DoubleEditItem( const QString& title, QtxResourceEdit* edit,
+                                                     Item* pItem, QWidget* parent )
+: PrefItem( Double, edit, pItem, parent )
+{
+  new QLabel( title, this );
+  myDouble = new QLineEdit( this );
+  myDouble->setValidator( new QDoubleValidator( myDouble ) );
+  myDouble->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::DoubleEditItem::~DoubleEditItem()
+{
+}
+
+void QtxListResourceEdit::DoubleEditItem::store()
+{
+  setString( myDouble->text() );
+}
+
+void QtxListResourceEdit::DoubleEditItem::retrieve()
+{
+  myDouble->setText( getString() );
+}
+
+/*
+  Class: QtxListResourceEdit::DoubleSpinItem
+  Descr: GUI implementation of resources double item.
+*/
+
+QtxListResourceEdit::DoubleSpinItem::DoubleSpinItem( const QString& title, QtxResourceEdit* edit,
+                                                     Item* pItem, QWidget* parent )
+: PrefItem( DblSpin, edit, pItem, parent )
+{
+  new QLabel( title, this );
+  myDouble = new QtxDblSpinBox( this );
+  myDouble->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::DoubleSpinItem::~DoubleSpinItem()
+{
+}
+
+void QtxListResourceEdit::DoubleSpinItem::store()
+{
+  setDouble( myDouble->value() );
+}
+
+void QtxListResourceEdit::DoubleSpinItem::retrieve()
+{
+  myDouble->setValue( getDouble() );
+}
+
+QVariant QtxListResourceEdit::DoubleSpinItem::property( const QString& name ) const
+{
+  QVariant var;
+  if ( name == QString( "minimum" ) || name == QString( "min" ) )
+    var = QVariant( myDouble->minValue() );
+  else if ( name == QString( "maximum" ) || name == QString( "max" ) )
+    var = QVariant( myDouble->maxValue() );
+  else if ( name == QString( "precision" ) )
+    var = QVariant( myDouble->precision() );
+  else if ( name == QString( "step" ) )
+    var = QVariant( myDouble->lineStep() );
+  else if ( name == QString( "special" ) )
+    var = QVariant( myDouble->specialValueText() );
+  else if ( name == QString( "prefix" ) )
+    var = QVariant( myDouble->prefix() );
+  else if ( name == QString( "suffix" ) )
+    var = QVariant( myDouble->suffix() );
+  return var;
+}
+
+void QtxListResourceEdit::DoubleSpinItem::setProperty( const QString& name, const QVariant& var )
+{
+  QVariant prop = var;
+
+  if ( ( name == QString( "minimum" ) || name == QString( "min" ) ) && prop.cast( QVariant::Double ) )
+    myDouble->setMinValue( prop.toDouble() );
+  else if ( ( name == QString( "maximum" ) || name == QString( "max" ) ) && prop.cast( QVariant::Double ) )
+    myDouble->setMaxValue( prop.toDouble() );
+  else if ( name == QString( "step" ) && prop.cast( QVariant::Double ) && prop.toDouble() > 0 )
+    myDouble->setLineStep( prop.toDouble() );
+  else if ( name == QString( "precision" ) && prop.cast( QVariant::Int ) && prop.toInt() > 0 )
+    myDouble->setPrecision( prop.toInt() );
+  else if ( name == QString( "special" ) && prop.cast( QVariant::String ) )
+    myDouble->setSpecialValueText( prop.toString() );
+  else if ( name == QString( "prefix" ) && prop.cast( QVariant::String ) )
+    myDouble->setPrefix( prop.toString() );
+  else if ( name == QString( "suffix" ) && prop.cast( QVariant::String ) )
+    myDouble->setSuffix( prop.toString() );
+}
+
+/*
+  Class: QtxListResourceEdit::ColorItem
+  Descr: GUI implementation of resources color item.
+*/
+
+QtxListResourceEdit::ColorItem::ColorItem( const QString& title, QtxResourceEdit* edit,
+                                           Item* pItem, QWidget* parent )
+: PrefItem( Color, edit, pItem, parent )
+{
+  class ColorSelector : public QLabel
+  {
+  public:
+    ColorSelector( QWidget* parent = 0 ) : QLabel( parent )
+    {
+      setFrameStyle( WinPanel | Raised );
+    }
+    virtual ~ColorSelector() {}
+    virtual QSize minimumSizeHint() const
+    {
+      return QLabel::minimumSizeHint() + QSize( 0, 2 );
+    }
+
+  protected:
+    virtual void mousePressEvent( QMouseEvent* e )
+    {
+      if ( e->button() == LeftButton )
+      {
+        setFrameStyle( WinPanel | Sunken );
+        QColor c = QColorDialog::getColor( paletteBackgroundColor(), this );
+        if ( c.isValid() )
+          setPaletteBackgroundColor( c );
+
+        setFrameStyle( WinPanel | Raised );
+      }
+    }
+  };
+
+  new QLabel( title, this );
+  myColor = new ColorSelector( this );
+  myColor->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+}
+
+QtxListResourceEdit::ColorItem::~ColorItem()
+{
+}
+
+void QtxListResourceEdit::ColorItem::store()
+{
+  setColor( myColor->paletteBackgroundColor() );
+}
+
+void QtxListResourceEdit::ColorItem::retrieve()
+{
+  myColor->setPaletteBackgroundColor( getColor() );
+}
+
+
+/*
+  Class: QtxListResourceEdit::FontItem
+  Descr: GUI implementation of resources font item.
+*/
+QtxListResourceEdit::FontItem::FontItem( const QString& title, QtxResourceEdit* edit,
+                                         Item* pItem, QWidget* parent )
+: PrefItem( Font, edit, pItem, parent )
+{
+  new QLabel( title, this );
+  myFamilies = new QtxComboBox( false, this );
+  mySizes = new QtxComboBox( true, this );
+  mySizes->setInsertionPolicy( QComboBox::NoInsertion );
+  myBold = new QCheckBox( tr( "Bold" ), this );
+  myItalic = new QCheckBox( tr( "Italic" ), this );
+  myUnderline = new QCheckBox( tr( "Underline" ), this );
+  myPreview = new QToolButton( this );
+  myPreview->setText( "..." );
+
+  myFamilies->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
+  mySizes->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
+
+  connect( myFamilies, SIGNAL( activated( int ) ), this, SLOT( onActivateFamily( int ) ) );
+  connect( myPreview, SIGNAL( clicked() ), this, SLOT( onPreview() ) );
+
+  setProperty( "system", ( bool )true );
+  setProperty( "widget_flags", ( int )All );
+}
+
+QtxListResourceEdit::FontItem::~FontItem()
+{
+}
+
+void QtxListResourceEdit::FontItem::store()
+{
+  QFont f( family(), size() );
+  bool bold, italic, underline;
+  params( bold, italic, underline );
+  f.setBold( bold );
+  f.setItalic( italic );
+  f.setUnderline( underline );
+  Item::setFont( f );
+}
+
+void QtxListResourceEdit::FontItem::retrieve()
+{
+  QFont f = getFont();
+  setFamily( f.family() );
+  setSize( f.pointSize() );
+  setParams( f.bold(), f.italic(), f.underline() );
+}
+
+QVariant QtxListResourceEdit::FontItem::property( const QString& name ) const
+{
+  if( name=="system" )
+    return myIsSystem;
+
+  else if( name=="widget_flags" )
+    return ( int )myFlags;
+  
+  if( myIsSystem )
+  {
+    if( name=="families" )
+    {
+      QFontDatabase fdb;
+      return fdb.families();
+    }
+
+    else if( name=="default_family" )
+    {
+      QFontDatabase fdb;
+      QStringList fam = fdb.families();
+      if( fam.count()>0 )
+        return fam.first();
+      else
+        return QString::null;
+    }
+
+    else
+    {
+      QStringList parts = QStringList::split( ":", name );
+      if( parts.count()==2 )
+      {
+        if( parts[1]=="default_bold" || parts[1]=="default_italic" || parts[1]=="default_underline" )
+          return false;
+
+        else if( parts[1]=="sizes" )
+        {
+          QFontDatabase fdb;
+          QValueList<int> sizes = fdb.pointSizes( parts[0] );
+          QValueList<QVariant> vsizes;
+          QValueList<int>::const_iterator anIt = sizes.begin(),
+                                          aLast = sizes.end();
+          for( ; anIt!=aLast; anIt++ )
+            vsizes.append( *anIt );
+
+          return vsizes;
+        }
+
+        else if( parts[1]=="default_size" )
+        {
+          if( parts[0].isEmpty() )
+            return 0;
+            
+          QFontDatabase fdb;
+          QValueList<int> sizes = fdb.pointSizes( parts[0] );
+          if( sizes.count()>0 )
+            return sizes.first();
+          else
+            return 0;
+        }
+      }
+    }
+  }
+
+  else if( myProperties.contains( name ) )
+    return myProperties[ name ];
+
+  return QVariant();
+}
+
+void QtxListResourceEdit::FontItem::setProperty( const QString& name, const QVariant& value )
+{
+  if( name=="system" )
+  {
+    if( !value.canCast( QVariant::Bool ) )
+      return;
+
+    bool isSystem = value.toBool();
+    if( myIsSystem==isSystem )
+      return;
+
+    myIsSystem = isSystem;
+
+    QVariant families = property( "families" );
+    QString fam = family();
+
+    myFamilies->clear();
+    if( families.canCast( QVariant::StringList ) )
+    {
+      QStringList list = families.toStringList();
+      myFamilies->insertStringList( list );
+    }
+
+    setFamily( fam );
+    setSize( -1 ); //set default size
+  }
+  
+  else if( name=="widget_flags" )
+  {
+    if( !value.canCast( QVariant::Int ) )
+      return;
+
+    int wf = value.toInt();
+    
+    myFlags = wf;
+    myFamilies ->setShown( wf & Family );
+    mySizes    ->setShown( wf & Size );
+    mySizes->lineEdit()->setReadOnly( ( wf & UserSize )==0 );
+    myBold     ->setShown( wf & Bold );
+    myItalic   ->setShown( wf & Italic );
+    myUnderline->setShown( wf & Underline );
+    bool isSystem = property( "system" ).canCast( QVariant::Bool ) ? property( "system" ).toBool() : false;
+    myPreview->setShown( ( wf & Preview ) && isSystem );
+
+    internalUpdate();
+  }
+  
+  else
+    myProperties[ name ] = value;
+}
+
+void QtxListResourceEdit::FontItem::setFamily( const QString& f )
+{
+  QString curtext;
+  if( myFamilies->isShown() )
+  {
+    if( myFamilies->listBox()->findItem( f, Qt::ExactMatch ) )
+      curtext = f;
+  }
+  else
+  {
+    QVariant deffam = property( "default_family" );
+    if( deffam.canCast( QVariant::String ) )
+      curtext = deffam.toString();
+  }
+
+  int idx = -1;
+  for ( int i = 0; i < (int)myFamilies->count() && idx < 0; i++ )
+  {
+    if ( myFamilies->text( i ) == curtext )
+      idx = i;
+  }
+
+  if ( idx >= 0 )
+    myFamilies->setCurrentItem( idx );
+
+  onActivateFamily( idx );  
+}
+
+QString QtxListResourceEdit::FontItem::family() const
+{
+  return myFamilies->currentText();
+}
+
+void QtxListResourceEdit::FontItem::setSize( const int s )
+{
+  int cursize = -1;
+  if( mySizes->isShown() && s>0 )
+  {
+    if( ( myFlags & UserSize ) || mySizes->listBox()->findItem( QString( "%1" ).arg( s ), Qt::ExactMatch ) )
+      cursize = s;
+  }
+  else
+  {
+    QVariant defsize = property( QString( "%1:default_size" ).arg( family() ) );
+    if( defsize.canCast( QVariant::Int ) )
+      cursize = defsize.toInt();
+  }
+
+  mySizes->setCurrentText( cursize>0 ? QString( "%1" ).arg( cursize ) : "" );
+}
+
+int QtxListResourceEdit::FontItem::size() const
+{
+  QString s = mySizes->currentText();
+  bool ok;
+  int pSize = s.toInt( &ok );
+  return ( ok ? pSize : 0 );
+}
+
+void QtxListResourceEdit::FontItem::setParams( const bool bold, const bool italic, const bool underline )
+{
+  bool curbold = false, curitalic = false, curunderline = false;
+  if( myBold->isShown() )
+    curbold = bold;
+  else
+  {
+    QVariant def = property( QString( "%1:default_bold" ).arg( family() ) );
+    if( def.canCast( QVariant::Bool ) )
+      curbold = def.toBool();
+  }
+  if( myItalic->isShown() )
+    curitalic = italic;
+  else
+  {
+    QVariant def = property( QString( "%1:default_italic" ).arg( family() ) );
+    if( def.canCast( QVariant::Bool ) )
+      curitalic = def.toBool();
+  }
+  if( myUnderline->isShown() )
+    curunderline = underline;
+  else
+  {
+    QVariant def = property( QString( "%1:default_underline" ).arg( family() ) );
+    if( def.canCast( QVariant::Bool ) )
+      curunderline = def.toBool();
+  }
+  myBold->setChecked( curbold );
+  myItalic->setChecked( curitalic );
+  myUnderline->setChecked( curunderline );
+}
+
+void QtxListResourceEdit::FontItem::params( bool& bold, bool& italic, bool& underline )
+{
+  bold = myBold->isChecked();
+  italic = myItalic->isChecked();
+  underline = myUnderline->isChecked();
+}
+
+void QtxListResourceEdit::FontItem::internalUpdate()
+{
+  //update internal selection of font properties
+  setFamily( family() );
+  setSize( size() );
+  bool b1, b2, b3;
+  params( b1, b2, b3 );
+  setParams( b1, b2, b3 );
+}
+
+void QtxListResourceEdit::FontItem::onActivateFamily( int )
+{
+  QVariant sizes = property( QString( "%1:sizes" ).arg( family() ) );
+
+  int s = size();
+  mySizes->clear();
+  if( sizes.canCast( QVariant::List ) )
+  {
+    QValueList<QVariant> list = sizes.toList();
+    QStringList sizeItems;
+    QValueList<QVariant>::const_iterator anIt = list.begin(),
+                                         aLast = list.end();
+    for( ; anIt!=aLast; anIt++ )
+      if( (*anIt).canCast( QVariant::Int ) && (*anIt).toInt()>0 )
+        sizeItems.append( QString( "%1" ).arg( (*anIt).toInt() ) );
+    mySizes->insertStringList( sizeItems );
+  }
+  setSize( s );
+}
+
+void QtxListResourceEdit::FontItem::onPreview()
+{
+  QFont f( family(), size() );
+  bool bold, italic, underline;
+  params( bold, italic, underline );
+  f.setBold( bold );
+  f.setItalic( italic );
+  f.setUnderline( underline );
+
+  bool ok;
+  f = QFontDialog::getFont( &ok, f );
+
+  if( ok )
+  {
+    setFamily( f.family() );
+    setSize( f.pointSize() );
+    setParams( f.bold(), f.italic(), f.underline() );
+  }
+}
+
+
+
+
+
+/*
+  Class: QtxListResourceEdit::DirListItem
+  Descr: 
+*/
+QtxListResourceEdit::DirListItem::DirListItem( const QString& title, QtxResourceEdit* edit, Item* pItem, QWidget* parent )
+: PrefItem( Font, edit, pItem, parent )
+{
+  myDirListEditor = new QtxDirListEditor( this ); 
+}
+
+QtxListResourceEdit::DirListItem::~DirListItem()
+{
+}
+
+void QtxListResourceEdit::DirListItem::store()
+{
+  QStringList list;
+  myDirListEditor->getPathList(list);
+  setString( QString(list.join(";")) );
+}
+
+void QtxListResourceEdit::DirListItem::retrieve()
+{
+  myDirListEditor->setPathList(QStringList::split(";", getString()));
+}
+
+
+
+/*
+  Class: QtxListResourceEdit::FileItem
+  Descr: GUI implementation of resources file item.
+*/
+QtxListResourceEdit::FileItem::FileItem( const QString& title, QtxResourceEdit* edit,
+                                         Item* pItem, QWidget* parent )
+: PrefItem( Font, edit, pItem, parent ),
+  myFlags( QFileInfo::ReadUser ),
+  myIsExisting( true ),
+  myIsReadOnly ( true ),
+  myFileDlg( 0 )
+{
+  new QLabel( title, this );
+  myFile = new QLineEdit( this );
+  myFile->setValidator( new FileValidator( this, myFile ) );
+  myFile->setReadOnly( myIsReadOnly );
+  myOpenFile = new QToolButton( this );
+  myOpenFile->setText( "..." );
+  connect( myOpenFile, SIGNAL( clicked() ), this, SLOT( onOpenFile() ) );
+}
+
+QtxListResourceEdit::FileItem::~FileItem()
+{
+  if( myFileDlg ) 
+    delete myFileDlg;
+}
+
+void QtxListResourceEdit::FileItem::store()
+{
+  setString( myFile->text() );
+}
+
+void QtxListResourceEdit::FileItem::retrieve()
+{
+  myFile->setText( getString() );
+}
+
+QVariant QtxListResourceEdit::FileItem::property( const QString& name ) const
+{
+  if( name=="filter" )
+    return myFilter;
+  else if( name=="existing" )
+    return myIsExisting;
+  else if( name=="flags" )
+    return myFlags;
+  else if( name=="readOnly")
+    return myIsReadOnly;
+
+  return QVariant();
+}
+
+void QtxListResourceEdit::FileItem::setProperty( const QString& name, const QVariant& value )
+{
+  if( name=="filter" )
+  {
+    if( value.canCast( QVariant::String ) )
+    {
+      myFilter.clear();
+      myFilter.append( value.toString() );
+    }
+    else if( value.canCast( QVariant::StringList ) )
+      myFilter = value.toStringList();
+  }
+  else if( name=="existing" && value.canCast( QVariant::Bool ) )
+    myIsExisting = value.toBool();
+
+  else if( name=="flags" && value.canCast( QVariant::UInt ) )
+    myFlags = value.toUInt();
+
+  else if( name=="readOnly" && value.canCast( QVariant::Bool) ) {
+    myIsReadOnly = value.toBool();
+    myFile->setReadOnly( myIsReadOnly );
+  }
+}
+
+void QtxListResourceEdit::FileItem::onOpenFile()
+{
+  if( !myFileDlg )
+  {
+    myFileDlg = new QFileDialog( "." );
+    connect( myFileDlg, SIGNAL( fileHighlighted( const QString& ) ), this, SLOT( onFileSelected( const QString& ) ) );
+  }
+  
+  myFileDlg->setCaption( title() );
+  myFileDlg->setFilters( myFilter );
+  myFileDlg->setMode( myIsExisting ? QFileDialog::ExistingFile : QFileDialog::AnyFile );
+
+  if( myFileDlg->exec()==QDialog::Accepted )
+  {
+    myFile->setText( myFileDlg->selectedFile() ); 
+  }
+}
+
+bool QtxListResourceEdit::FileItem::isFileCorrect( const QString& f ) const
+{
+  bool res = false;
+  QFileInfo info( f );
+  if( !myIsExisting || info.exists() )
+    res = info.isFile() && info.permission( myFlags );
+
+  return res;
+}
+
+void QtxListResourceEdit::FileItem::onFileSelected( const QString& f )
+{
+  if( myFileDlg && !isFileCorrect( f ) )
+    myFileDlg->setSelection( "" );
+}
+
+
+
+QtxListResourceEdit::FileItem::FileValidator::FileValidator( FileItem* item, QObject* parent )
+: QValidator( parent ),
+  myItem( item )
+{
+}
+
+QtxListResourceEdit::FileItem::FileValidator::~FileValidator()
+{
+}
+
+QValidator::State QtxListResourceEdit::FileItem::FileValidator::validate( QString& f, int& ) const
+{
+  if( myItem && myItem->isFileCorrect( f ) )
+    return QValidator::Acceptable;
+  else
+    return QValidator::Intermediate;
+}
diff --git a/src/Qtx/QtxListResourceEdit.h b/src/Qtx/QtxListResourceEdit.h
new file mode 100644 (file)
index 0000000..19713ca
--- /dev/null
@@ -0,0 +1,530 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxListResourceEdit.h
+// Author:    Sergey TELKOV
+
+#ifndef QTXLISTRESOURCEEDIT_H
+#define QTXLISTRESOURCEEDIT_H
+
+#include "QtxResourceEdit.h"
+
+#include <qmap.h>
+#include <qhbox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qvalidator.h>
+
+class QLabel;
+class QListBox;
+class QLineEdit;
+class QCheckBox;
+class QComboBox;
+class QTabWidget;
+class QWidgetStack;
+
+class QtxIntSpinBox;
+class QtxDblSpinBox;
+
+class QtxDirListEditor;
+
+/*
+  Class: QtxListResourceEdit
+  Descr: GUI implementation of QtxResourceEdit - manager of resources
+*/
+
+class QTX_EXPORT QtxListResourceEdit : public QFrame, public QtxResourceEdit
+{
+  Q_OBJECT
+
+public:
+  class Tab;
+  class Group;
+  class Category;
+  class PrefItem;
+
+  class Spacer;
+  class ColorItem;
+  class StateItem;
+  class SelectItem;
+  class StringItem;
+  class DoubleSpinItem;
+  class DoubleEditItem;
+  class IntegerSpinItem;
+  class IntegerEditItem;
+  class FontItem;
+  class FileItem;
+  class DirListItem;
+
+  enum { Space, Bool, Color, String, Selector, DblSpin, IntSpin, Double, Integer, GroupBox, Font, DirList, File, User };
+
+public:
+  QtxListResourceEdit( QtxResourceMgr*, QWidget* = 0 );
+  virtual ~QtxListResourceEdit();
+
+  virtual void  setItemProperty( const int, const QString&, const QVariant& );
+
+signals:
+  void          resourceChanged( int );
+  void          resourceChanged( QString&, QString& );
+  void          resourcesChanged( const QMap<int, QString>& );
+
+private slots:
+  void          onSelectionChanged();
+
+protected:
+  virtual void  itemAdded( Item* );
+  virtual Item* createItem( const QString&, const int );
+  virtual void  changedResources( const QMap<Item*, QString>& );
+
+private:
+  void          updateState();
+  void          updateVisible();
+
+private:
+  QListBox*     myList;
+  QWidgetStack* myStack;
+};
+
+/*
+  Class: QtxListResourceEdit::Category
+  Descr: GUI implementation of 'Category' frame
+*/
+
+class QtxListResourceEdit::Category : public QFrame, public Item
+{
+public:
+  Category( QtxListResourceEdit*, QWidget* = 0 );
+  virtual ~Category();
+
+  virtual bool     isEmpty() const;
+
+  virtual int      type() const;
+  virtual void     store();
+  virtual void     retrieve();
+
+  virtual QVariant property( const QString& ) const;
+  virtual void     setProperty( const QString&, const QVariant& );
+
+protected:
+  virtual Item*    createItem( const QString&, const int );
+
+private:
+  void             updateState();
+
+private:
+  QLabel*          myInfo;
+  QTabWidget*      myTabs;
+};
+
+/*
+  Class: QtxListResourceEdit::Tab
+  Descr: GUI implementation of resources tab.
+*/
+
+class QtxListResourceEdit::Tab : public QFrame, public Item
+{
+public:
+  Tab( QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~Tab();
+
+  virtual int   type() const;
+  virtual void  store();
+  virtual void  retrieve();
+
+public:
+  virtual void  polish();
+
+protected:
+  virtual Item* createItem( const QString&, const int );
+
+private:
+  void          adjustLabels();
+
+private:
+  QWidget*      myMainFrame;
+};
+
+/*
+  Class: QtxListResourceEdit::Group
+  Descr: GUI implementation of resources group.
+*/
+
+class QtxListResourceEdit::Group : public QGroupBox, public Item
+{
+public:
+  Group( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~Group();
+
+  virtual int      type() const;
+  virtual void     store();
+  virtual void     retrieve();
+
+  virtual QVariant property( const QString& ) const;
+  virtual void     setProperty( const QString&, const QVariant& );
+
+  virtual void     setTitle( const QString& );
+
+protected:
+  virtual Item*    createItem( const QString&, const int );
+};
+
+/*
+  Class: QtxListResourceEdit::PrefItem
+  Descr: Base class for preferences items.
+*/
+
+class QtxListResourceEdit::PrefItem : public QHBox, public Item
+{
+public:
+  PrefItem( const int, QtxResourceEdit*, Item* = 0, QWidget* = 0 );
+  virtual ~PrefItem();
+
+  virtual int   type() const;
+
+protected:
+  virtual Item* createItem( const QString&, const int );
+
+private:
+  int           myType;
+};
+
+/*
+  Class: QtxListResourceEdit::Spacer
+  Descr: GUI implementation of resources spacer.
+*/
+
+class QtxListResourceEdit::Spacer : public PrefItem
+{
+public:
+  Spacer( QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~Spacer();
+
+  virtual void store();
+  virtual void retrieve();
+};
+
+/*
+  Class: QtxListResourceEdit::SelectItem
+  Descr: GUI implementation of resources selector item.
+*/
+
+class QtxListResourceEdit::SelectItem : public PrefItem
+{
+public:
+  SelectItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~SelectItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+  virtual QVariant property( const QString& ) const;
+  virtual void     setProperty( const QString&, const QVariant& );
+
+private:
+  void             setStrings( const QVariant& );
+  void             setIndexes( const QVariant& );
+
+  void             setStrings( const QStringList& );
+  void             setIndexes( const QValueList<int>& );
+
+private:
+  QComboBox*       myList;
+  QMap<int, int>   myIndex;
+};
+
+/*
+  Class: QtxListResourceEdit::StateItem
+  Descr: GUI implementation of resources bool item.
+*/
+
+class QtxListResourceEdit::StateItem : public PrefItem
+{
+public:
+  StateItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~StateItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+private:
+  QCheckBox*       myState;
+};
+
+/*
+  Class: QtxListResourceEdit::StringItem
+  Descr: GUI implementation of resources string item.
+*/
+
+class QtxListResourceEdit::StringItem : public PrefItem
+{
+public:
+  StringItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~StringItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+private:
+  QLineEdit*       myString;
+};
+
+/*
+  Class: QtxListResourceEdit::IntegerEditItem
+  Descr: GUI implementation of resources integer item.
+*/
+
+class QtxListResourceEdit::IntegerEditItem : public PrefItem
+{
+public:
+  IntegerEditItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~IntegerEditItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+private:
+  QLineEdit*       myInteger;
+};
+
+/*
+  Class: QtxListResourceEdit::IntegerSpinItem
+  Descr: GUI implementation of resources integer item.
+*/
+
+class QtxListResourceEdit::IntegerSpinItem : public PrefItem
+{
+public:
+  IntegerSpinItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~IntegerSpinItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+  virtual QVariant property( const QString& ) const;
+  virtual void     setProperty( const QString&, const QVariant& );
+
+private:
+  QtxIntSpinBox*  myInteger;
+};
+
+/*
+  Class: QtxListResourceEdit::DoubleEditItem
+  Descr: GUI implementation of resources double item.
+*/
+
+class QtxListResourceEdit::DoubleEditItem : public PrefItem
+{
+public:
+  DoubleEditItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~DoubleEditItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+private:
+  QLineEdit*       myDouble;
+};
+
+/*
+  Class: QtxListResourceEdit::DoubleSpinItem
+  Descr: GUI implementation of resources double item.
+*/
+
+class QtxListResourceEdit::DoubleSpinItem : public PrefItem
+{
+public:
+  DoubleSpinItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~DoubleSpinItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+  virtual QVariant property( const QString& ) const;
+  virtual void     setProperty( const QString&, const QVariant& );
+
+private:
+  QtxDblSpinBox*   myDouble;
+};
+
+/*
+  Class: QtxListResourceEdit::ColorItem
+  Descr: GUI implementation of resources color item.
+*/
+
+class QtxListResourceEdit::ColorItem : public PrefItem
+{
+public:
+  ColorItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~ColorItem();
+
+  virtual void     store();
+  virtual void     retrieve();
+
+private:
+  QWidget*         myColor;
+};
+
+/*
+  Class: QtxListResourceEdit::FontItem
+  Descr: GUI implementation of resources font item.
+*/
+
+class QtxComboBox;
+class QToolButton;
+
+class QtxListResourceEdit::FontItem : public PrefItem
+{
+  Q_OBJECT
+
+public:
+  typedef enum
+  {
+    Family    = 0x01,
+    Size      = 0x02,
+    UserSize  = 0x04,
+    Bold      = 0x08,
+    Italic    = 0x10,
+    Underline = 0x20,
+    Preview   = 0x40,
+
+    All = Family | Size | UserSize | Bold | Italic | Underline | Preview
+    
+  } WidgetFlags;
+  
+public:
+  FontItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~FontItem();
+
+  virtual void store();
+  virtual void retrieve();
+
+  virtual QVariant property( const QString& ) const;
+  virtual void     setProperty( const QString&, const QVariant& );
+
+private slots:
+  void onActivateFamily( int );
+  void onPreview();
+  
+private:
+  void       setFamily( const QString& );
+  QString    family() const;
+  void       setSize( const int );
+  int        size() const;
+  void       setParams( const bool, const bool, const bool );
+  void       params( bool&, bool&, bool& );
+  void       internalUpdate();
+  
+private:
+  int            myFlags;
+  bool           myIsSystem;
+  QtxComboBox   *myFamilies, *mySizes;
+  QCheckBox     *myBold, *myItalic, *myUnderline;
+  QToolButton   *myPreview;
+  QMap<QString, QVariant>   myProperties;
+};
+
+
+/*!
+ * \brief GUI implementation of resources directory list item.
+ *
+ * 
+ */
+class QtxListResourceEdit::DirListItem : public PrefItem
+{
+  Q_OBJECT
+  
+public:
+
+  /*!
+   * \brief Constructor
+   */
+  DirListItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  /*!
+   * \brief Destructor
+   */
+  virtual ~DirListItem();
+
+  /*!
+   * \brief Stores the data
+   */
+  virtual void     store();
+
+  /*!
+   * \brief Retrieves the data
+   */
+  virtual void     retrieve();
+
+private:
+  QtxDirListEditor* myDirListEditor; //!< The widget wich implements in GUI the list of directories
+};
+
+/*
+  Class: QtxListResourceEdit::FontItem
+  Descr: GUI implementation of resources font item.
+*/
+
+class QtxComboBox;
+class QToolButton;
+class QFileDialog;
+
+class QtxListResourceEdit::FileItem : public PrefItem
+{
+  Q_OBJECT
+
+private:
+  class FileValidator : public QValidator
+  {
+  public:
+    FileValidator( FileItem*, QObject* );
+    ~FileValidator();
+
+    virtual QValidator::State validate( QString&, int& ) const;
+
+  private:
+    FileItem* myItem;
+  };
+
+public:
+  FileItem( const QString&, QtxResourceEdit*, Item*, QWidget* = 0 );
+  virtual ~FileItem();
+
+  virtual void store();
+  virtual void retrieve();
+  
+  virtual QVariant property( const QString& ) const;
+  virtual void     setProperty( const QString&, const QVariant& );
+
+  virtual bool isFileCorrect( const QString& ) const;
+
+private slots:
+  void onOpenFile();
+  void onFileSelected( const QString& );
+
+private:
+  uint          myFlags;
+  bool          myIsReadOnly;
+  QStringList   myFilter;
+  bool          myIsExisting;
+  QLineEdit*    myFile;
+  QToolButton*  myOpenFile;
+  QFileDialog*  myFileDlg;
+};
+
+
+#endif
diff --git a/src/Qtx/QtxMainWindow.cxx b/src/Qtx/QtxMainWindow.cxx
new file mode 100644 (file)
index 0000000..b8968ef
--- /dev/null
@@ -0,0 +1,383 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxMainWindow.cxx
+// Author:    Sergey TELKOV
+
+#include "QtxMainWindow.h"
+
+#include "QtxToolBar.h"
+#include "QtxResourceMgr.h"
+
+#include <qlayout.h>
+#include <qmenubar.h>
+#include <qstatusbar.h>
+#include <qapplication.h>
+
+/*!
+    Class: QtxMainWindow::Filter [Internal]
+    Descr: Internal object with event filter for QtxMainWindow.
+*/
+
+class QtxMainWindow::Filter : public QObject
+{
+public:
+  Filter( QWidget*, QtxMainWindow*, QObject* = 0 );
+  virtual ~Filter();
+
+  virtual bool eventFilter( QObject*, QEvent* );
+
+private:
+  QMainWindow* myMain;
+  QWidget*     myWidget;
+};
+
+QtxMainWindow::Filter::Filter( QWidget* wid, QtxMainWindow* mw, QObject* parent )
+: QObject( parent ),
+myMain( mw ),
+myWidget( wid )
+{
+  myMain->installEventFilter( this );
+};
+
+QtxMainWindow::Filter::~Filter()
+{
+}
+
+bool QtxMainWindow::Filter::eventFilter( QObject* o, QEvent* e )
+{
+  if ( myMain == o && e->type() == QEvent::ChildRemoved &&
+       myWidget == ((QChildEvent*)e)->child() )
+    return true;
+
+  return QObject::eventFilter( o, e );
+}
+
+/*!
+    Class: QtxMainWindow [Public]
+    Descr: Main window with support of dockable menubar/status bar
+           and geometry store/retrieve.
+*/
+
+QtxMainWindow::QtxMainWindow( QWidget* parent, const char* name, WFlags f )
+: QMainWindow( parent, name, f ),
+myMode( -1 ),
+myMenuBar( NULL ),
+myStatusBar( NULL )
+{
+}
+
+QtxMainWindow::~QtxMainWindow()
+{
+  setDockableMenuBar( false );
+  setDockableStatusBar( false );
+}
+
+bool QtxMainWindow::isDockableMenuBar() const
+{
+  return myMenuBar;
+}
+
+void QtxMainWindow::setDockableMenuBar( const bool on )
+{
+  if ( isDockableMenuBar() == on )
+    return;
+
+  QMenuBar* mb = menuBar();
+  if ( !mb )
+    return;
+
+  if ( on && !myMenuBar )
+  {
+    mb->setCaption( tr( "Menu bar" ) );
+    QtxToolBar* dockMb = new QtxToolBar( true, this, "menu bar container" );
+    myMenuBar = dockMb;
+    new Filter( mb, this, myMenuBar );
+    dockMb->setWidget( mb );
+    dockMb->setNewLine( true );
+    dockMb->setStretchable( true );
+    dockMb->setResizeEnabled( false );
+
+    moveDockWindow( dockMb, DockTop );
+    setDockEnabled( dockMb, Left, false );
+    setDockEnabled( dockMb, Right, false );
+
+    setAppropriate( dockMb, false );
+
+    connect( dockMb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+  }
+  else if ( !on && myMenuBar )
+  {
+    mb->reparent( this, QPoint( 0, 0 ), mb->isVisibleTo( mb->parentWidget() ) );
+    disconnect( myMenuBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+    delete myMenuBar;
+    myMenuBar = 0;
+    QChildEvent ce( QEvent::ChildRemoved, mb );
+    QApplication::sendEvent( this, &ce );
+  }
+
+  setUpLayout();
+}
+
+bool QtxMainWindow::isDockableStatusBar() const
+{
+  return myStatusBar;
+}
+
+void QtxMainWindow::setDockableStatusBar( const bool on )
+{
+  if ( isDockableStatusBar() == on )
+    return;
+
+  QStatusBar* sb = statusBar();
+  if ( !sb )
+    return;
+
+  if ( on && !myStatusBar )
+  {
+    sb->setCaption( tr( "Status bar" ) );
+    QtxToolBar* dockSb = new QtxToolBar( true, this, "status bar container" );
+    myStatusBar = dockSb;
+    new Filter( sb, this, myStatusBar );
+    dockSb->setWidget( sb );
+    dockSb->setNewLine( true );
+    dockSb->setStretchable( true );
+    dockSb->setResizeEnabled( false );
+    sb->setMinimumWidth( 250 );
+
+    sb->setSizeGripEnabled( false );
+
+    moveDockWindow( dockSb, DockBottom );
+    setDockEnabled( dockSb, Left, false );
+    setDockEnabled( dockSb, Right, false );
+
+    setAppropriate( dockSb, false );
+
+    connect( dockSb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+  }
+  else if ( !on && myStatusBar )
+  {
+    sb->reparent( this, QPoint( 0, 0 ), sb->isVisibleTo( sb->parentWidget() ) );
+    disconnect( myStatusBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+    delete myStatusBar;
+    myStatusBar = 0;
+    QChildEvent ce( QEvent::ChildRemoved, sb );
+    QApplication::sendEvent( this, &ce );
+
+    sb->setSizeGripEnabled( true );
+  }
+
+  setUpLayout();
+}
+
+void QtxMainWindow::loadGeometry( QtxResourceMgr* resMgr, const QString& section )
+{
+  QString sec = section.stripWhiteSpace();
+  if ( !resMgr || sec.isEmpty() )
+    return;
+
+  int winState = -1;
+  if ( !resMgr->value( sec, "state", winState ) )
+  {
+    QString stateStr;
+    if ( resMgr->value( sec, "state", stateStr ) )
+      winState = windowState( stateStr );
+  }
+
+  int win_w = resMgr->integerValue( sec, "width", width() );
+  int win_h = resMgr->integerValue( sec, "height", height() );
+
+  int winPosX = windowPosition( resMgr->stringValue( sec, QString( "pos_x" ), QString::null ) );
+  int winPosY = windowPosition( resMgr->stringValue( sec, QString( "pos_y" ), QString::null ) );
+
+  QWidget* desk = QApplication::desktop();
+
+  int win_x = 0;
+  if ( winPosX == WP_Absolute )
+    win_x = resMgr->integerValue( sec, "pos_x", x() );
+  else if ( desk )
+    win_x = relativeCoordinate( winPosX, desk->width(), win_w );
+
+  int win_y = 0;
+  if ( winPosX == WP_Absolute )
+    win_y = resMgr->integerValue( sec, "pos_y", y() );
+  else if ( desk )
+    win_y = relativeCoordinate( winPosY, desk->height(), win_h );
+
+  bool vis = isVisibleTo( parentWidget() );
+
+  resize( win_w, win_h );
+  move( win_x, win_y );
+
+  myMode = -1;
+
+  if ( vis )
+    QApplication::postEvent( this, new QCustomEvent( QEvent::User, (void*)winState ) );
+  else
+    myMode = winState;
+}
+
+void QtxMainWindow::show()
+{
+  if ( myMode != -1 )
+    QApplication::postEvent( this, new QCustomEvent( QEvent::User, (void*)myMode ) );
+
+  myMode = -1;
+
+  QMainWindow::show();
+}
+
+void QtxMainWindow::customEvent( QCustomEvent* e )
+{
+  QMainWindow::customEvent( e );
+
+  int mode = (int)e->data();
+  switch ( mode )
+  {
+  case WS_Normal:
+    showNormal();
+    break;
+  case WS_Minimized:
+    showMinimized();
+    break;
+  case WS_Maximized:
+    showMaximized();
+    break;
+  }
+}
+
+int QtxMainWindow::relativeCoordinate( const int type, const int WH, const int wh ) const
+{
+  int res = 0;
+  switch ( type )
+  {
+  case WP_Center:
+    res = ( WH - wh ) / 2;
+    break;
+  case WP_Left:
+    res = 0;
+    break;
+  case WP_Right:
+    res = WH - wh;
+    break;
+  }
+  return res;
+}
+
+void QtxMainWindow::saveGeometry( QtxResourceMgr* resMgr, const QString& section ) const
+{
+  QString sec = section.stripWhiteSpace();
+  if ( !resMgr || sec.isEmpty() )
+    return;
+
+  resMgr->setValue( sec, "pos_x", pos().x() );
+  resMgr->setValue( sec, "pos_y", pos().y() );
+  resMgr->setValue( sec, "width", width() );
+  resMgr->setValue( sec, "height", height() );
+
+  int winState = WS_Normal;
+  if ( isMinimized() )
+    winState = WS_Minimized;
+  else if ( isMaximized() )
+    winState = WS_Maximized;
+
+  resMgr->setValue( sec, "state", winState );
+}
+
+bool QtxMainWindow::eventFilter( QObject* o, QEvent* e )
+{
+  return QMainWindow::eventFilter( o, e );
+}
+
+void QtxMainWindow::setAppropriate( QDockWindow* dw, bool a )
+{
+  QMainWindow::setAppropriate( dw, myStatusBar != dw && myMenuBar != dw && a );
+}
+
+void QtxMainWindow::setUpLayout()
+{
+  QMainWindow::setUpLayout();
+
+  if ( myMenuBar && layout() )
+    layout()->setMenuBar( 0 );
+}
+
+void QtxMainWindow::onDestroyed( QObject* obj )
+{
+  QObject* o = 0;
+  if ( obj == myMenuBar )
+  {
+    myMenuBar = 0;
+    o = menuBar();
+  }
+  else if ( obj == myStatusBar )
+  {
+    myStatusBar = 0;
+    o = statusBar();
+  }
+
+  if ( o )
+  {
+    QChildEvent ce( QEvent::ChildRemoved, o );
+    QApplication::sendEvent( this, &ce );
+  }
+}
+
+int QtxMainWindow::windowState( const QString& str ) const
+{
+  static QMap<QString, int> winStateMap;
+  if ( winStateMap.isEmpty() )
+  {
+    winStateMap["normal"]    = WS_Normal;
+    winStateMap["min"]       = WS_Minimized;
+    winStateMap["mini"]      = WS_Minimized;
+    winStateMap["minimized"] = WS_Minimized;
+    winStateMap["max"]       = WS_Maximized;
+    winStateMap["maxi"]      = WS_Maximized;
+    winStateMap["maximized"] = WS_Maximized;
+    winStateMap["hidden"]    = WS_Hidden;
+    winStateMap["hided"]     = WS_Hidden;
+    winStateMap["hide"]      = WS_Hidden;
+    winStateMap["invisible"] = WS_Hidden;
+  }
+
+  int res = -1;
+  QString stateStr = str.stripWhiteSpace().lower();
+  if ( winStateMap.contains( stateStr ) )
+    res = winStateMap[stateStr];
+  return res;
+}
+
+int QtxMainWindow::windowPosition( const QString& str ) const
+{
+  static QMap<QString, int> winPosMap;
+  if ( winPosMap.isEmpty() )
+  {
+    winPosMap["center"] = WP_Center;
+    winPosMap["left"]   = WP_Left;
+    winPosMap["right"]  = WP_Right;
+    winPosMap["top"]    = WP_Top;
+    winPosMap["bottom"] = WP_Bottom;
+  }
+
+  int res = WP_Absolute;
+  QString posStr = str.stripWhiteSpace().lower();
+  if ( winPosMap.contains( posStr ) )
+    res = winPosMap[posStr];
+  return res;
+}
diff --git a/src/Qtx/QtxMainWindow.h b/src/Qtx/QtxMainWindow.h
new file mode 100644 (file)
index 0000000..c2aa1bd
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxMainWindow.h
+// Author:    Sergey TELKOV
+
+#ifndef QTXMAINWINDOW_H
+#define QTXMAINWINDOW_H
+
+#include "Qtx.h"
+
+#include <qmainwindow.h>
+
+class QDockWindow;
+class QtxResourceMgr;
+
+class QTX_EXPORT QtxMainWindow : public QMainWindow
+{
+  Q_OBJECT
+
+  class Filter;
+
+  enum { WS_Normal, WS_Minimized, WS_Maximized, WS_Hidden };
+  enum { WP_Absolute, WP_Center, WP_Left, WP_Right, WP_Top = WP_Left, WP_Bottom = WP_Right };
+
+public:
+  QtxMainWindow( QWidget* = 0, const char* = 0, WFlags = WType_TopLevel );
+  virtual ~QtxMainWindow();
+
+  bool              isDockableMenuBar() const;
+  void              setDockableMenuBar( const bool );
+
+  bool              isDockableStatusBar() const;
+  void              setDockableStatusBar( const bool );
+
+  void              loadGeometry( QtxResourceMgr*, const QString& );
+  void              saveGeometry( QtxResourceMgr*, const QString& ) const;
+
+  virtual bool      eventFilter( QObject*, QEvent* );
+
+public slots:
+  virtual void      show();
+  virtual void      setAppropriate( QDockWindow*, bool );
+
+protected:
+  virtual void      setUpLayout();
+  virtual void      customEvent( QCustomEvent* );
+
+private slots:
+  void              onDestroyed( QObject* );
+
+private:
+  int               windowState( const QString& ) const;
+  int               windowPosition( const QString& ) const;
+  int               relativeCoordinate( const int, const int, const int ) const;
+
+private:
+  int               myMode;
+  QDockWindow*      myMenuBar;
+  QDockWindow*      myStatusBar;
+};
+
+#endif
diff --git a/src/Qtx/QtxPopupMgr.cxx b/src/Qtx/QtxPopupMgr.cxx
new file mode 100644 (file)
index 0000000..f01716c
--- /dev/null
@@ -0,0 +1,735 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+
+#include "QtxPopupMgr.h"
+#include "QtxListOfOperations.h"
+#include "QtxStdOperations.h"
+#include "QtxAction.h"
+
+#include <qpopupmenu.h>
+#include <qdatetime.h>
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxValue QtxPopupMgr::Selection::globalParam( const QString& str ) const
+{
+  if( str==selCountParam() )
+    return count();
+
+  else if( str[0]==equality() )
+  {
+    QtxSets::ValueSet set;
+    QString par = str.mid( 1 );
+
+    for( int i=0, n=count(); i<n; i++ )
+    {
+      QtxValue v = param( i, par );
+      if( v.isValid() )
+       QtxSets::add( set, v );
+      else
+       return QtxValue();      
+    }
+    return set;
+  }
+
+  else
+    return QtxValue();
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QChar QtxPopupMgr::Selection::equality() const
+{
+  return defEquality();
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QString QtxPopupMgr::Selection::selCountParam() const
+{
+  return defSelCountParam();
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QChar QtxPopupMgr::Selection::defEquality()
+{
+    return '$';
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QString QtxPopupMgr::Selection::defSelCountParam()
+{
+    return "selcount";
+}
+
+
+
+
+
+//================================================================
+// Class : 
+// Purpose  : 
+//================================================================
+class QtxCacheSelection : public QtxPopupMgr::Selection
+{
+public:
+  QtxCacheSelection( QtxPopupMgr::Selection* );
+  virtual ~QtxCacheSelection();
+
+  virtual int      count() const;
+  virtual QtxValue param( const int, const QString& ) const;
+  virtual QtxValue globalParam( const QString& ) const;
+
+private:
+  typedef QMap< QString, QtxValue >  CacheMap;
+
+  QtxPopupMgr::Selection*    mySel;
+  CacheMap                   myParamCache;
+};
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxCacheSelection::QtxCacheSelection( QtxPopupMgr::Selection* sel )
+: mySel( sel )
+{
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxCacheSelection::~QtxCacheSelection()
+{
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+int QtxCacheSelection::count() const
+{
+  return mySel ? mySel->count() : 0;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxValue QtxCacheSelection::param( const int i, const QString& name ) const
+{
+  QString param_name = name + "#####" + QString::number( i );
+  if( myParamCache.contains( param_name ) )
+    return myParamCache[ param_name ];
+  else
+  {
+    QtxValue v;
+    if( mySel )
+      v = mySel->param( i, name );
+    if( v.isValid() )
+      ( ( CacheMap& )myParamCache ).insert( param_name, v );
+    return v;
+  }
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxValue QtxCacheSelection::globalParam( const QString& name ) const
+{
+  if( myParamCache.contains( name ) )
+    return myParamCache[ name ];
+  else
+  {
+    QtxValue v;
+    if( mySel )
+      v = mySel->globalParam( name );
+    if( v.isValid() )
+      ( ( CacheMap& )myParamCache ).insert( name, v );
+    return v;
+  }
+}
+
+
+
+
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxPopupMgr::Operations::Operations( QtxPopupMgr* mgr )
+: QtxStrings(),
+  myPopupMgr( mgr )
+{
+    QStringList aList;
+    aList.append( "every" );
+    aList.append( "any" );
+    aList.append( "onlyone" );
+    addOperations( aList );
+
+    myParser = new QtxParser( mgr->myOperations );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxPopupMgr::Operations::~Operations()
+{
+    delete myParser;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+int QtxPopupMgr::Operations::prior( const QString& op, bool isBin ) const
+{
+    if( !isBin && ( op=="every" || op=="any" || op=="onlyone" ) )
+        return 1;
+    else
+        return QtxStrings::prior( op, isBin );
+
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxParser::Error QtxPopupMgr::Operations::calculate
+    ( const QString& op, QtxValue& v1, QtxValue& v2 ) const
+{
+    int ind = -1;
+    if( op=="every" )
+        ind = 0;
+    else if( op=="any" )
+        ind = 1;
+    else if( op=="onlyone" )
+        ind = 2;
+
+    if( ind>=0 && ind<=2 )
+    {
+        QString val_name = op + "(" + v2.toString() + ")";
+        QtxParser::Error err = QtxParser::OK;
+
+        if( !myValues.contains( val_name ) )
+        {
+            myParser->setExpr( v2.toString() );
+            QStringList params, specific;
+            myParser->paramsList( params );
+
+            myParser->clear();
+            myPopupMgr->setParams( myParser, specific );
+
+            QtxPopupMgr::Selection* sel = myPopupMgr->myCurrentSelection;
+
+            int global_result = 0;
+            if( sel )
+                for( int i=0, n=sel->count(); i<n; i++ )
+                {
+                    QStringList::const_iterator anIt = specific.begin(),
+                                                aLast = specific.end();
+                    for( ; anIt!=aLast; anIt++ )
+                    {
+                        QtxValue v = sel->param( i, *anIt );
+                        if( v.isValid() )
+                            myParser->set( *anIt, v );
+                        else
+                            return QtxParser::InvalidToken;
+                    }
+
+                    QtxValue res = myParser->calculate();
+                    err = myParser->lastError();
+                    if( err==QtxParser::OK )
+                        if( res.type()==QVariant::Bool )
+                        {
+                            if( res.toBool() )
+                                global_result++;
+                            if( ind==2 && global_result>1 )
+                                break;
+                        }
+                        else
+                            return QtxParser::InvalidResult;
+                    else
+                        return err;
+                }
+
+            QtxValue& vv = ( QtxValue&  )myValues[ val_name ];
+            vv = ( ind==0 && global_result==sel->count() ) ||
+                 ( ind==1 ) ||
+                 ( ind==2 && global_result==1 );
+        }
+
+        v2 = myValues[ val_name ];
+
+        return err;
+    }
+    else
+        return QtxStrings::calculate( op, v1, v2 );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+void QtxPopupMgr::Operations::clear()
+{
+    myValues.clear();
+}
+
+
+
+
+
+
+
+
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxPopupMgr::QtxPopupMgr( QPopupMenu* popup, QObject* parent )
+: QtxActionMenuMgr( popup, parent ),
+  myCurrentSelection( 0 )
+{
+    createOperations();
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxPopupMgr::~QtxPopupMgr()
+{
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+void QtxPopupMgr::createOperations()
+{
+    myOperations = new QtxListOfOperations;
+    myOperations->prepend( "logic",   new QtxLogic(),           0 );
+    myOperations->prepend( "arithm",  new QtxArithmetics(),    50 );
+    myOperations->append( "strings", new QtxStrings(),       100 );
+    myOperations->append( "sets",    new QtxSets(),          150 );
+    myOperations->append( "custom",  new Operations( this ), 200 );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+int QtxPopupMgr::registerAction( QAction* act,
+                                 const QString& visible,
+                                 const QString& toggle,
+                                 const int id )
+{
+    int _id = QtxActionMenuMgr::registerAction( act, id );
+    setRule( _id, visible, true );
+    setRule( _id, toggle, false );
+    return _id;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+void QtxPopupMgr::unRegisterAction( const int id )
+{
+    QAction* act = action( id );
+
+    myVisibility.remove( act );
+    myToggle.remove( act );
+
+    remove( id );
+    //QtxActionMenuMgr::unRegisterAction( id );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+bool QtxPopupMgr::hasRule( QAction* act, bool visibility ) const
+{
+    return map( visibility ).contains( act );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+bool QtxPopupMgr::hasRule( const int id, bool visibility ) const
+{
+    return hasRule( action( id ), visibility );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+void QtxPopupMgr::setRule( QAction* act, const QString& rule, bool visibility )
+{
+    if( !act || rule.isEmpty() )
+        return;
+
+    if( !hasRule( act, visibility ) )
+    {
+        QtxParser* p = new QtxParser( myOperations, rule );
+        if( p->lastError()==QtxParser::OK )
+            map( visibility ).insert( act, p );
+        else
+            delete p;
+    }
+    else
+    {
+        QtxParser* p = map( visibility )[ act ];
+        p->setExpr( rule );
+        if( p->lastError()!=QtxParser::OK )
+            p->setExpr( QString() );
+    }
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+void QtxPopupMgr::setRule( const int id, const QString& rule, bool visibility )
+{
+    setRule( action( id ), rule, visibility );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+bool result( QtxParser* p )
+{
+    bool res = false;
+    if( p )
+    {
+        QtxValue vv = p->calculate();
+        res = p->lastError()==QtxParser::OK &&
+            ( ( vv.type()==QVariant::Int && vv.toInt()!=0 ) ||
+              ( vv.type()==QVariant::Bool && vv.toBool() ) );
+    }
+    return res;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+void QtxPopupMgr::setParams( QtxParser* p, QStringList& specific ) const
+{
+    if( !p || !myCurrentSelection )
+        return;
+
+    QStringList params;
+
+    p->paramsList( params );
+    QStringList::const_iterator anIt = params.begin(),
+                                aLast = params.end();
+    for( ; anIt!=aLast; anIt++ )
+    {
+      QtxValue v = myCurrentSelection->globalParam( *anIt );
+      if( v.isValid() )
+       p->set( *anIt, v );
+      else
+        specific.append( *anIt );
+    }
+}
+
+bool operator<( const QtxValue& v1, const QtxValue& v2 )
+{
+  QVariant::Type t1 = v1.type(), t2 = v2.type();
+  if( t1==t2 )
+  {
+    switch( t1 )
+    {
+    case QVariant::Int:
+      return v1.toInt() < v2.toInt();
+      
+    case QVariant::Double:
+      return v1.toDouble() < v2.toDouble();
+
+    case QVariant::CString:
+    case QVariant::String:
+      return v1.toString() < v2.toString();
+
+    case QVariant::StringList:
+    case QVariant::List:
+    {
+      const QValueList<QtxValue>& aList1 = v1.toList(), aList2 = v2.toList();
+      QValueList<QtxValue>::const_iterator
+       anIt1 = aList1.begin(), aLast1 = aList1.end(),
+        anIt2 = aList2.begin(), aLast2 = aList2.end();
+      for( ; anIt1!=aLast1 && anIt2!=aLast2; anIt1++, anIt2++ )
+       if( (*anIt1)!=(*anIt2) )
+         return (*anIt1)<(*anIt2);
+
+      return anIt1==aLast1 && anIt2!=aLast2;
+    }
+
+    default:
+      return v1.toString()<v2.toString();
+    }
+  }
+  else
+    return t1<t2;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+bool QtxPopupMgr::isSatisfied( QAction* act, bool visibility ) const
+{
+  QString menu = act->menuText();
+
+  bool res = false;
+  if( !act )
+    return res;
+
+  if( hasRule( act, visibility ) )
+  {
+    QtxParser* p = map( visibility )[ act ];
+    QStringList specific;
+    p->clear();
+    ( ( Operations* )myOperations->operations( "custom" ) )->clear();
+
+    setParams( p, specific );
+
+    QMap<QValueList<QtxValue>,int> aCorteges;
+    QValueList<QtxValue> c;
+
+    if( specific.count()>0 )
+      if( myCurrentSelection )
+      {
+       res = false;
+
+       for( int i=0, n=myCurrentSelection->count(); i<n && !res; i++ )
+       {
+         QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
+         c.clear();
+         for( ; anIt1!=aLast1; anIt1++ )
+           c.append( myCurrentSelection->param( i, *anIt1 ) );
+         aCorteges.insert( c, 0 );
+       }
+       
+       //qDebug( QString( "%1 corteges" ).arg( aCorteges.count() ) );
+       QMap<QValueList<QtxValue>,int>::const_iterator anIt = aCorteges.begin(), aLast = aCorteges.end();
+       for( ; anIt!=aLast; anIt++ )
+       {
+         QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
+         const QValueList<QtxValue>& aCortege = anIt.key();
+         QValueList<QtxValue>::const_iterator anIt2 = aCortege.begin();
+         for( ; anIt1!=aLast1; anIt1++, anIt2++ )
+           p->set( *anIt1, *anIt2 );
+         res = res || result( p );
+       }
+
+       /*
+       for( int i=0, n=myCurrentSelection->count(); i<n && !res; i++ )
+       {
+         QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
+         for( ; anIt1!=aLast1; anIt1++ )
+           p->set( *anIt1, myCurrentSelection->param( i, *anIt1 ) );
+         res = res || result( p );
+       }*/
+      }
+      else
+       res = false;
+    else
+      res = result( p );
+  }
+
+  return res;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+bool QtxPopupMgr::isVisible( const int actId, const int place ) const
+{
+    bool res = QtxActionMenuMgr::isVisible( actId, place );
+    QAction* act = action( actId );
+    if( hasRule( act, true ) )
+        res = res && isSatisfied( act, true );
+    return res;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+void QtxPopupMgr::updatePopup( QPopupMenu* p, Selection* sel )
+{
+  QTime t1 = QTime::currentTime();
+
+  if( !p || !sel )
+    return;
+
+  myCurrentSelection = new QtxCacheSelection( sel );
+  RulesMap::iterator anIt = myToggle.begin(),
+                            aLast = myToggle.end();
+  for( ; anIt!=aLast; anIt++ )
+    if( anIt.key()->isToggleAction() && hasRule( anIt.key(), false ) )
+      anIt.key()->setOn( isSatisfied( anIt.key(), false ) );
+
+  setWidget( ( QWidget* )p );
+  updateMenu();
+  QTime t2 = QTime::currentTime();
+  qDebug( QString( "update popup time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
+  qDebug( QString( "number of objects = %1" ).arg( myCurrentSelection->count() ) );
+
+  delete myCurrentSelection;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxPopupMgr::RulesMap& QtxPopupMgr::map( bool visibility ) const
+{
+    return ( RulesMap& )( visibility ? myVisibility : myToggle );
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+bool QtxPopupMgr::load( const QString& fname, QtxActionMgr::Reader& r )
+{
+  PopupCreator cr( &r, this );
+  return r.read( fname, cr );
+}
+
+
+
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r,
+                                         QtxPopupMgr* mgr )
+: QtxActionMgr::Creator( r ),
+  myMgr( mgr )
+{
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QtxPopupMgr::PopupCreator::~PopupCreator()
+{
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu,
+                                       const ItemAttributes& attr, const int pId )
+{
+  if( !myMgr || !reader() )
+    return -1;
+
+  QString label   = reader()->option( "label",     "label"     ),
+          id      = reader()->option( "id",        "id"        ),
+          pos     = reader()->option( "pos",       "pos"       ),
+          group   = reader()->option( "group",     "group"     ),
+          tooltip = reader()->option( "tooltip",   "tooltip"   ),
+          sep     = reader()->option( "separator", "separator" ),
+          accel   = reader()->option( "accel",     "accel"     ),
+          icon    = reader()->option( "icon",      "icon"      ),
+          toggle  = reader()->option( "toggle",    "toggle"    );
+
+  int res = -1, actId = intValue( attr, id, -1 );;
+  if( subMenu )
+    res = myMgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+  else if( tag==sep )
+    res = myMgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+  else //if( !myMgr->contains( actId ) )
+  {
+    QPixmap pix; QIconSet set;
+    QString name = strValue( attr, icon );
+    if( !name.isEmpty() )
+    {
+      if( loadPixmap( name, pix ) )
+        set = QIconSet( pix );
+    }
+
+    QString actLabel = strValue( attr, label );
+    QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, actLabel,
+                                       QKeySequence( strValue( attr, accel ) ),
+                                       myMgr );
+    newAct->setToolTip( strValue( attr, tooltip ) );
+    QString toggleact = strValue( attr, toggle );
+    bool isToggle = !toggleact.isEmpty();
+    newAct->setToggleAction( isToggle );
+    newAct->setOn( toggleact.lower()=="true" );
+        
+    connect( newAct );
+    int aid = myMgr->registerAction( newAct, visibleRule( attr ), 
+                                     isToggle ? toggleRule( attr ) : QString::null,
+                                     actId );
+    res = myMgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+  }
+
+  return res;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QString QtxPopupMgr::PopupCreator::visibleRule( const ItemAttributes& ) const
+{
+  return QString::null;
+}
+
+//================================================================
+// Function : 
+// Purpose  : 
+//================================================================
+QString QtxPopupMgr::PopupCreator::toggleRule( const ItemAttributes& ) const
+{
+  return QString::null;
+}
diff --git a/src/Qtx/QtxPopupMgr.h b/src/Qtx/QtxPopupMgr.h
new file mode 100644 (file)
index 0000000..a75a7dc
--- /dev/null
@@ -0,0 +1,136 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+
+#ifndef __QTX_POPUP_MGR_HEADER__
+#define __QTX_POPUP_MGR_HEADER__
+
+#include "Qtx.h"
+#include "QtxActionMenuMgr.h"
+#include "QtxParser.h"
+#include "QtxStdOperations.h"
+
+#include <qmap.h>
+
+class QtxListOfOperations;
+
+//================================================================
+// Class    : 
+// Purpose  : 
+//================================================================
+class QTX_EXPORT QtxPopupMgr : public QtxActionMenuMgr
+{
+    Q_OBJECT
+
+public:
+    class QTX_EXPORT Selection
+    {
+    public:
+        virtual int      count() const = 0;
+        virtual QtxValue param( const int, const QString& ) const = 0;
+       virtual QtxValue globalParam( const QString& ) const;
+
+       virtual QChar    equality() const;
+       virtual QString  selCountParam() const;
+
+       static QChar    defEquality();
+       static QString  defSelCountParam();
+    };
+
+protected:
+    class Operations : public QtxStrings
+    {
+    public:
+        Operations( QtxPopupMgr* );
+        virtual ~Operations();
+
+        virtual int   prior( const QString&, bool isBin ) const;
+        virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const;
+
+        void clear();
+
+    private:
+        QtxPopupMgr*               myPopupMgr;
+        QtxParser*                 myParser;
+        QMap< QString, QtxValue >  myValues;
+    };
+
+    friend class Operations;
+
+protected:
+  class PopupCreator;
+
+public:
+    QtxPopupMgr( QPopupMenu*, QObject* = 0 );
+    virtual ~QtxPopupMgr();
+
+    virtual int  registerAction( QAction*,
+                                 const QString& visible,
+                                 const QString& toggle = QString::null,
+                                 const int = -1 );
+    virtual void unRegisterAction( const int );
+
+    virtual bool isVisible( const int actId, const int place ) const;
+
+    bool    hasRule( QAction*, bool visibility ) const;
+    bool    hasRule( const int, bool visibility ) const;
+    void    setRule( QAction*, const QString&, bool visibility );
+    void    setRule( const int, const QString&, bool visibility );
+    void    updatePopup( QPopupMenu*, Selection* );
+
+    //return name of parameter corresponding to selected objects count
+    //it will be set automatically
+
+    virtual bool load( const QString&, QtxActionMgr::Reader& );
+
+protected:
+    typedef QMap< QAction*, QtxParser* > RulesMap;
+
+protected:
+    virtual bool      isSatisfied( QAction*, bool visibility ) const;
+            void      setParams( QtxParser*, QStringList& ) const;
+            RulesMap& map( bool visibility ) const;
+
+    void createOperations();
+
+private:
+    RulesMap                 myVisibility, myToggle;
+    Selection*               myCurrentSelection;
+    QtxListOfOperations*     myOperations;
+};
+
+
+
+class QtxPopupMgr::PopupCreator : public QtxActionMgr::Creator
+{
+public:
+  PopupCreator( QtxActionMgr::Reader*, QtxPopupMgr* );
+  virtual ~PopupCreator();
+
+  virtual int append( const QString&, const bool,
+                      const ItemAttributes&, const int );
+
+  virtual QString visibleRule( const ItemAttributes& ) const;
+  virtual QString toggleRule( const ItemAttributes& ) const;
+
+private:
+  QtxPopupMgr* myMgr;
+};
+
+
+#endif
diff --git a/src/Qtx/QtxWorkstack.cxx b/src/Qtx/QtxWorkstack.cxx
new file mode 100644 (file)
index 0000000..c267236
--- /dev/null
@@ -0,0 +1,2011 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxWorkstack.cxx
+// Author:    Sergey TELKOV
+
+#include "QtxWorkstack.h"
+
+#include <qstyle.h>
+#include <qimage.h>
+#include <qaction.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+#include <qiconset.h>
+#include <qpainter.h>
+#include <qsplitter.h>
+#include <qpopupmenu.h>
+#include <qobjectlist.h>
+#include <qpushbutton.h>
+#include <qwidgetstack.h>
+#include <qapplication.h>
+#include <qinputdialog.h>
+#include <qevent.h>
+
+#define DARK_COLOR_LIGHT      250
+/*!
+    Class: QtxWorkstack [Public]
+    Descr:
+*/
+
+QtxWorkstack::QtxWorkstack( QWidget* parent )
+: QWidget( parent ),
+myWin( 0 ),
+myArea( 0 ),
+myWorkWin( 0 ),
+myWorkArea( 0 )
+{
+  myActionsMap.insert( SplitVertical,   new QAction( tr( "Split vertically" ),   0, this ) );
+  myActionsMap.insert( SplitHorizontal, new QAction( tr( "Split horizontally" ), 0, this ) );
+  myActionsMap.insert( Close,           new QAction( tr( "Close" ),       0, this ) );
+  myActionsMap.insert( Rename,          new QAction( tr( "Rename" ),      0, this ) );
+
+  connect( myActionsMap[SplitVertical], SIGNAL( activated() ), this, SLOT( splitVertical() ) );
+  connect( myActionsMap[SplitHorizontal], SIGNAL( activated() ), this, SLOT( splitHorizontal() ) );
+  connect( myActionsMap[Close], SIGNAL( activated() ), this, SLOT( onCloseWindow() ) );
+  connect( myActionsMap[Rename], SIGNAL( activated() ), this, SLOT( onRename() ) );
+
+  QVBoxLayout* base = new QVBoxLayout( this );
+  mySplit = new QSplitter( this );
+  mySplit->setChildrenCollapsible( false );
+  base->addWidget( mySplit );
+}
+
+QtxWorkstack::~QtxWorkstack()
+{
+}
+
+QWidgetList QtxWorkstack::windowList() const
+{
+  QPtrList<QtxWorkstackArea> lst;
+  areas( mySplit, lst, true );
+
+  QWidgetList widList;
+  for ( QPtrListIterator<QtxWorkstackArea> it( lst ); it.current(); ++it )
+  {
+    QWidgetList wids = it.current()->widgetList();
+    for ( QWidgetListIt itr( wids ); itr.current(); ++itr )
+      widList.append( itr.current() );
+  }
+
+  return widList;
+}
+
+QWidgetList QtxWorkstack::splitWindowList() const
+{
+  return myArea ? myArea->widgetList() : QWidgetList();
+}
+
+QWidget* QtxWorkstack::activeWindow() const
+{
+  return myWin;
+}
+
+void QtxWorkstack::split( const int o )
+{
+  QtxWorkstackArea* area = myWorkArea;
+  if ( !area )
+    area = activeArea();
+  if ( !area )
+    return;
+
+  if ( area->widgetList().count() < 2 )
+    return;
+
+  QWidget* curWid = area->activeWidget();
+  if ( !curWid )
+    return;
+
+  QSplitter* s = splitter( area );
+  QPtrList<QtxWorkstackArea> areaList;
+  areas( s, areaList );
+
+  QPtrList<QSplitter> splitList;
+  splitters( s, splitList );
+
+  QSplitter* trg = 0;
+  if ( areaList.count() + splitList.count() < 2 || s->orientation() == o )
+    trg = s;
+
+  if ( !trg )
+    trg = wrapSplitter( area );
+
+  if ( !trg )
+    return;
+
+  trg->setOrientation( (Orientation)o );
+
+  QtxWorkstackArea* newArea = createArea( 0 );
+  insertWidget( newArea, trg, area );
+
+  area->removeWidget( curWid );
+  newArea->insertWidget( curWid );
+
+  distributeSpace( trg );
+
+  curWid->show();
+  curWid->setFocus();
+}
+
+/*!
+* \brief Split workarea of the given widget on two parts.
+* \param wid  - widget, belonging to this workstack
+* \param o    - orientation of splitting (Qt::Horizontal or Qt::Vertical)
+* \param type - type of splitting, see <VAR>SplitType</VAR> enumeration
+*/
+void QtxWorkstack::Split (QWidget* wid, const Qt::Orientation o, const SplitType type)
+{
+  if (!wid) return;
+
+  // find area of the given widget
+  QtxWorkstackArea* area = NULL;
+  QPtrList<QtxWorkstackArea> allAreas;
+  areas(mySplit, allAreas, true);
+
+  QPtrListIterator<QtxWorkstackArea> it (allAreas);
+  for (; it.current() && !area; ++it) {
+    if (it.current()->contains(wid))
+      area = it.current();
+  }
+  if (!area) return;
+
+  QWidgetList wids = area->widgetList();
+  if (wids.count() < 2)
+    return;
+
+  QSplitter* s = splitter(area);
+  QPtrList<QtxWorkstackArea> areaList;
+  areas(s, areaList);
+
+  QPtrList<QSplitter> splitList;
+  splitters(s, splitList);
+
+  QSplitter* trg = 0;
+  if (areaList.count() + splitList.count() < 2 || s->orientation() == o)
+    trg = s;
+
+  if (!trg) trg = wrapSplitter(area);
+  if (!trg) return;
+
+  trg->setOrientation(o);
+
+  QtxWorkstackArea* newArea = createArea(0);
+  insertWidget(newArea, trg, area);
+
+  switch (type) {
+  case SPLIT_STAY:
+    {
+      QWidgetListIt itr (wids);
+      for (; itr.current(); ++itr)
+      {
+        QWidget* wid_i = itr.current();
+        if (wid_i != wid) {
+          area->removeWidget(wid_i);
+          newArea->insertWidget(wid_i);
+        }
+      }
+    }
+    break;
+  case SPLIT_AT:
+    {
+      QWidgetListIt itr (wids);
+      for (; itr.current() && itr.current() != wid; ++itr) {
+      }
+      for (; itr.current(); ++itr) {
+        area->removeWidget(itr.current());
+        newArea->insertWidget(itr.current());
+      }
+    }
+    break;
+  case SPLIT_MOVE:
+    area->removeWidget(wid);
+    newArea->insertWidget(wid);
+    break;
+  }
+
+  distributeSpace(trg);
+}
+
+/*!
+* \brief Put given widget on top of its workarea
+* \param wid - widget, belonging to this workstack
+*/
+/*
+void QtxWorkstack::OnTop (QWidget* wid)
+{
+  if ( !wid )
+    return;
+
+  // find area of the given widget
+  QtxWorkstackArea* area = 0;
+  QPtrList<QtxWorkstackArea> allAreas;
+  areas( mySplit, allAreas, true );
+  for ( QPtrListIterator<QtxWorkstackArea> it( allAreas ); it.current() && !area; ++it )
+  {
+    if ( it.current()->contains( wid ) )
+      area = it.current();
+  }
+
+  if ( area )
+    area->setActiveWidget( wid );
+}
+*/
+
+/*!
+* \brief Move widget(s) from source workarea into target workarea
+*        or just reorder widgets inside one workarea.
+* \param wid1 - widget from target workarea
+* \param wid2 - widget from source workarea
+* \param all  - if this parameter is TRUE, all widgets from source workarea will
+*               be moved into the target one, else only the \a wid2 will be moved
+*
+* Move \a wid2 in target workarea. Put it right after \a wid1.
+* If value of boolean argument is TRUE, all widgets from source workarea
+* will be moved together with \a wid2, source workarea will be deleted.
+* If \a wid1 and \a wid2 belongs to one workarea, simple reordering will take place.
+*/
+void QtxWorkstack::Attract ( QWidget* wid1, QWidget* wid2, const bool all )
+{
+  if ( !wid1 || !wid2 )
+    return;
+
+  // find area of the widgets
+  QtxWorkstackArea *area1 = NULL, *area2 = NULL;
+  QPtrList<QtxWorkstackArea> allAreas;
+  areas(mySplit, allAreas, true);
+  QPtrListIterator<QtxWorkstackArea> it (allAreas);
+  for (; it.current() && !(area1 && area2); ++it) {
+    if (it.current()->contains(wid1))
+      area1 = it.current();
+    if (it.current()->contains(wid2))
+      area2 = it.current();
+  }
+  if (!area1 || !area2) return;
+
+  QWidget* curWid = area1->activeWidget();
+  if (!curWid) return;
+
+  if (area1 == area2) {
+    if (all) {
+      // Set wid1 at first position, wid2 at second
+      area1->insertWidget(wid1);
+      area1->insertWidget(wid2, 1);
+    } else {
+      // Set wid2 right after wid1
+      area1->removeWidget(wid2);
+      int wid1_ind = 0;
+      QWidgetList wids1 = area1->widgetList();
+      QWidgetListIt itr1 (wids1);
+      for (; itr1.current() && itr1.current() != wid1; ++itr1, ++wid1_ind);
+      area1->insertWidget(wid2, wid1_ind + 1);
+    }
+  } else {
+    int wid1_ind = 0;
+    QWidgetList wids1 = area1->widgetList();
+    QWidgetListIt itr1 (wids1);
+    for (; itr1.current() && itr1.current() != wid1; ++itr1, ++wid1_ind);
+
+    if (all) {
+      // Set wid2 right after wid1, other widgets from area2 right after wid2
+      QWidgetList wids2 = area2->widgetList();
+      QWidgetListIt itr2 (wids2);
+      for (int ind = wid1_ind + 1; itr2.current(); ++itr2, ++ind)
+      {
+        area2->removeWidget(itr2.current());
+        if (itr2.current() == wid2) {
+          area1->insertWidget(itr2.current(), wid1_ind + 1);
+        } else {
+          area1->insertWidget(itr2.current(), ind);
+        }
+      }
+    } else {
+      // Set wid2 right after wid1
+      area2->removeWidget(wid2);
+      area1->insertWidget(wid2, wid1_ind + 1);
+    }
+  }
+
+  area1->setActiveWidget( curWid );
+}
+
+static void setSizes (QIntList& szList, const int item_ind,
+                      const int new_near, const int new_this, const int new_farr)
+{
+  // set size to all items before an item # <item_ind>
+  int cur_pos = 0;
+  QIntList::iterator its = szList.begin();
+  for (; its != szList.end() && cur_pos < item_ind; ++its, ++cur_pos) {
+    *its = new_near;
+  }
+  if (its == szList.end()) return;
+  // set size to item # <item_ind>
+  *its = new_this;
+  ++its;
+  // set size to all items after an item # <item_ind>
+  for (; its != szList.end(); ++its) {
+    *its = new_farr;
+  }
+}
+
+/*!
+* \brief Set position of the widget relatively its splitter.
+* \param wid - widget to set position of
+* \param pos - position relatively splitter. Value in range [0..1].
+*
+* Orientation of positioning will correspond to the splitter orientation.
+*/
+void QtxWorkstack::SetRelativePositionInSplitter( QWidget* wid, const double position )
+{
+  if ( position < 0.0 || 1.0 < position)
+    return;
+
+  if ( !wid )
+    return;
+
+  // find area of the given widget
+  QtxWorkstackArea* area = NULL;
+  QPtrList<QtxWorkstackArea> allAreas;
+  areas(mySplit, allAreas, true);
+  for ( QPtrListIterator<QtxWorkstackArea> it( allAreas );
+       it.current() && !area;
+       ++it )
+  {
+    if (it.current()->contains(wid))
+      area = it.current();
+  }
+
+  if ( !area )
+    return;
+
+  QSplitter* split = splitter( area );
+  if ( !split )
+    return;
+
+  // find index of the area in its splitter
+  int item_ind = -1;
+  bool isFound = false;
+  const QObjectList* was = split->children();
+  for (QObjectListIt ito (*was); ito.current() && !isFound; ++ito, ++item_ind)
+  {
+    if (ito.current() == area)
+      isFound = true;
+  }
+  if (!isFound || item_ind == 0)
+    return;
+
+  QIntList szList = split->sizes();
+  int splitter_size = (split->orientation() == Horizontal ?
+                       split->width() : split->height());
+  int nb = szList.count();
+
+  int new_prev = int(splitter_size * position / item_ind);
+  int new_next  = int(splitter_size * (1.0 - position) / (nb - item_ind));
+  setSizes (szList, item_ind, new_prev, new_next, new_next);
+  split->setSizes(szList);
+}
+
+/*!
+* \brief Set position of the widget relatively the entire workstack.
+* \param wid - widget to set position of
+* \param o   - orientation of positioning (Qt::Horizontal or Qt::Vertical).
+*              If o = Qt::Horizontal, horizontal position of \a wid will be changed.
+*              If o = Qt::Vertical, vertical position of \a wid will be changed.
+* \param pos - position relatively workstack. Value in range [0..1].
+*/
+void QtxWorkstack::SetRelativePosition( QWidget* wid, const Qt::Orientation o,
+                                        const double position )
+{
+  if ( position < 0.0 || 1.0 < position )
+    return;
+
+  if ( !wid )
+    return;
+
+  int splitter_size = o == Horizontal ? mySplit->width() : mySplit->height();
+  int need_pos = int( position * splitter_size );
+  int splitter_pos = 0;
+
+  if ( setPosition( wid, mySplit, o, need_pos, splitter_pos ) != 0 )
+  {
+    // impossible to set required position
+  }
+}
+
+/*!
+* \brief Sets the action's accelerator key to accel. 
+* \param id - the key of the action in the actions map.
+* \param accel - action's accelerator key.
+*/
+void QtxWorkstack::setAccel( const int id, const int accel )
+{
+  if ( !myActionsMap.contains( id ) )
+    return;
+
+  myActionsMap[id]->setAccel( accel );
+}
+
+/*!
+* \brief Returns the action's accelerator key.
+* \param id - the key of the action in the actions map.
+* \retval int  - action's accelerator key.
+*/
+int QtxWorkstack::accel( const int id ) const
+{
+  int res = 0;
+  if ( myActionsMap.contains( id ) )
+    res = myActionsMap[id]->accel();
+  return res;
+}
+
+static int positionSimple (QIntList& szList, const int nb, const int splitter_size,
+                           const int item_ind, const int item_rel_pos,
+                           const int need_pos, const int splitter_pos)
+{
+  if (item_ind == 0) { // cannot move in this splitter
+    return (need_pos - splitter_pos);
+  }
+
+  int delta = 0;
+  int new_prev = 0;
+  int new_this = szList[item_ind];
+  int new_next = 0;
+
+  bool isToCheck = false;
+
+  if (need_pos < splitter_pos) {
+    // Set size of all previous workareas to zero <--
+    if (item_ind == nb - 1) {
+      // item iz last in the splitter, it will occupy all the splitter
+      new_this = splitter_size;
+    } else {
+      // recompute size of next items in splitter
+      new_next = (splitter_size - new_this) / (nb - item_ind - 1);
+    }
+    delta = need_pos - splitter_pos;
+
+  } else if (need_pos > (splitter_pos + splitter_size)) {
+    // Set size of all next workareas to zero -->
+    // recompute size of previous items in splitter
+    new_this = 0;
+    new_prev = (splitter_size - new_this) / item_ind;
+    delta = need_pos - (splitter_pos + splitter_size - new_this);
+
+  } else { // required position lays inside this splitter
+    // Move workarea inside splitter into required position <->
+    int new_item_rel_pos = need_pos - splitter_pos;
+    new_prev = new_item_rel_pos / item_ind;
+    if (need_pos < (splitter_pos + item_rel_pos)) {
+      // Make previous workareas smaller, next - bigger
+      // No problem to keep old size of the widget
+    } else {
+      // Make previous workareas bigger, next - smaller
+      if (new_this > splitter_size - new_item_rel_pos) {
+        new_this = splitter_size - new_item_rel_pos;
+      }
+      // jfa to do: in this case fixed size of next widgets could prevent right resizing
+      isToCheck = true;
+    }
+    if (item_ind == nb - 1) {
+      new_this = splitter_size - new_item_rel_pos;
+    } else {
+      new_next = (splitter_size - new_item_rel_pos - new_this) / (nb - item_ind - 1);
+    }
+    delta = 0;
+  }
+
+  setSizes (szList, item_ind, new_prev, new_this, new_next);
+  return delta;
+}
+
+/*!
+* \brief Set position of given widget.
+* \param wid          - widget to be moved
+* \param split        - currently processed splitter (goes from more common
+*                       to more particular splitter in recursion calls)
+* \param o            - orientation of positioning
+* \param need_pos     - required position of the given widget in pixels
+*                       (from top/left side of workstack area)
+* \param splitter_pos - position of the splitter \a split
+*                       (from top/left side of workstack area)
+* \retval int - returns difference between a required and a distinguished position.
+* 
+* Internal method. Recursively calls itself.
+* Is called from <VAR>SetRelativePosition</VAR> public method.
+*/
+int QtxWorkstack::setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
+                               const int need_pos, const int splitter_pos )
+{
+  if ( !wid || !split )
+    return need_pos - splitter_pos;
+
+  // Find corresponding sub-splitter.
+  // Find also index of appropriate item in current splitter.
+  int cur_ind = 0, item_ind = 0;
+  bool isBottom = false, isFound = false;
+  QSplitter* sub_split = NULL;
+  const QObjectList* objs = split->children();
+  if ( objs )
+  {
+    for (QObjectListIt it (*objs); it.current() && !isFound; ++it)
+    {
+      if (it.current()->inherits( "QtxWorkstackArea")) {
+        if (((QtxWorkstackArea*)it.current())->contains(wid)) {
+          item_ind = cur_ind;
+          isBottom = true;
+          isFound = true;
+        }
+        cur_ind++;
+      } else if (it.current()->inherits("QSplitter")) {
+        QPtrList<QtxWorkstackArea> areaList;
+        areas((QSplitter*)it.current(), areaList, true);
+        for (QPtrListIterator<QtxWorkstackArea> ita (areaList);
+             ita.current() && !isFound;
+             ++ita)
+        {
+          if (ita.current()->contains(wid)) {
+            item_ind = cur_ind;
+            isFound = true;
+            sub_split = (QSplitter*)it.current();
+          }
+        }
+        cur_ind++;
+      }
+    }
+  }
+  if (!isFound)
+    return (need_pos - splitter_pos);
+
+  if (split->orientation() == o) {
+    // Find coordinates of near and far sides of the appropriate item relatively current splitter
+    int splitter_size = (o == Horizontal ? split->width() : split->height());
+    QIntList szList = split->sizes();
+    int nb = szList.count();
+    int item_rel_pos = 0; // position of near side of item relatively this splitter
+    for (int i = 0; i < item_ind; i++) {
+      item_rel_pos += szList[i];
+    }
+    int item_size = szList[item_ind]; // size of item
+    int item_pos = splitter_pos + item_rel_pos;
+
+    // Resize splitter items to complete the conditions
+    if (isBottom) {
+      // I. Bottom of splitters stack reached
+
+      int delta = positionSimple(szList, nb, splitter_size, item_ind, item_rel_pos, need_pos, splitter_pos);
+      split->setSizes(szList);
+      // Recompute delta, as some windows can reject given size
+      int new_item_rel_pos = 0;
+      QIntList szList1 = split->sizes();
+      for (int i = 0; i < item_ind; i++) {
+        new_item_rel_pos += szList1[i];
+      }
+      delta = need_pos - (splitter_pos + new_item_rel_pos);
+      return delta;
+
+    } else {
+      // II. Bottom of splitters stack is not yet reached
+
+      if (item_ind == 0) { // cannot move in this splitter
+        // Process in sub-splitter
+        return setPosition(wid, sub_split, o, need_pos, splitter_pos);
+      }
+
+      int new_prev = 0;
+      int new_this = szList[item_ind];
+      int new_next = 0;
+
+      if (need_pos < splitter_pos) {
+        // Set size of all previous workareas to zero <--
+        if (item_ind == nb - 1) {
+          new_this = splitter_size;
+        } else {
+          new_next = (splitter_size - new_this) / (nb - item_ind - 1);
+        }
+        setSizes (szList, item_ind, new_prev, new_this, new_next);
+        split->setSizes(szList);
+        // Recompute splitter_pos, as some windows can reject given size
+        int new_item_rel_pos = 0;
+        QIntList szList1 = split->sizes();
+        for (int i = 0; i < item_ind; i++) {
+          new_item_rel_pos += szList1[i];
+        }
+        // Process in sub-splitter
+        return setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
+      } else if (need_pos > (splitter_pos + splitter_size)) {
+        // Set size of all next workareas to zero -->
+        new_prev = (splitter_size - new_this) / item_ind;
+        setSizes (szList, item_ind, new_prev, new_this, new_next);
+        split->setSizes(szList);
+        // Recompute splitter_pos, as some windows can reject given size
+        int new_item_rel_pos = 0;
+        QIntList szList1 = split->sizes();
+        for (int i = 0; i < item_ind; i++) {
+          new_item_rel_pos += szList1[i];
+        }
+        // Process in sub-splitter
+        return setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
+      } else {
+        // Set appropriate size of all previous/next items <->
+        int new_item_rel_pos = item_rel_pos;
+        if (need_pos < item_pos || (item_pos + item_size) < need_pos) {
+          // Move item inside splitter into required position <->
+          int new_this = szList[item_ind];
+          int new_next = 0;
+          new_item_rel_pos = need_pos - splitter_pos;
+          if ((item_pos + item_size) < need_pos) {
+            //new_item_rel_pos = need_pos - (item_pos + item_size);
+            new_item_rel_pos = item_rel_pos + (need_pos - (item_pos + item_size));
+          }
+          int new_prev = new_item_rel_pos / item_ind;
+          if (need_pos < (splitter_pos + item_rel_pos)) {
+            // Make previous workareas smaller, next - bigger
+            // No problem to keep old size of the widget
+          } else {
+            // Make previous workareas bigger, next - smaller
+            if (new_this > splitter_size - new_item_rel_pos) {
+              new_this = splitter_size - new_item_rel_pos;
+            }
+          }
+          if (item_ind == nb - 1) {
+            new_this = splitter_size - new_item_rel_pos;
+          } else {
+            new_next = (splitter_size - new_item_rel_pos - new_this) / (nb - item_ind - 1);
+          }
+          setSizes (szList, item_ind, new_prev, new_this, new_next);
+          split->setSizes(szList);
+          // Recompute new_item_rel_pos, as some windows can reject given size
+          new_item_rel_pos = 0;
+          QIntList szList1 = split->sizes();
+          for (int i = 0; i < item_ind; i++) {
+            new_item_rel_pos += szList1[i];
+          }
+        } else {
+          // Do nothing
+        }
+        // Process in sub-splitter
+        int add_pos = setPosition(wid, sub_split, o, need_pos, splitter_pos + new_item_rel_pos);
+        if (add_pos == 0)
+          return 0;
+
+        // this can be if corresponding workarea is first in sub-splitter
+        // or sub-splitter has another orientation
+
+        // Resize ones again to reach precize position <->
+        int need_pos_1 = splitter_pos + new_item_rel_pos + add_pos;
+
+        // Move workarea inside splitter into required position <->
+        int delta_1 = positionSimple(szList, nb, splitter_size, item_ind,
+                                     new_item_rel_pos, need_pos_1, splitter_pos);
+        split->setSizes(szList);
+        // Recompute new_item_rel_pos, as some windows can reject given size
+        new_item_rel_pos = 0;
+        QIntList szList1 = split->sizes();
+        for (int i = 0; i < item_ind; i++) {
+          new_item_rel_pos += szList1[i];
+        }
+        delta_1 = need_pos_1 - (splitter_pos + new_item_rel_pos);
+        return delta_1;
+      }
+    }
+  } else {
+    return setPosition(wid, sub_split, o, need_pos, splitter_pos);
+  }
+
+  return 0;
+}
+
+void QtxWorkstack::distributeSpace( QSplitter* split ) const
+{
+  if ( !split )
+    return;
+
+  QIntList szList = split->sizes();
+  int size = ( split->orientation() == Horizontal ?
+               split->width() : split->height() ) / szList.count();
+  for ( QIntList::iterator it = szList.begin(); it != szList.end(); ++it )
+    *it = size;
+  split->setSizes( szList );
+}
+
+void QtxWorkstack::splitVertical()
+{
+  split( Qt::Horizontal );
+}
+
+void QtxWorkstack::splitHorizontal()
+{
+  split( Qt::Vertical );
+}
+
+void QtxWorkstack::onRename()
+{
+  if ( !myWorkWin )
+    return;
+
+  bool ok = false;
+  QString newName = QInputDialog::getText( tr( "Rename" ), tr( "Enter new name:" ), QLineEdit::Normal,
+                                           myWorkWin->caption(), &ok, topLevelWidget() );
+  if ( ok && !newName.isEmpty() )
+    myWorkWin->setCaption( newName );
+}
+
+QSplitter* QtxWorkstack::wrapSplitter( QtxWorkstackArea* area )
+{
+  if ( !area )
+    return 0;
+
+  QSplitter* pSplit = splitter( area );
+  if ( !pSplit )
+    return 0;
+
+  bool upd = pSplit->isUpdatesEnabled();
+  pSplit->setUpdatesEnabled( false );
+
+  QIntList szList = pSplit->sizes();
+
+  QSplitter* wrap = new QSplitter( 0 );
+#if defined QT_VERSION && QT_VERSION >= 0x30200
+  wrap->setChildrenCollapsible( false );
+#endif
+  insertWidget( wrap, pSplit, area );
+  area->reparent( wrap, QPoint( 0, 0 ), true );
+
+  pSplit->setSizes( szList );
+
+  pSplit->setUpdatesEnabled( upd );
+
+  return wrap;
+}
+
+void QtxWorkstack::insertWidget( QWidget* wid, QWidget* pWid, QWidget* after )
+{
+  if ( !wid || !pWid )
+    return;
+
+  QWidgetList moveList;
+  const QObjectList* lst = pWid->children();
+  if ( lst )
+  {
+    bool found = false;
+    for ( QObjectListIt it( *lst ); it.current(); ++it )
+    {
+      if ( found && ( it.current()->inherits( "QSplitter" ) ||
+                      it.current()->inherits( "QtxWorkstackArea" ) ) )
+        moveList.append( (QWidget*)it.current() );
+      if ( it.current() == after )
+        found = true;
+    }
+  }
+
+  QMap<QWidget*, bool> map;
+  for ( QWidgetListIt it( moveList ); it.current(); ++it )
+  {
+    map.insert( it.current(), it.current()->isVisibleTo( it.current()->parentWidget() ) );
+    it.current()->reparent( 0, QPoint( 0, 0 ), false );
+  }
+
+  wid->reparent( pWid, QPoint( 0, 0 ), true );
+
+  for ( QWidgetListIt itr( moveList ); itr.current(); ++itr )
+    itr.current()->reparent( pWid, QPoint( 0, 0 ), map.contains( itr.current() ) ? map[itr.current()] : false );
+}
+
+/*!
+* \brief Closes the active window.
+*/
+void QtxWorkstack::onCloseWindow()
+{
+  if ( myWorkWin )
+    myWorkWin->close();
+  else if( activeWindow() )
+    activeWindow()->close();
+}
+
+void QtxWorkstack::onDestroyed( QObject* obj )
+{
+  QtxWorkstackArea* area = (QtxWorkstackArea*)obj;
+
+  if ( area == myArea )
+    myArea = 0;
+
+  if ( !myArea )
+  {
+    QtxWorkstackArea* cur = neighbourArea( area );
+    if ( cur )
+      cur->setFocus();
+  }
+
+  QApplication::postEvent( this, new QCustomEvent( QEvent::User ) );
+}
+
+void QtxWorkstack::onWindowActivated( QWidget* wid )
+{
+  const QObject* obj = sender();
+  if ( !obj->inherits( "QtxWorkstackArea" ) )
+    return;
+
+  setActiveArea( (QtxWorkstackArea*)obj );
+}
+
+void QtxWorkstack::onDeactivated( QtxWorkstackArea* area )
+{
+  if ( myArea != area )
+    return;
+
+  QPtrList<QtxWorkstackArea> lst;
+  areas( mySplit, lst, true );
+
+  int idx = lst.find( area );
+  if ( idx == -1 )
+    return;
+
+  myWin = 0;
+  myArea = 0;
+
+  QtxWorkstackArea* newArea = neighbourArea( area );
+  if ( newArea && newArea->activeWidget() )
+    newArea->activeWidget()->setFocus();
+
+  QApplication::postEvent( this, new QCustomEvent( QEvent::User ) );
+}
+
+void QtxWorkstack::onContextMenuRequested( QWidget* w, QPoint p )
+{
+  QtxWorkstackArea* anArea = dynamic_cast<QtxWorkstackArea*>( (QObject*)sender()  );
+  if ( !anArea )
+    anArea = activeArea();
+
+  if ( !anArea )
+    return;
+
+  QWidgetList lst = anArea->widgetList();
+  if ( lst.isEmpty() )
+    return;
+
+  myWorkWin = w;
+  myWorkArea = anArea;
+
+  QPopupMenu* pm = new QPopupMenu();
+  
+  if ( lst.count() > 1 )
+  {
+    myActionsMap[SplitVertical]->addTo( pm );
+    myActionsMap[SplitHorizontal]->addTo( pm );
+    pm->insertSeparator();
+  }
+
+  if ( w )
+  {
+    myActionsMap[Close]->addTo( pm );
+    myActionsMap[Rename]->addTo( pm );
+  }
+
+  if ( pm->count() )
+    pm->exec( p );
+
+  delete pm;
+
+  myWorkWin = 0;
+  myWorkArea = 0;
+}
+
+void QtxWorkstack::childEvent( QChildEvent* e )
+{
+  if ( e->inserted() && e->child()->isWidgetType() )
+  {
+         QWidget* w = (QWidget*)e->child();
+         if ( w && w != mySplit )
+    {
+      targetArea()->insertWidget( w );
+      return;
+    }
+  }
+  QWidget::childEvent( e );
+}
+
+void QtxWorkstack::customEvent( QCustomEvent* e )
+{
+  updateState();
+}
+
+QSplitter* QtxWorkstack::splitter( QtxWorkstackArea* area ) const
+{
+  if ( !area )
+    return 0;
+
+  QSplitter* split = 0;
+
+  QWidget* wid = area->parentWidget();
+  if ( wid && wid->inherits( "QSplitter" ) )
+    split = (QSplitter*)wid;
+
+  return split;
+}
+
+void QtxWorkstack::splitters( QSplitter* split, QPtrList<QSplitter>& splitList, const bool rec ) const
+{
+  if ( !split )
+    return;
+
+  const QObjectList* objs = split->children();
+  if ( objs )
+  {
+    for ( QObjectListIt it( *objs ); it.current(); ++it )
+    {
+      if ( rec )
+        splitters( (QSplitter*)it.current(), splitList, rec );
+      if ( it.current()->inherits( "QSplitter" ) )
+        splitList.append( (QSplitter*)it.current() );
+    }
+  }
+}
+
+void QtxWorkstack::areas( QSplitter* split, QPtrList<QtxWorkstackArea>& areaList, const bool rec ) const
+{
+  if ( !split )
+    return;
+
+  const QObjectList* objs = split->children();
+  if ( objs )
+  {
+    for ( QObjectListIt it( *objs ); it.current(); ++it )
+    {
+      if ( it.current()->inherits( "QtxWorkstackArea" ) )
+        areaList.append( (QtxWorkstackArea*)it.current() );
+      else if ( rec && it.current()->inherits( "QSplitter" ) )
+        areas( (QSplitter*)it.current(), areaList, rec );
+    }
+  }
+}
+
+QtxWorkstackArea* QtxWorkstack::activeArea() const
+{
+  return myArea;
+}
+
+QtxWorkstackArea* QtxWorkstack::targetArea()
+{
+  QtxWorkstackArea* area = activeArea();
+  if ( !area )
+    area = currentArea();
+  if ( !area )
+  {
+    QPtrList<QtxWorkstackArea> lst;
+    areas( mySplit, lst );
+    if ( !lst.isEmpty() )
+      area = lst.first();
+  }
+
+  if ( !area )
+    area = createArea( mySplit );
+
+  return area;
+}
+
+QtxWorkstackArea* QtxWorkstack::currentArea() const
+{
+  QtxWorkstackArea* area = 0;
+  QWidget* wid = focusWidget();
+  while ( wid && !area )
+  {
+    if ( wid->inherits( "QtxWorkstackArea" ) )
+      area = (QtxWorkstackArea*)wid;
+    wid = wid->parentWidget();
+  }
+
+  return area;
+}
+
+QtxWorkstackArea* QtxWorkstack::createArea( QWidget* parent ) const
+{
+  QtxWorkstackArea* area = new QtxWorkstackArea( parent );
+
+  connect( area, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+  connect( area, SIGNAL( activated( QWidget* ) ), this, SLOT( onWindowActivated( QWidget* ) ) );
+  connect( area, SIGNAL( contextMenuRequested( QWidget*, QPoint ) ),
+          this, SLOT( onContextMenuRequested( QWidget*, QPoint ) ) );
+  connect( area, SIGNAL( deactivated( QtxWorkstackArea* ) ), this, SLOT( onDeactivated( QtxWorkstackArea* ) ) );
+
+  return area;
+}
+
+void QtxWorkstack::setActiveArea( QtxWorkstackArea* area )
+{
+  QWidget* oldCur = myWin;
+
+  QtxWorkstackArea* oldArea = myArea;
+
+  myArea = area;
+
+  if ( myArea != oldArea )
+  {
+    if ( oldArea )
+      oldArea->updateActiveState();
+    if ( myArea )
+      myArea->updateActiveState();
+  }
+
+  if ( myArea )
+    myWin = myArea->activeWidget();
+
+  if ( myWin && oldCur != myWin )
+    emit windowActivated( myWin );
+}
+
+QtxWorkstackArea* QtxWorkstack::neighbourArea( QtxWorkstackArea* area ) const
+{
+  QPtrList<QtxWorkstackArea> lst;
+  areas( mySplit, lst, true );
+  int pos = lst.find( area );
+  if ( pos < 0 )
+    return 0;
+
+  QtxWorkstackArea* na = 0;
+  for ( int i = pos - 1; i >= 0 && !na; i-- )
+  {
+    if ( !lst.at( i )->isEmpty() )
+      na = lst.at( i );
+  }
+
+  for ( int j = pos + 1; j < (int)lst.count() && !na; j++ )
+  {
+    if ( !lst.at( j )->isEmpty() )
+        na = lst.at( j );
+  }
+  return na;
+}
+
+QtxWorkstackArea* QtxWorkstack::areaAt( const QPoint& p ) const
+{
+  QtxWorkstackArea* area = 0;
+  QPtrList<QtxWorkstackArea> lst;
+  areas( mySplit, lst, true );
+  for ( QPtrListIterator<QtxWorkstackArea> it( lst ); it.current() && !area; ++it )
+  {
+    QtxWorkstackArea* cur = it.current();
+    QRect r = cur->geometry();
+    if ( cur->parentWidget() )
+      r = QRect( cur->parentWidget()->mapToGlobal( r.topLeft() ), r.size() );
+    if ( r.contains( p ) )
+      area = cur;
+  }
+  return area;
+}
+
+void QtxWorkstack::updateState()
+{
+  updateState( mySplit );
+}
+
+void QtxWorkstack::updateState( QSplitter* split )
+{
+  QPtrList<QSplitter> recList;
+  splitters( split, recList, false );
+  for ( QPtrListIterator<QSplitter> itr( recList ); itr.current(); ++itr )
+    updateState( itr.current() );
+
+  QPtrList<QSplitter> splitList;
+  splitters( split, splitList, false );
+
+  QPtrList<QtxWorkstackArea> areaList;
+  areas( split, areaList, false );
+
+  bool vis = false;
+  for ( QPtrListIterator<QtxWorkstackArea> it( areaList ); it.current(); ++it )
+  {
+    if ( it.current()->isEmpty() )
+      it.current()->hide();
+    else
+    {
+      it.current()->show();
+      vis = true;
+    }
+  }
+
+  if ( split == mySplit )
+    return;
+
+  for ( QPtrListIterator<QSplitter> iter( splitList ); iter.current() && !vis; ++iter )
+    vis = iter.current()->isVisibleTo( iter.current()->parentWidget() );
+
+  if ( areaList.isEmpty() && splitList.isEmpty() )
+    delete split;
+  else if ( vis )
+    split->show();
+  else
+    split->hide();
+}
+
+/*!
+    Class: QtxWorkstackArea [Internal]
+    Descr:
+*/
+
+QtxWorkstackArea::QtxWorkstackArea( QWidget* parent )
+: QWidget( parent )
+{
+  QVBoxLayout* base = new QVBoxLayout( this );
+
+  QHBox* top = new QHBox( this );
+  base->addWidget( top );
+
+  myBar = new QtxWorkstackTabBar( top );
+
+  QPushButton* close = new QPushButton( top );
+  close->setPixmap( style().stylePixmap( QStyle::SP_TitleBarCloseButton ) );
+  close->setAutoDefault( true );
+  close->setFlat( true );
+  myClose = close;
+
+  top->setStretchFactor( myBar, 1 );
+
+  myStack = new QWidgetStack( this );
+
+  base->addWidget( myStack, 1 );
+
+  connect( myClose, SIGNAL( clicked() ), this, SLOT( onClose() ) );
+  connect( myBar, SIGNAL( selected( int ) ), this, SLOT( onSelected( int ) ) );
+  connect( myBar, SIGNAL( dragActiveTab() ), this, SLOT( onDragActiveTab() ) );
+  connect( myBar, SIGNAL( contextMenuRequested( QPoint ) ), this, SLOT( onContextMenuRequested( QPoint ) ) );
+
+  updateState();
+
+  updateActiveState();
+
+  qApp->installEventFilter( this );
+}
+
+QtxWorkstackArea::~QtxWorkstackArea()
+{
+  qApp->removeEventFilter( this );
+}
+
+bool QtxWorkstackArea::isEmpty() const
+{
+  bool res = false;
+  for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !res; ++it )
+    res = it.data().vis;
+  return !res;
+}
+
+void QtxWorkstackArea::insertWidget( QWidget* wid, const int idx )
+{
+  if ( !wid )
+    return;
+
+  int pos = myList.find( wid );
+  if ( pos != -1 && ( pos == idx || ( idx < 0 && pos == (int)myList.count() - 1 ) ) )
+    return;
+
+  myList.removeRef( wid );
+  pos = idx < 0 ? myList.count() : idx;
+  myList.insert( QMIN( pos, (int)myList.count() ), wid );
+  if ( !myInfo.contains( wid ) )
+  {
+    QtxWorkstackChild* child = new QtxWorkstackChild( wid, myStack );
+    myChild.insert( wid, child );
+    myInfo.insert( wid, WidgetInfo() );
+    myInfo[wid].id = generateId();
+    myInfo[wid].vis = wid->isVisibleTo( wid->parentWidget() );
+
+    connect( child, SIGNAL( destroyed( QObject* ) ), this, SLOT( onChildDestroyed( QObject* ) ) );
+    connect( wid, SIGNAL( destroyed() ), this, SLOT( onWidgetDestroyed() ) );
+    connect( child, SIGNAL( shown( QtxWorkstackChild* ) ), this, SLOT( onChildShown( QtxWorkstackChild* ) ) );
+    connect( child, SIGNAL( hided( QtxWorkstackChild* ) ), this, SLOT( onChildHided( QtxWorkstackChild* ) ) );
+    connect( child, SIGNAL( activated( QtxWorkstackChild* ) ), this, SLOT( onChildActivated( QtxWorkstackChild* ) ) );
+    connect( child, SIGNAL( captionChanged( QtxWorkstackChild* ) ), this, SLOT( onChildCaptionChanged( QtxWorkstackChild* ) ) );
+  }
+
+  updateState();
+
+  setWidgetActive( wid );
+  wid->setFocus();
+}
+
+void QtxWorkstackArea::onContextMenuRequested( QPoint p )
+{
+  const QtxWorkstackTabBar* bar = ::qt_cast<const QtxWorkstackTabBar*>( sender() );
+  if ( !bar )
+    return;
+
+  QWidget* wid = 0;
+  QTab* tab = myBar->tabAt( tabAt( p ) );
+  if ( tab )
+    wid = widget( tab->identifier() );
+
+  emit contextMenuRequested( wid, p );
+}
+
+void QtxWorkstackArea::onWidgetDestroyed()
+{
+  if ( sender() )
+    removeWidget( (QWidget*)sender(), false );
+}
+
+void QtxWorkstackArea::removeWidget( QWidget* wid, const bool del )
+{
+  if ( !myList.contains( wid ) )
+    return;
+
+  if ( myBar->tab( widgetId( wid ) ) )
+    myBar->removeTab( myBar->tab( widgetId( wid ) ) );
+  myStack->removeWidget( child( wid ) );
+
+  myList.remove( wid );
+  myInfo.remove( wid );
+  myChild.remove( wid );
+
+  if( del )
+  {
+    delete child( wid );
+    if( myList.isEmpty() )
+      delete this;
+    else
+      updateState();
+  }
+  else
+    updateState();
+}
+
+QWidgetList QtxWorkstackArea::widgetList() const
+{
+  QWidgetList lst;
+  for ( QWidgetListIt it( myList ); it.current(); ++it )
+  {
+    if ( widgetVisibility( it.current() ) )
+      lst.append( it.current() );
+  }
+  return lst;
+}
+
+QWidget* QtxWorkstackArea::activeWidget() const
+{
+  return widget( myBar->currentTab() );
+}
+
+void QtxWorkstackArea::setActiveWidget( QWidget* wid )
+{
+  myBar->setCurrentTab( widgetId( wid ) );
+}
+
+bool QtxWorkstackArea::contains( QWidget* wid ) const
+{
+  return myList.contains( wid );
+}
+
+void QtxWorkstackArea::show()
+{
+  QMap<QWidget*, bool> map;
+  for ( QWidgetListIt it( myList ); it.current(); ++it )
+  {
+    map.insert( it.current(), isBlocked( it.current() ) );
+    setBlocked( it.current(), true );
+  }
+
+  QWidget::show();
+
+  for ( QWidgetListIt itr( myList ); itr.current(); ++itr )
+    setBlocked( itr.current(), map.contains( itr.current() ) ? map[itr.current()] : false );
+}
+
+void QtxWorkstackArea::hide()
+{
+  QMap<QWidget*, bool> map;
+  for ( QWidgetListIt it( myList ); it.current(); ++it )
+  {
+    map.insert( it.current(), isBlocked( it.current() ) );
+    setBlocked( it.current(), true );
+  }
+
+  QWidget::hide();
+
+  for ( QWidgetListIt itr( myList ); itr.current(); ++itr )
+    setBlocked( itr.current(), map.contains( itr.current() ) ? map[itr.current()] : false );
+}
+
+bool QtxWorkstackArea::isActive() const
+{
+  QtxWorkstack* ws = workstack();
+  if ( !ws )
+    return false;
+
+  return ws->activeArea() == this;
+}
+
+void QtxWorkstackArea::updateActiveState()
+{
+  myBar->setActive( isActive() );
+}
+
+QtxWorkstack* QtxWorkstackArea::workstack() const
+{
+  QtxWorkstack* ws = 0;
+  QWidget* wid = parentWidget();
+  while ( wid && !ws )
+  {
+    if ( wid->inherits( "QtxWorkstack" ) )
+      ws = (QtxWorkstack*)wid;
+    wid = wid->parentWidget();
+  }
+  return ws;
+}
+
+bool QtxWorkstackArea::eventFilter( QObject* o, QEvent* e )
+{
+  if ( o->isWidgetType() )
+  {
+    QWidget* wid = (QWidget*)o;
+    if ( e->type() == QEvent::FocusIn || e->type() == QEvent::MouseButtonPress )
+    {
+      bool ok = false;
+      while ( !ok && wid && wid != myClose )
+      {
+        ok = wid == this;
+        wid = wid->parentWidget();
+      }
+      if ( ok )
+        QApplication::postEvent( this, new QCustomEvent( (QEvent::Type)( e->type() == QEvent::FocusIn ? ActivateWidget : FocusWidget ) ) );
+    }
+  }
+  return false;
+}
+
+QRect QtxWorkstackArea::floatRect() const
+{
+  QRect r = myStack->geometry();
+  return QRect( mapToGlobal( r.topLeft() ), mapToGlobal( r.bottomRight() ) );
+}
+
+QRect QtxWorkstackArea::floatTab( const int idx ) const
+{
+  return myBar->tabRect( idx );
+}
+
+int QtxWorkstackArea::tabAt( const QPoint& p ) const
+{
+  int idx = -1;
+  for ( int i = 0; i < myBar->count() && idx == -1; i++ )
+  {
+    QRect r = myBar->tabRect( i );
+    if ( r.isValid() && r.contains( p ) )
+      idx = i;
+  }
+  return idx;
+}
+
+void QtxWorkstackArea::customEvent( QCustomEvent* e )
+{
+  switch ( e->type() )
+  {
+  case ActivateWidget:
+    emit activated( activeWidget() );
+    break;
+  case FocusWidget:
+    if ( activeWidget() )
+    {
+      if ( !activeWidget()->focusWidget() )
+        activeWidget()->setFocus();
+      else {
+        if ( activeWidget()->focusWidget()->hasFocus()) {
+          QFocusEvent in(QEvent::FocusIn);
+         QApplication::sendEvent(this, &in);
+       }
+        else
+          activeWidget()->focusWidget()->setFocus();
+      }
+    }
+    break;
+  case RemoveWidget:
+    removeWidget( (QWidget*)e->data() );
+    break;
+  }
+}
+
+void QtxWorkstackArea::focusInEvent( QFocusEvent* e )
+{
+  QWidget::focusInEvent( e );
+
+  emit activated( activeWidget() );
+}
+
+void QtxWorkstackArea::mousePressEvent( QMouseEvent* e )
+{
+  QWidget::mousePressEvent( e );
+
+  emit activated( activeWidget() );
+}
+
+void QtxWorkstackArea::onClose()
+{
+  QWidget* wid = activeWidget();
+  if ( wid )
+    wid->close();
+}
+
+void QtxWorkstackArea::onSelected( int id )
+{
+  updateCurrent();
+
+  emit activated( activeWidget() );
+}
+
+void QtxWorkstackArea::onDragActiveTab()
+{
+  QtxWorkstackChild* c = child( activeWidget() );
+  if ( !c )
+    return;
+
+  new QtxWorkstackDrag( workstack(), c );
+}
+
+void QtxWorkstackArea::onChildDestroyed( QObject* obj )
+{
+  QtxWorkstackChild* child = (QtxWorkstackChild*)obj;
+  myStack->removeWidget( child );
+
+  QWidget* wid = 0;
+  for ( ChildMap::ConstIterator it = myChild.begin(); it != myChild.end() && !wid; ++it )
+  {
+    if ( it.data() == child )
+      wid = it.key();
+  }
+
+  myChild.remove( wid );
+
+  QApplication::postEvent( this, new QCustomEvent( (QEvent::Type)RemoveWidget, wid ) );
+}
+
+void QtxWorkstackArea::onChildShown( QtxWorkstackChild* c )
+{
+  setWidgetShown( c->widget(), true );
+}
+
+void QtxWorkstackArea::onChildHided( QtxWorkstackChild* c )
+{
+  setWidgetShown( c->widget(), false );
+}
+
+void QtxWorkstackArea::onChildActivated( QtxWorkstackChild* c )
+{
+  setWidgetActive( c->widget() );
+}
+
+void QtxWorkstackArea::onChildCaptionChanged( QtxWorkstackChild* c )
+{
+  updateTab( c->widget() );
+}
+
+void QtxWorkstackArea::updateCurrent()
+{
+  QMap<QWidget*, bool> map;
+  for ( QWidgetListIt it( myList ); it.current(); ++it )
+  {
+    map.insert( it.current(), isBlocked( it.current() ) );
+    setBlocked( it.current(), true );
+  }
+
+  myStack->raiseWidget( myBar->currentTab() );
+
+  for ( QWidgetListIt itr( myList ); itr.current(); ++itr )
+    setBlocked( itr.current(), map.contains( itr.current() ) ? map[itr.current()] : false );
+}
+
+void QtxWorkstackArea::updateTab( QWidget* wid )
+{
+  QTab* tab = myBar->tab( widgetId( wid ) );
+  if ( !tab )
+    return;
+
+  QIconSet icoSet;
+  if ( wid->icon() )
+  {
+    QPixmap pix = *wid->icon();
+    pix.convertFromImage( pix.convertToImage().smoothScale( pix.width(), 16, QImage::ScaleMin ) );
+    icoSet = QIconSet( pix );
+  }
+
+  tab->setIconSet( icoSet );
+  tab->setText( wid->caption() );
+}
+
+QWidget* QtxWorkstackArea::widget( const int id ) const
+{
+  QWidget* wid = 0;
+  for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !wid; ++it )
+  {
+    if ( it.data().id == id )
+      wid = it.key();
+  }
+  return wid;
+}
+
+int QtxWorkstackArea::widgetId( QWidget* wid ) const
+{
+  int id = -1;
+  if ( myInfo.contains( wid ) )
+    id = myInfo[wid].id;
+  return id;
+}
+
+bool QtxWorkstackArea::widgetVisibility( QWidget* wid ) const
+{
+  bool res = false;
+  if ( myInfo.contains( wid ) )
+    res = myInfo[wid].vis;
+  return res;
+}
+
+void QtxWorkstackArea::setWidgetActive( QWidget* wid )
+{
+  int id = widgetId( wid );
+  if ( id < 0 )
+    return;
+
+  myBar->setCurrentTab( id );
+}
+
+void QtxWorkstackArea::setWidgetShown( QWidget* wid, const bool on )
+{
+  if ( isBlocked( wid ) || !myInfo.contains( wid ) || myInfo[wid].vis == on )
+    return;
+
+  myInfo[wid].vis = on;
+  updateState();
+}
+
+void QtxWorkstackArea::updateState()
+{
+  bool updBar = myBar->isUpdatesEnabled();
+  bool updStk = myStack->isUpdatesEnabled();
+  myBar->setUpdatesEnabled( false );
+  myStack->setUpdatesEnabled( false );
+
+  bool block = myBar->signalsBlocked();
+  myBar->blockSignals( true );
+
+  QWidget* prev = activeWidget();
+
+  int idx = 0;
+  for ( QWidgetListIt it( myList ); it.current(); ++it )
+  {
+    QWidget* wid = it.current();
+    int id = widgetId( wid );
+
+    if ( id < 0 )
+      continue;
+
+    bool vis = widgetVisibility( wid );
+
+    if ( myBar->tab( id ) && ( !vis || myBar->indexOf( id ) != idx ) )
+      myBar->removeTab( myBar->tab( id ) );
+
+    if ( !myBar->tab( id ) && vis )
+    {
+      QTab* tab = new QTab( wid->caption() );
+      myBar->insertTab( tab, idx );
+      tab->setIdentifier( id );
+    }
+
+    updateTab( wid );
+
+    bool block = isBlocked( wid );
+    setBlocked( wid, true );
+
+    QtxWorkstackChild* cont = child( wid );
+
+    if ( !vis )
+      myStack->removeWidget( cont );
+    else if ( !myStack->widget( id ) )
+      myStack->addWidget( cont, id );
+
+    if ( vis )
+      idx++;
+
+    setBlocked( wid, block );
+  }
+
+  int curId = widgetId( prev );
+  if ( !myBar->tab( curId ) )
+  {
+    QWidget* wid = 0;
+    int pos = myList.find( prev );
+    for ( int i = pos - 1; i >= 0 && !wid; i-- )
+    {
+      if ( widgetVisibility( myList.at( i ) ) )
+        wid = myList.at( i );
+    }
+
+    for ( int j = pos + 1; j < (int)myList.count() && !wid; j++ )
+    {
+      if ( widgetVisibility( myList.at( j ) ) )
+        wid = myList.at( j );
+    }
+
+    if ( wid )
+      curId = widgetId( wid );
+  }
+
+  myBar->setCurrentTab( curId );
+
+  myBar->blockSignals( block );
+
+  updateCurrent();
+
+  myBar->setUpdatesEnabled( updBar );
+  myStack->setUpdatesEnabled( updStk );
+  if ( updBar )
+    myBar->update();
+  if ( updStk )
+    myStack->update();
+
+  QResizeEvent re( myBar->size(), myBar->size() );
+  QApplication::sendEvent( myBar, &re );
+
+  if ( isEmpty() )
+  {
+    hide();
+    emit deactivated( this );
+  }
+  else
+  {
+    show();
+    if ( prev != activeWidget() )
+      emit activated( activeWidget() );
+  }
+}
+
+int QtxWorkstackArea::generateId() const
+{
+  QMap<int, int> map;
+
+  for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end(); ++it )
+    map.insert( it.data().id, 0 );
+
+  int id = 0;
+  while ( map.contains( id ) )
+    id++;
+
+  return id;
+}
+
+bool QtxWorkstackArea::isBlocked( QWidget* wid ) const
+{
+  return myBlock.contains( wid );
+}
+
+void QtxWorkstackArea::setBlocked( QWidget* wid, const bool on )
+{
+  if ( on )
+    myBlock.insert( wid, 0 );
+  else
+    myBlock.remove( wid );
+}
+
+QtxWorkstackChild* QtxWorkstackArea::child( QWidget* wid ) const
+{
+  QtxWorkstackChild* res = 0;
+  if ( myChild.contains( wid ) )
+    res = myChild[wid];
+  return res;
+}
+
+/*!
+    Class: QtxWorkstackChild [Internal]
+    Descr:
+*/
+
+QtxWorkstackChild::QtxWorkstackChild( QWidget* wid, QWidget* parent )
+: QHBox( parent ),
+myWidget( wid )
+{
+  myWidget->reparent( this, QPoint( 0, 0 ), myWidget->isVisibleTo( myWidget->parentWidget() ) );
+  myWidget->installEventFilter( this );
+
+  connect( myWidget, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+}
+
+QtxWorkstackChild::~QtxWorkstackChild()
+{
+  qApp->removeEventFilter( this );
+
+  if ( !widget() )
+    return;
+
+  widget()->removeEventFilter( this );
+  widget()->reparent( 0, QPoint( 0, 0 ), false );
+  disconnect( widget(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+}
+
+QWidget* QtxWorkstackChild::widget() const
+{
+  return myWidget;
+}
+
+bool QtxWorkstackChild::eventFilter( QObject* o, QEvent* e )
+{
+  if ( o->isWidgetType() )
+  {
+    if ( e->type() == QEvent::CaptionChange || e->type() == QEvent::IconChange )
+      emit captionChanged( this );
+
+    if ( !e->spontaneous() && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) )
+      emit shown( this );
+
+    if ( !e->spontaneous() && ( e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
+      emit hided( this );
+
+    if ( e->type() == QEvent::FocusIn )
+      emit activated( this );
+  }
+  return QHBox::eventFilter( o, e );
+}
+
+void QtxWorkstackChild::onDestroyed( QObject* obj )
+{
+  if ( obj != widget() )
+    return;
+
+  myWidget = 0;
+  deleteLater();
+}
+
+void QtxWorkstackChild::childEvent( QChildEvent* e )
+{
+  if ( e->type() == QEvent::ChildRemoved && e->child() == widget() )
+  {
+    myWidget = 0;
+    deleteLater();
+  }
+  QHBox::childEvent( e );
+}
+
+/*!
+    Class: QtxWorkstackTabBar [Internal]
+    Descr:
+*/
+
+QtxWorkstackTabBar::QtxWorkstackTabBar( QWidget* parent )
+: QTabBar( parent ),
+myId( -1 )
+{
+}
+
+QtxWorkstackTabBar::~QtxWorkstackTabBar()
+{
+}
+
+void QtxWorkstackTabBar::setActive( const bool on )
+{
+  QFont aFont = font();
+  aFont.setUnderline( on );
+  QColorGroup* aColGrp = new QColorGroup();
+  QPalette aPal = palette();
+  if ( !on ) {
+    aPal.setColor( QColorGroup::HighlightedText, aColGrp->foreground() );
+    aPal.setColor( QColorGroup::Highlight, colorGroup().dark().light( DARK_COLOR_LIGHT ) );
+    setPalette( aPal );
+  }
+  else {
+    aPal.setColor( QColorGroup::HighlightedText, aColGrp->highlightedText() );
+    aPal.setColor( QColorGroup::Highlight, aColGrp->highlight() );
+    unsetPalette();
+  }
+  setFont( aFont );
+
+  update();
+}
+
+QRect QtxWorkstackTabBar::tabRect( const int idx ) const
+{
+  QRect r;
+  QTab* t = tabAt( idx );
+  if ( t )
+  {
+    r = t->rect();
+    r.setLeft( QMAX( r.left(), 0 ) );
+
+    int x1 = tabAt( 0 )->rect().left();
+    int x2 = tabAt( count() - 1 )->rect().right();
+
+    int bw = 0;
+    if ( QABS( x2 - x1 ) > width() )
+#if defined QT_VERSION && QT_VERSION >= 0x30300
+      bw = 2 * style().pixelMetric( QStyle::PM_TabBarScrollButtonWidth, this );
+#else
+      bw = 2 * 16;
+#endif
+
+    int limit = width() - bw;
+    r.setRight( QMIN( r.right(), limit ) );
+
+    r = QRect( mapToGlobal( r.topLeft() ), r.size() );
+  }
+  return r;
+}
+
+void QtxWorkstackTabBar::mouseMoveEvent( QMouseEvent* e )
+{
+  if ( myId != -1 && !tab( myId )->rect().contains( e->pos() ) )
+  {
+    myId = -1;
+    emit dragActiveTab();
+  }
+
+  QTabBar::mouseMoveEvent( e );
+}
+
+void QtxWorkstackTabBar::mousePressEvent( QMouseEvent* e )
+{
+  QTabBar::mousePressEvent( e );
+
+  if ( e->button() == LeftButton )
+    myId = currentTab();
+}
+
+void QtxWorkstackTabBar::mouseReleaseEvent( QMouseEvent* e )
+{
+  QTabBar::mouseReleaseEvent( e );
+
+  myId = -1;
+
+  if ( e->button() == RightButton )
+    emit contextMenuRequested( e->globalPos() );
+}
+
+void QtxWorkstackTabBar::contextMenuEvent( QContextMenuEvent* e )
+{
+  if ( e->reason() != QContextMenuEvent::Mouse )
+    emit contextMenuRequested( e->globalPos() );
+}
+
+void QtxWorkstackTabBar::paintLabel( QPainter* p, const QRect& br, QTab* t, bool has_focus ) const
+{
+  if ( currentTab() != t->identifier() )
+  {
+    QFont fnt = p->font();
+    fnt.setUnderline( false );
+    p->setFont( fnt );
+  }
+  QTabBar::paintLabel( p, br, t, has_focus );
+}
+
+/*!
+    Class: QtxWorkstackDrag [Internal]
+    Descr:
+*/
+
+QtxWorkstackDrag::QtxWorkstackDrag( QtxWorkstack* ws, QtxWorkstackChild* child )
+: QObject( 0 ),
+myWS( ws ),
+myTab( -1 ),
+myArea( 0 ),
+myPainter( 0 ),
+myChild( child )
+{
+  qApp->installEventFilter( this );
+}
+
+QtxWorkstackDrag::~QtxWorkstackDrag()
+{
+  qApp->removeEventFilter( this );
+
+  endDrawRect();
+}
+
+bool QtxWorkstackDrag::eventFilter( QObject*, QEvent* e )
+{
+  switch ( e->type() )
+  {
+  case QEvent::MouseMove:
+    updateTarget( ((QMouseEvent*)e)->globalPos() );
+    break;
+  case QEvent::MouseButtonRelease:
+    drawRect();
+    endDrawRect();
+    dropWidget();
+    deleteLater();
+    break;
+  default:
+    return false;
+  }
+  return true;
+}
+
+void QtxWorkstackDrag::updateTarget( const QPoint& p )
+{
+  int tab = -1;
+  QtxWorkstackArea* area = detectTarget( p, tab );
+  setTarget( area, tab );
+}
+
+QtxWorkstackArea* QtxWorkstackDrag::detectTarget( const QPoint& p, int& tab ) const
+{
+  if ( p.isNull() )
+    return 0;
+
+  QtxWorkstackArea* area = myWS->areaAt( p );
+  if ( area )
+    tab = area->tabAt( p );
+  return area;
+}
+
+void QtxWorkstackDrag::setTarget( QtxWorkstackArea* area, const int tab )
+{
+  if ( !area || ( myArea == area && tab == myTab ) )
+    return;
+
+  startDrawRect();
+
+  if ( myArea )
+    drawRect();
+
+  myTab = tab;
+  myArea = area;
+
+  if ( myArea )
+    drawRect();
+}
+
+void QtxWorkstackDrag::dropWidget()
+{
+  if ( myArea )
+    myArea->insertWidget( myChild->widget(), myTab );
+}
+
+void QtxWorkstackDrag::drawRect()
+{
+  if ( !myPainter || !myArea )
+    return;
+
+  QRect r = myArea->floatRect();
+  int m = myPainter->pen().width();
+
+  r.setTop( r.top() + m + 2 );
+  r.setLeft( r.left() + m + 2 );
+  r.setRight( r.right() - m - 2 );
+  r.setBottom( r.bottom() - m - 2 );
+
+  myPainter->drawRect( r );
+
+  QRect tr = myArea->floatTab( myTab );
+  tr.setTop( tr.top() + m );
+  tr.setLeft( tr.left() + m );
+  tr.setRight( tr.right() - m );
+  tr.setBottom( tr.bottom() - m );
+
+  myPainter->drawRect( tr );
+}
+
+void QtxWorkstackDrag::endDrawRect()
+{
+  delete myPainter;
+  myPainter = 0;
+}
+
+void QtxWorkstackDrag::startDrawRect()
+{
+  if ( myPainter )
+    return;
+
+  int scr = QApplication::desktop()->screenNumber( (QWidget*)this );
+  QWidget* paint_on = QApplication::desktop()->screen( scr );
+
+  myPainter = new QPainter( paint_on, true );
+  myPainter->setPen( QPen( gray, 3 ) );
+  myPainter->setRasterOp( XorROP );
+}
diff --git a/src/Qtx/QtxWorkstack.h b/src/Qtx/QtxWorkstack.h
new file mode 100644 (file)
index 0000000..8157a2a
--- /dev/null
@@ -0,0 +1,338 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// File:      QtxWorkstack.h
+// Author:    Sergey TELKOV
+
+#ifndef QTXWORKSTACK_H
+#define QTXWORKSTACK_H
+
+#include "Qtx.h"
+
+#include <qhbox.h>
+#include <qwidget.h>
+#include <qtabbar.h>
+#include <qwidgetlist.h>
+
+class QAction;
+class QTabBar;
+class QPainter;
+class QSplitter;
+class QPushButton;
+class QWidgetStack;
+
+class QtxWorkstackArea;
+class QtxWorkstackDrag;
+class QtxWorkstackChild;
+class QtxWorkstackTabBar;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QTX_EXPORT QtxWorkstack : public QWidget
+{
+  Q_OBJECT
+
+public:
+  enum { SplitVertical, SplitHorizontal, Close, Rename };
+    
+  enum SplitType
+  {
+    SPLIT_STAY, //!< given widget stays in its workarea, others are moved into a new one
+    SPLIT_AT,   //!< widgets before a given widget stays in they workarea, others are moved into a new one
+    SPLIT_MOVE  //!< given widget is moved into a new workarea, others stay in an old one
+  };
+
+public:
+  QtxWorkstack( QWidget* = 0 );
+  virtual ~QtxWorkstack();
+
+  QWidgetList         windowList() const;
+  QWidgetList         splitWindowList() const;
+
+  QWidget*            activeWindow() const;
+
+  int                 accel( const int ) const;
+  void                setAccel( const int, const int );
+
+  void                split( const int );
+
+  // STV: Useless function. wid->setFocus() should be used instead.
+  // void OnTop( QWidget* wid);
+
+  void Split( QWidget* wid, const Qt::Orientation o, const SplitType type );
+  void Attract( QWidget* wid1, QWidget* wid2, const bool all );
+  void SetRelativePosition( QWidget* wid, const Qt::Orientation o, const double pos );
+  void SetRelativePositionInSplitter( QWidget* wid, const double pos );
+
+signals:
+  void                windowActivated( QWidget* );
+
+public slots:
+  void                splitVertical();
+  void                splitHorizontal();
+  
+private slots:
+  void                onRename();
+  void                onCloseWindow();
+  void                onDestroyed( QObject* );
+  void                onWindowActivated( QWidget* );
+  void                onContextMenuRequested( QWidget*, QPoint );
+  void                onDeactivated( QtxWorkstackArea* );
+
+protected:
+  virtual void        childEvent( QChildEvent* );
+  virtual void        customEvent( QCustomEvent* );
+
+private:
+  QSplitter*          splitter( QtxWorkstackArea* ) const;
+  void                splitters( QSplitter*, QPtrList<QSplitter>&, const bool = false ) const;
+  void                areas( QSplitter*, QPtrList<QtxWorkstackArea>&, const bool = false ) const;
+
+  QSplitter*          wrapSplitter( QtxWorkstackArea* );
+  void                insertWidget( QWidget*, QWidget*, QWidget* );
+
+  QtxWorkstackArea*   areaAt( const QPoint& ) const;
+
+  QtxWorkstackArea*   targetArea();
+  QtxWorkstackArea*   activeArea() const;
+  QtxWorkstackArea*   currentArea() const;
+
+  void                setActiveArea( QtxWorkstackArea* );
+  QtxWorkstackArea*   neighbourArea( QtxWorkstackArea* ) const;
+
+  QtxWorkstackArea*   createArea( QWidget* ) const;
+
+  void                updateState();
+  void                updateState( QSplitter* );
+
+  void                distributeSpace( QSplitter* ) const;
+  int                 setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
+                                                          const int need_pos, const int splitter_pos );
+
+private:
+  QWidget*            myWin;
+  QtxWorkstackArea*   myArea;
+  QSplitter*          mySplit;
+  QWidget*            myWorkWin;
+  QtxWorkstackArea*   myWorkArea;
+
+  QMap<int, QAction*> myActionsMap; //!< The map of the actions. Allows to get the QAction object by the key.
+
+  friend class QtxWorkstackArea;
+  friend class QtxWorkstackDrag;
+};
+
+class QtxWorkstackArea : public QWidget
+{
+  Q_OBJECT
+
+public:
+  QtxWorkstackArea( QWidget* );
+  virtual ~QtxWorkstackArea();
+
+  bool                isEmpty() const;
+
+  void                insertWidget( QWidget*, const int = -1 );
+  void                removeWidget( QWidget*, const bool = true );
+
+  QWidget*            activeWidget() const;
+  void                setActiveWidget( QWidget* );
+
+  bool                contains( QWidget* ) const;
+
+  QWidgetList         widgetList() const;
+
+  bool                isActive() const;
+  void                updateActiveState();
+
+  QtxWorkstack*       workstack() const;
+
+  virtual bool        eventFilter( QObject*, QEvent* );
+
+  QRect               floatRect() const;
+  QRect               floatTab( const int ) const;
+
+  int                 tabAt( const QPoint& ) const;
+
+signals:
+  void                activated( QWidget* );
+  void                contextMenuRequested( QWidget*, QPoint );
+  void                deactivated( QtxWorkstackArea* );
+
+public slots:
+  virtual void        show();
+  virtual void        hide();
+
+private slots:
+  void                onClose();
+  void                onSelected( int );
+
+  void                onWidgetDestroyed();
+
+  void                onChildDestroyed( QObject* );
+  void                onChildShown( QtxWorkstackChild* );
+  void                onChildHided( QtxWorkstackChild* );
+  void                onChildActivated( QtxWorkstackChild* );
+  void                onChildCaptionChanged( QtxWorkstackChild* );
+
+  void                onDragActiveTab();
+  void                onContextMenuRequested( QPoint );
+
+protected:
+  virtual void        customEvent( QCustomEvent* );
+  virtual void        focusInEvent( QFocusEvent* );
+  virtual void        mousePressEvent( QMouseEvent* );
+
+private:
+  enum { ActivateWidget = QEvent::User, FocusWidget, RemoveWidget };
+
+private:
+  void                updateState();
+  void                updateCurrent();
+  void                updateTab( QWidget* );
+
+  QWidget*            widget( const int ) const;
+  int                 widgetId( QWidget* ) const;
+  bool                widgetVisibility( QWidget* ) const;
+
+  void                setWidgetActive( QWidget* );
+  void                setWidgetShown( QWidget*, const bool );
+
+  int                 generateId() const;
+
+  bool                isBlocked( QWidget* ) const;
+  void                setBlocked( QWidget*, const bool );
+
+  QtxWorkstackChild*  child( QWidget* ) const;
+
+private:
+  struct WidgetInfo
+  {
+    WidgetInfo() : id( 0 ), vis( false ) {}
+    int id; bool vis;
+  };
+
+  typedef QMap<QWidget*, bool>               BlockMap;
+  typedef QMap<QWidget*, QtxWorkstackChild*> ChildMap;
+  typedef QMap<QWidget*, WidgetInfo>         WidgetInfoMap;
+
+private:
+  QtxWorkstackTabBar* myBar;
+  QPushButton*        myClose;
+  QWidgetStack*       myStack;
+
+  QWidgetList         myList;
+  WidgetInfoMap       myInfo;
+  ChildMap            myChild;
+  BlockMap            myBlock;
+};
+
+class QtxWorkstackChild : public QHBox
+{
+  Q_OBJECT
+
+public:
+  QtxWorkstackChild( QWidget*, QWidget* = 0 );
+  virtual ~QtxWorkstackChild();
+
+  QWidget*            widget() const;
+
+  virtual bool        eventFilter( QObject*, QEvent* );
+
+signals:
+  void                shown( QtxWorkstackChild* );
+  void                hided( QtxWorkstackChild* );
+  void                activated( QtxWorkstackChild* );
+  void                captionChanged( QtxWorkstackChild* );
+
+private slots:
+  void                onDestroyed( QObject* );
+
+protected:
+  virtual void        childEvent( QChildEvent* );
+
+private:
+  QWidget*            myWidget;
+};
+
+class QtxWorkstackTabBar : public QTabBar
+{
+  Q_OBJECT
+
+public:
+  QtxWorkstackTabBar( QWidget* = 0 );
+  virtual ~QtxWorkstackTabBar();
+
+  QRect               tabRect( const int ) const;
+
+  void                setActive( const bool );
+
+signals:
+  void                dragActiveTab();
+  void                contextMenuRequested( QPoint );
+
+protected:
+  virtual void        mouseMoveEvent( QMouseEvent* );
+  virtual void        mousePressEvent( QMouseEvent* );
+  virtual void        mouseReleaseEvent( QMouseEvent* );
+  virtual void        contextMenuEvent( QContextMenuEvent* );
+
+  virtual void        paintLabel( QPainter*, const QRect&, QTab*, bool ) const;
+
+private:
+  int                 myId;
+};
+
+class QtxWorkstackDrag : public QObject
+{
+  Q_OBJECT
+
+public:
+  QtxWorkstackDrag( QtxWorkstack*, QtxWorkstackChild* );
+  virtual ~QtxWorkstackDrag();
+
+  virtual bool        eventFilter( QObject*, QEvent* );
+
+private:
+  void                dropWidget();
+
+  void                updateTarget( const QPoint& );
+  QtxWorkstackArea*   detectTarget( const QPoint&, int& ) const;
+  void                setTarget( QtxWorkstackArea*, const int );
+
+  void                drawRect();
+  void                endDrawRect();
+  void                startDrawRect();
+
+private:
+  QtxWorkstack*       myWS;
+  QtxWorkstackChild*  myChild;
+
+  int                 myTab;
+  QtxWorkstackArea*   myArea;
+  QPainter*           myPainter;
+  
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx
new file mode 100644 (file)
index 0000000..3cb6cbb
--- /dev/null
@@ -0,0 +1,1345 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+//=============================================================================
+// File      : SALOME_PYQT_Module.cxx
+// Created   : 25/04/05
+// Author    : Vadim SANDLER
+// Project   : SALOME
+// Copyright : 2003-2005 CEA/DEN, EDF R&D
+// $Header   : $
+//=============================================================================
+
+#include "SALOME_PYQT_Module.h"
+
+#include "PyInterp_Dispatcher.h"
+#include "SUIT_ResourceMgr.h"
+#include "STD_MDIDesktop.h"
+#include "STD_TabDesktop.h"
+#include "SalomeApp_Application.h"
+#include "SalomeApp_Study.h"
+
+#include "QtxWorkstack.h"
+#include <SALOME_LifeCycleCORBA.hxx>
+#include <Container_init_python.hxx>
+
+#include <qfile.h>
+#include <qdom.h>
+#include <qworkspace.h>
+#include <qpopupmenu.h>
+
+#include "SALOME_PYQT_SipDefs.h"
+#if defined(SIP_VERS_v4_old) || defined(SIP_VERS_v4_new)
+#include "sipAPISalomePyQtGUI.h"
+#else
+#include "sipSalomePyQtGUIDeclSalomePyQtGUI.h"
+#endif
+
+#include <sipqtQWidget.h>
+#include <sipqtQPopupMenu.h>
+
+#include <CORBA.h>
+
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+// Default name of the module, replaced at the moment of module creation
+#define __DEFAULT_NAME__ "SALOME_PYQT_Module"
+
+///////////////////////////////////////////////////////////////////////////////
+// If __CALL_OLD_METHODS__ macro is not defined the invoking of obsolete Python 
+// module's methods like setSetting(), definePopup(), etc. is blocked.
+// This macro is defined by default (in Makefile)
+#ifdef __CALL_OLD_METHODS__
+const bool IsCallOldMethods = true;
+#else 
+const bool IsCallOldMethods = false;
+#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.
+///////////////////////////////////////////////////////////////////////////////
+
+//=============================================================================
+// The class for parsing of the XML resource files.
+// Used for backward compatibility with existing Python modules.
+//=============================================================================
+class SALOME_PYQT_XmlHandler
+{
+public:
+  SALOME_PYQT_XmlHandler( SALOME_PYQT_Module* module, const QString& fileName );
+  void createActions();
+  void createPopup  ( QPopupMenu*    menu, 
+                     const QString& context, 
+                     const QString& parent, 
+                     const QString& object );
+
+protected:
+  void createToolBar   ( QDomNode& parentNode );
+  void createMenu      ( QDomNode& parentNode, 
+                        const int parentMenuId = -1 );
+
+  void insertPopupItems( QDomNode&   parentNode, 
+                        QPopupMenu* menu );
+
+private:
+  SALOME_PYQT_Module* myModule;
+  QDomDocument        myDoc;
+};
+
+//=============================================================================
+// SALOME_PYQT_Module class implementation (implements CAM_Module API for
+// all Python-based SALOME module
+//=============================================================================
+
+// While the SalomePyQtGUI 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
+#if defined(SIP_STATIC_MODULE)
+extern "C" void initSalomePyQtGUI();
+#else
+PyMODINIT_FUNC initSalomePyQtGUI();
+#endif
+
+/*!
+ * This function creates an instance of SALOME_PYQT_Module object by request
+ * of and application object when the module is loaded.
+ */
+extern "C" {
+  SALOME_PYQT_EXPORT CAM_Module* createModule() {
+    static bool alreadyInitialized = false;
+    if ( !alreadyInitialized ) {
+      // call only once (see above) !
+      PyEval_RestoreThread( KERNEL_PYTHON::_gtstate );
+      initSalomePyQtGUI(); 
+      PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );
+      alreadyInitialized = !alreadyInitialized;
+    }
+    return new SALOME_PYQT_Module();
+  }
+}
+
+/*! 
+ * Static variables definition
+ */
+SALOME_PYQT_Module::InterpMap SALOME_PYQT_Module::myInterpMap;
+SALOME_PYQT_Module* SALOME_PYQT_Module::myInitModule = 0;
+
+/*!
+ * Little trick : provide an access to being activated Python module from outside;
+ * needed by the SalomePyQt library :(
+*/
+SALOME_PYQT_Module* SALOME_PYQT_Module::getInitModule() 
+{ 
+  return myInitModule; 
+}
+
+/*!
+ * Constructor
+ */
+SALOME_PYQT_Module::SALOME_PYQT_Module() :
+       SalomeApp_Module( __DEFAULT_NAME__ ), myModule( 0 ), myXmlHandler ( 0 )
+{
+  myMenuActionList.setAutoDelete( false );
+  myPopupActionList.setAutoDelete( false );
+  myToolbarActionList.setAutoDelete( false );
+}
+
+/*!
+ * Destructor
+ */
+SALOME_PYQT_Module::~SALOME_PYQT_Module()
+{
+  myMenuActionList.clear();
+  myPopupActionList.clear();
+  myToolbarActionList.clear();
+  if ( myXmlHandler )
+    delete myXmlHandler;
+}
+
+/*!
+ * Initialization of the module.
+ * Inherited from CAM_Module.
+ *
+ * This method is used for creation of the menus, toolbars and other staff.
+ * There are two ways:
+ * - 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 by calling the corresponding methods of SalomePyQt
+ *   Python API in the Python module's initialize() method which is called from here.
+ * NOTE: if postponed modules loading is not used, the active study might be not defined
+ * yet at this stage, so initialize() method should not perform any study-based initialization.
+ */
+void SALOME_PYQT_Module::initialize( CAM_Application* app )
+{
+  SalomeApp_Module::initialize( app );
+
+  // Try to get XML resource file name
+  SUIT_ResourceMgr* aResMgr = getApp()->resourceMgr();
+  QString aLang = aResMgr->stringValue( "language", "language", QString::null );
+  if ( aLang.isEmpty() ) aLang = QString( "en" );
+  QString aName = name( "" );
+  QString aFileName = aName + "_" + aLang + ".xml";
+  aFileName = aResMgr->path( "resources", aName, aFileName );
+  // parse XML file if it is found and create actions
+  if ( !myXmlHandler && !aFileName.isEmpty() ) {
+    myXmlHandler = new SALOME_PYQT_XmlHandler( this, aFileName );
+    myXmlHandler->createActions();
+  }
+
+  // perform internal initialization and call module's initialize() method
+  // InitializeReq: request class for internal init() operation
+  class InitializeReq : public PyInterp_Request
+  {
+  public:
+    InitializeReq( CAM_Application*    _app,
+                  SALOME_PYQT_Module* _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_Module* myObj;
+  };
+
+  // Posting the request
+  PyInterp_Dispatcher::Get()->Exec( new InitializeReq( app, this ) );
+}
+
+/*!
+ * Activation of the module.
+ * Inherited from CAM_Module.
+ */
+bool SALOME_PYQT_Module::activateModule( SUIT_Study* theStudy )
+{
+  MESSAGE( "SALOME_PYQT_Module::activateModule" );
+
+  bool res = SalomeApp_Module::activateModule( theStudy );
+  
+  if ( !res )
+    return res;
+
+  // ActivateReq: request class for internal activate() operation
+  class ActivateReq : public PyInterp_Request
+  {
+  public:
+    ActivateReq( SUIT_Study*         _study, 
+                SALOME_PYQT_Module* _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_Module* myObj;
+  };
+
+  // Posting the request
+  PyInterp_Dispatcher::Get()->Exec( new ActivateReq( theStudy, this ) );
+
+  // activate menus, toolbars, etc
+  setMenuShown( true );
+  setToolShown( true );
+
+  return true;
+}
+
+/*!
+ * Deactivation of the module.
+ * Inherited from CAM_Module.
+ */
+bool SALOME_PYQT_Module::deactivateModule( SUIT_Study* theStudy )
+{
+  MESSAGE( "SALOME_PYQT_Module::deactivateModule" );
+
+  bool res = SalomeApp_Module::deactivateModule( theStudy );
+
+  // deactivate menus, toolbars, etc
+  setMenuShown( false );
+  setToolShown( false );
+
+  // DeactivateReq: request class for internal deactivate() operation
+  class DeactivateReq : public PyInterp_LockRequest
+  {
+  public:
+    DeactivateReq( PyInterp_base*      _py_interp, 
+                  SUIT_Study*         _study, 
+                  SALOME_PYQT_Module* _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_Module* myObj;
+  };
+
+  // Posting the request
+  PyInterp_Dispatcher::Get()->Exec( new DeactivateReq( myInterp, theStudy, this ) );
+
+  return res;
+}
+
+/*!
+ * Processes GUI action (from main menu, toolbar or context popup menu)
+ */
+void SALOME_PYQT_Module::onGUIEvent()
+{
+  // get sender action
+  const QObject* obj = sender();
+  if ( !obj || !obj->inherits( "QAction" ) )
+    return;
+  QAction* action = (QAction*)obj;
+
+  // get action ID
+  int id = actionId( action );
+  MESSAGE( "SALOME_PYQT_Module::onGUIEvent: id = " << id );
+
+  // perform synchronous request to Python event dispatcher
+  class GUIEvent : public PyInterp_LockRequest
+  {
+  public:
+    GUIEvent( PyInterp_base*      _py_interp, 
+             SALOME_PYQT_Module* _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_Module* myObj;
+  };
+
+  // Posting the request
+  PyInterp_Dispatcher::Get()->Exec( new GUIEvent( myInterp, this, id ) );
+}
+
+/*!
+ * Processes GUI action (from context popup menu, only for XML-based actions!)
+ */
+void SALOME_PYQT_Module::onGUIEvent( int id ) 
+{
+  // perform synchronous request to Python event dispatcher
+  class GUIEvent : public PyInterp_LockRequest
+  {
+  public:
+    GUIEvent( PyInterp_base*      _py_interp, 
+             SALOME_PYQT_Module* _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_Module* myObj;
+  };
+
+  // Posting the request
+  PyInterp_Dispatcher::Get()->Exec( new GUIEvent( myInterp, this, id ) );
+}
+
+/*! 
+  Context popup menu request.
+  Called when user activates popup menu in some window (view, object browser, etc).
+  */
+void SALOME_PYQT_Module::contextMenuPopup( const QString& theContext, QPopupMenu* thePopupMenu, QString& /*title*/ )
+{
+  MESSAGE( "SALOME_PYQT_Module::contextMenuPopup : " << theContext.latin1() );
+  // perform synchronous request to Python event dispatcher
+  class PopupMenuEvent : public PyInterp_LockRequest
+  {
+  public:
+    PopupMenuEvent( PyInterp_base*     _py_interp, 
+                   SALOME_PYQT_Module* _obj,
+                   const QString&      _context, 
+                   QPopupMenu*        _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_Module* myObj;
+    QString             myContext;
+    QPopupMenu*         myPopup;
+  };
+
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+    PyInterp_Dispatcher::Get()->Exec( new PopupMenuEvent( myInterp, this, theContext, thePopupMenu ) );
+}
+
+/*!
+ * Defines the dockable window associated with the module.
+ * To fill the list of windows the correspondind Python module's windows() 
+ * method is called from SALOME_PYQT_Module::init() method.
+ * By default, ObjectBrowser, PythonConsole and LogWindow are provided.
+ */
+void SALOME_PYQT_Module::windows( QMap<int, int>& mappa ) const
+{
+  // First clear the output parameters 
+  QMap<int, int>::ConstIterator it;
+  for ( it = myWindowsMap.begin(); it != myWindowsMap.end(); ++it ) {
+    mappa[ it.key() ] = it.data();
+  }
+}
+
+/*!
+ * Defines the compatible views which should be opened on module activation.
+ * To fill the list of views the correspondind Python module's views() 
+ * method is called from SALOME_PYQT_Module::init() method.
+ * By default, the list is empty.
+ */
+void SALOME_PYQT_Module::viewManagers( QStringList& listik ) const
+{
+  for ( QStringList::ConstIterator it = myViewMgrList.begin(); it != myViewMgrList.end(); ++it ) {
+    listik.append( *it );
+  }
+}
+
+/*!
+ * Performs internal initialization
+ * - initializes/gets the Python interpreter (one per study)
+ * - imports the Python module
+ * - passes the workspace widget to the Python module
+ * - calls Python module's initialize() method
+ * - calls Python module's windows() method
+ * - calls Python module's views() method
+ */
+void SALOME_PYQT_Module::init( CAM_Application* app )
+{
+  // reset interpreter to NULL
+  myInterp = NULL;
+
+  // get study Id
+  SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( app );
+  if ( !anApp )
+    return;
+
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+  if ( !aStudy )
+    return;
+  int aStudyId = aStudy ? aStudy->studyDS()->StudyId() : 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 
+  myInitModule = this;
+
+  if ( IsCallOldMethods ) { // __CALL_OLD_METHODS__
+    // call Python module's setWorkspace() method
+    setWorkSpace();
+  }                         //__CALL_OLD_METHODS__
+
+  // 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 , "initialize")){
+    PyObjWrapper res( PyObject_CallMethod( myModule, "initialize", "" ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+  
+  // get the windows list from the Python module by calling windows() method
+  // ... first put default values
+  myWindowsMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft );
+  myWindowsMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::DockBottom );
+  // VSR: LogWindow is not yet implemented
+  // myWindowsMap.insert( SalomeApp_Application::WT_LogWindow,     Qt::DockBottom );
+
+  if(PyObject_HasAttrString(myModule , "windows")){
+    PyObjWrapper res1( PyObject_CallMethod( myModule, "windows", "" ) );
+    if( !res1 ) {
+      PyErr_Print();
+    }
+    else {
+      myWindowsMap.clear();
+      if ( PyDict_Check( res1 ) ) {
+        PyObject* key;
+        PyObject* value;
+        int 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 the windows list from the Python module by calling views() method
+  if(PyObject_HasAttrString(myModule , "views")){
+    PyObjWrapper res2( PyObject_CallMethod( myModule, "views", "" ) );
+    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 ) );
+         }
+        }
+      }
+    }
+  }
+  myInitModule = 0;
+}
+
+/*!
+ * Performs internal activation: 
+ * - initializes/gets the Python interpreter (one per study)
+ * - imports the Python GUI module
+ * - calls Python module's setSettings() method (obsolete function, used for compatibility with old code)
+ *   or activate() method (for new modules)
+ */
+void SALOME_PYQT_Module::activate( SUIT_Study* theStudy )
+{
+  // get study Id
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theStudy );
+  int aStudyId = aStudy ? aStudy->studyDS()->StudyId() : 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 
+  // get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+  if ( IsCallOldMethods ) { //__CALL_OLD_METHODS__
+    // call Python module's setSettings() method (obsolete)
+    if(PyObject_HasAttrString(myModule , "setSettings")){
+      PyObjWrapper res( PyObject_CallMethod( myModule, "setSettings", "" ) );
+      if( !res ) {
+        PyErr_Print();
+      }
+    }
+  }                         //__CALL_OLD_METHODS__
+
+  // call Python module's activate() method (for the new modules)
+  if(PyObject_HasAttrString(myModule , "activate")){
+    PyObjWrapper res1( PyObject_CallMethod( myModule, "activate", "" ) );
+    if( !res1 ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+ * Performs internal deactivation: 
+ * - calls Python module's deactivate() method
+ */
+void SALOME_PYQT_Module::deactivate( SUIT_Study* theStudy )
+{
+  // 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 , "deactivate")){
+    PyObjWrapper res( PyObject_CallMethod( myModule, "deactivate", "" ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+ * Called when active the study is actived (user brings its desktop to top)
+ * - initializes/gets the Python interpreter (one per study)
+ * - imports the Python GUI module
+ * - calls Python module's activeStudyChanged() method
+ */
+void SALOME_PYQT_Module::studyChanged( SUIT_Study* theStudy )
+{
+  // get study Id
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theStudy );
+  int aStudyId = aStudy ? aStudy->studyDS()->StudyId() : 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 
+  // get python lock
+  PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+  // call Python module's activeStudyChanged() method
+  if(PyObject_HasAttrString(myModule , "activeStudyChanged")){
+    PyObjWrapper res( PyObject_CallMethod( myModule, "activeStudyChanged", "i", aStudyId ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+ * Get module engine, returns nil var if engine is not found in LifeCycleCORBA
+ */
+Engines::Component_var SALOME_PYQT_Module::getEngine() const
+{
+  Engines::Component_var comp;
+  // temporary solution
+  try {
+    comp = getApp()->lcc()->FindOrLoad_Component( "FactoryServerPy", name( "" ) );
+  }
+  catch (CORBA::Exception&) {
+  }
+  return comp;
+}
+
+/*!
+ * Get module engine IOR, returns empty string if engine is not found in LifeCycleCORBA
+ */
+QString SALOME_PYQT_Module::engineIOR() const
+{
+  if ( !CORBA::is_nil( getEngine() ) )
+    return QString( getApp()->orb()->object_to_string( getEngine() ) );
+  return QString( "" );
+}
+
+/*! 
+ * Called when study desktop is activated.
+ * Used for notifying about changing of the active study.
+ */
+void SALOME_PYQT_Module::studyActivated()
+{
+  // StudyChangedReq: request class for internal studyChanged() operation
+  class StudyChangedReq : public PyInterp_Request
+  {
+  public:
+    StudyChangedReq( SUIT_Study*         _study, 
+                    SALOME_PYQT_Module* _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_Module* myObj;
+  };
+
+  // Posting the request
+  PyInterp_Dispatcher::Get()->Exec( new StudyChangedReq( application()->activeStudy(), this ) );
+}
+
+/*!
+ * Processes context popup menu request
+ * - 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.
+ */
+void SALOME_PYQT_Module::contextMenu( const QString& theContext, QPopupMenu* thePopupMenu )
+{
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule )
+    return;
+  
+  QString aContext( theContext ), aObject( "" ), aParent( "" );
+  if ( IsCallOldMethods && PyObject_HasAttrString(myModule , "definePopup") ) { //__CALL_OLD_METHODS__
+    // call definePopup() Python module's function
+    // this is obsolete function, used only for compatibility reasons
+    PyObjWrapper res(PyObject_CallMethod( myModule, 
+                                         "definePopup", 
+                                         "sss",
+                                         aContext.latin1(), 
+                                         aObject.latin1(), 
+                                         aParent.latin1() ) );
+    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;
+      }
+    }
+  }                        //__CALL_OLD_METHODS__
+
+  // first try to create menu via XML parser:
+  // we create popup menus without help of QtxPopupMgr
+  if ( myXmlHandler )
+    myXmlHandler->createPopup( thePopupMenu, aContext, aParent, aObject );
+
+  PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QPopupMenu ) );
+
+  // then call Python module's createPopupMenu() method (for new modules)
+  if ( PyObject_HasAttrString(myModule , "createPopupMenu") ) { 
+    PyObjWrapper res1( PyObject_CallMethod( myModule,
+                                         "createPopupMenu",
+                                         "Os",
+                                         sipPopup.get(),
+                                         aContext.latin1() ) );
+    if( !res1 ) {
+      PyErr_Print();
+    }
+  }
+
+  if ( IsCallOldMethods && PyObject_HasAttrString(myModule , "customPopup") ) { //__CALL_OLD_METHODS__
+    // call customPopup() Python module's function
+    // this is obsolete function, used only for compatibility reasons
+    PyObjWrapper res2( PyObject_CallMethod( myModule,
+                                           "customPopup",
+                                           "Osss",
+                                           sipPopup.get(),
+                                           aContext.latin1(), 
+                                           aObject.latin1(), 
+                                           aParent.latin1() ) );
+    if( !res2 ) {
+      PyErr_Print();
+    }
+  }                        //__CALL_OLD_METHODS__
+}
+
+/*!
+ * Processes GUI event
+ * - calls Python module's OnGUIEvent() method
+ */ 
+void SALOME_PYQT_Module::guiEvent( const int theId )
+{
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myModule )
+    return;
+  
+  if ( PyObject_HasAttrString(myModule , "OnGUIEvent") ) { 
+    PyObjWrapper res( PyObject_CallMethod( myModule, "OnGUIEvent", "i", theId ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+/*!
+ *  Initialises python subinterpreter (one per study)
+ */
+void SALOME_PYQT_Module::initInterp( int theStudyId )
+{
+  // check study Id
+  if ( !theStudyId ) {
+    // Error! Study Id must not be 0!
+    myInterp = NULL;
+    return;
+  }
+  // try to find the subinterpreter
+  if( myInterpMap.find( theStudyId ) != myInterpMap.end() ) {
+    // found!
+    myInterp = myInterpMap[ theStudyId ];
+    return;
+  }
+  // not found - create a new one!
+  ///////////////////////////////////////////////////////////////////
+  // Attention: the creation of Python interpretor must be protected 
+  // by a C++ Lock because of C threads
+  ///////////////////////////////////////////////////////////////////
+  myInterp = new SALOME_PYQT_PyInterp();
+  myInterp->initialize();
+  myInterpMap[ theStudyId ] = myInterp;
+   
+  // 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
+  PyObjWrapper aRes( PyObject_CallMethod( aMod, "salome_init", "" ) );
+  if( !aRes ) {
+    // Error!
+    PyErr_Print();
+    return;
+  }
+}
+
+/*!
+ *  Imports Python GUI module and remember the reference to the module
+ *  !!! initInterp() should be called first!!!
+ */
+void SALOME_PYQT_Module::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 = QString( name("") ) + "GUI";
+  myModule = PyImport_ImportModule( (char*)( aMod.latin1() ) );
+  if( !myModule ) {
+    // Error!
+    PyErr_Print();
+    return;
+  }
+}
+
+/*!
+ *  Calls <module>.setWorkSpace() method with PyQt QWidget object to use with
+ *  interpreter.
+ *  !!! initInterp() and importModule() should be called first!!!
+ */
+void SALOME_PYQT_Module::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 ) { //__CALL_OLD_METHODS__
+    // ... 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();
+    }
+    PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget ) );
+    // ... and finally call Python module's setWorkspace() method (obsolete)
+    if ( PyObject_HasAttrString(myModule , "setWorkSpace") ) { 
+      PyObjWrapper res( PyObject_CallMethod( myModule, "setWorkSpace", "O", pyws.get() ) );
+      if( !res ) {
+        PyErr_Print();
+      }
+    }
+  }                         //__CALL_OLD_METHODS__
+}
+
+/*!
+ * Adds an action into private action list [internal usage]
+ */
+void SALOME_PYQT_Module::addAction( const PyQtGUIAction type, QAction* action )
+{
+  switch ( type ) {
+  case PYQT_ACTION_MENU:
+    myMenuActionList.append( action );
+    break;
+  case PYQT_ACTION_TOOLBAL:
+    myToolbarActionList.append( action );
+    break;
+  case PYQT_ACTION_POPUP:
+    myPopupActionList.append( action );
+    break;
+  }
+}
+
+
+/*!
+ * The next methods just call the parent implementation.
+ * This is done to open protected methods from CAM_Module class.
+*/
+int SALOME_PYQT_Module::createTool( const QString& name )
+{
+  return SalomeApp_Module::createTool( name );
+}
+int SALOME_PYQT_Module::createTool( const int id, const int tBar, const int idx )
+{
+  return SalomeApp_Module::createTool( id, tBar, idx );
+}
+int SALOME_PYQT_Module::createTool( const int id, const QString& tBar, const int idx )
+{
+  return SalomeApp_Module::createTool( id, tBar, idx );
+}
+int SALOME_PYQT_Module::createTool( QAction* a, const int tBar, const int id, const int idx )
+{
+  return SalomeApp_Module::createTool( a, tBar, id, idx );
+}
+int SALOME_PYQT_Module::createTool( QAction* a, const QString& tBar, const int id, const int idx )
+{
+  return SalomeApp_Module::createTool( a, tBar, id, idx );
+}
+int SALOME_PYQT_Module::createMenu( const QString& subMenu, const int menu, const int id, const int group, const int idx )
+{
+  return SalomeApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+int SALOME_PYQT_Module::createMenu( const QString& subMenu, const QString& menu, const int id, const int group, const int idx )
+{
+  return SalomeApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+int SALOME_PYQT_Module::createMenu( const int id, const int menu, const int group, const int idx )
+{
+  return SalomeApp_Module::createMenu( id, menu, group, idx );
+}
+int SALOME_PYQT_Module::createMenu( const int id, const QString& menu, const int group, const int idx )
+{
+  return SalomeApp_Module::createMenu( id, menu, group, idx );
+}
+int SALOME_PYQT_Module::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
+{
+  return SalomeApp_Module::createMenu( a, menu, id, group, idx );
+}
+int SALOME_PYQT_Module::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
+{
+  return SalomeApp_Module::createMenu( a, menu, id, group, idx );
+}
+QAction* SALOME_PYQT_Module::createSeparator()
+{
+  return SalomeApp_Module::separator();
+}
+QAction* SALOME_PYQT_Module::action( const int id ) const
+{
+  QAction* a = SalomeApp_Module::action( id );
+  if ( !a ) // try own action map for menu items
+    a = SalomeApp_Module::action( id + PYQT_ACTION_MENU );
+  if ( !a ) // try own action map for toolbar items
+    a = SalomeApp_Module::action( id + PYQT_ACTION_TOOLBAL );
+  if ( !a ) // try own action map for popup items
+    a = SalomeApp_Module::action( id + PYQT_ACTION_POPUP );
+  return a;
+}
+int SALOME_PYQT_Module::actionId( const QAction* a ) const
+{
+  int id = SalomeApp_Module::actionId( a );
+  if ( myMenuActionList.contains( a ) )    // check own action map for menu items
+    id -= PYQT_ACTION_MENU;
+  if ( myToolbarActionList.contains( a ) ) // check own action map for toolbar items
+    id -= PYQT_ACTION_TOOLBAL;
+  if ( myPopupActionList.contains( a ) )   // check own action map for popup items
+    id -= PYQT_ACTION_POPUP;
+  return id;
+}
+QAction* SALOME_PYQT_Module::createAction( const int id, const QString& text, const QString& icon, 
+                                          const QString& menu, const QString& tip, const int key,
+                                          const bool toggle )
+{
+  QIconSet anIcon;
+  if ( !icon.isEmpty() ) {
+    QPixmap pixmap  = getApp()->resourceMgr()->loadPixmap( name(""), tr( icon ) );
+    if ( !pixmap.isNull() )
+      anIcon = QIconSet( pixmap );
+  }
+  return SalomeApp_Module::createAction( id, text, anIcon, menu, tip, key, getApp()->desktop(), toggle, this, SLOT( onGUIEvent() ) );
+}
+
+
+//=============================================================================
+// SALOME_PYQT_XmlHandler class implementation
+//=============================================================================
+
+// gets an tag name for the dom element [ static ]
+// returns an empty string if the element does not have tag name
+static QString tagName( const QDomElement& element ) {
+ return element.tagName().stripWhiteSpace();
+}
+
+// gets an attribute by it's name for the dom element [ static ]
+// returns an empty string if the element does not have such attribute
+static QString attribute( const QDomElement& element, const QString& attName ) {
+  return element.attribute( attName ).stripWhiteSpace();
+}
+
+// checks the given value for the boolean value [ static ]
+// returns TRUE if string is "true", "yes" or "1"
+static bool checkBool( const QString& value ) {
+  return ( value == "true" || value == "yes" || value == "1" );
+}
+
+// checks the given value for the integer value [ static ]
+// returns -1 if item is empty or presents and invalid number
+static int checkInt( const QString& value ) 
+{
+  return value.isEmpty() ? -1 : value.toInt();
+}
+
+/*!
+ * Constructor
+ */
+SALOME_PYQT_XmlHandler::SALOME_PYQT_XmlHandler( SALOME_PYQT_Module* module, const QString& fileName ) 
+     : myModule( module )
+{
+  QFile aFile( fileName );
+  if ( !aFile.open( IO_ReadOnly ) )
+    return;
+  if ( !myDoc.setContent( &aFile ) ) {
+      aFile.close();
+      return;
+  }
+  aFile.close();
+}
+
+/*!
+  Called by SALOME_PYQT_Module::initialize() in order to create actions 
+  (menus, toolbars, popup menus)
+ */
+void SALOME_PYQT_XmlHandler::createActions()
+{
+  // get document element
+  QDomElement aDocElem = myDoc.documentElement();
+
+  // get 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 );
+  }
+}
+
+/*!
+ *  Creates popup menu
+ */
+void SALOME_PYQT_XmlHandler::createPopup( QPopupMenu*    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"   );
+      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;
+      }
+    }
+  }
+}
+
+/*!
+  Create main menu with child actions
+ */
+void SALOME_PYQT_XmlHandler::createMenu( QDomNode& parentNode, const int parentMenuId )
+{
+  if ( !myModule )
+    return;
+  
+  if ( 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" ) );
+    if ( !plabel.isEmpty() ) {
+      // create menu
+      int menuId = myModule->createMenu( plabel,         // label
+                                        parentMenuId,   // parent menu ID, should be -1 for main menu
+                                        pid,            // ID
+                                        80,             // group ID
+                                        ppos );         // position
+      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" ) );
+           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" ) );
+           ////QString execute = attribute( elem, "execute-action" );               // not used
+
+           // -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 && !myModule->action( SALOME_PYQT_Module::PYQT_ACTION_MENU + id ) ) {
+             // little trick to have several actions with same ID for menus and toolbars
+             id = SALOME_PYQT_Module::PYQT_ACTION_MENU + id;
+             // 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->addAction( SALOME_PYQT_Module::PYQT_ACTION_MENU, action );
+             myModule->createMenu( action, menuId, -1, 80, pos );
+           }
+         }
+         else if ( aTagName == "submenu" ) {
+           // create sub-menu
+           createMenu( node, menuId );
+         }
+         else if ( aTagName == "separator" ) {
+           // create menu separator
+           int     pos     = checkInt( attribute( elem, "pos-id" ) );
+           QAction* action = myModule->createSeparator();
+           myModule->createMenu( action, menuId, -1, 80, pos );
+         }
+       }
+       node = node.nextSibling();
+      }
+    }
+  }
+}
+
+/*!
+  Create a toolbar with child actions
+ */
+void SALOME_PYQT_XmlHandler::createToolBar( QDomNode& parentNode )
+{
+  if ( !myModule )
+    return;
+  
+  if ( 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" ) );
+           ////QString execute = attribute( elem, "execute-action" );               // not used
+
+           // -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 && !myModule->action( SALOME_PYQT_Module::PYQT_ACTION_TOOLBAL + id ) ) {
+             // little trick to have several actions with same ID for menus and toolbars
+             id = SALOME_PYQT_Module::PYQT_ACTION_TOOLBAL + id;
+             // 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->addAction( SALOME_PYQT_Module::PYQT_ACTION_TOOLBAL, action );
+             myModule->createTool( action, tbId, -1, pos );
+           }
+         }
+         else if ( aTagName == "separatorTB" ) {
+           // create toolbar separator
+           int     pos     = checkInt( attribute( elem, "pos-id" ) );
+           QAction* action = myModule->createSeparator();
+           myModule->createTool( action, tbId, -1, pos );
+         }
+       }
+       node = node.nextSibling();
+      }
+    }
+  }      
+}
+
+void SALOME_PYQT_XmlHandler::insertPopupItems( QDomNode& parentNode, QPopupMenu* menu )
+{
+  if ( !myModule )
+    return;
+  
+  if ( 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 );
+      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" );                   // not used
+       QString accel   = attribute( elem, "accel-id" );
+       /////bool    toggle  = checkBool( attribute( elem, "toggle-id" ) );       // not used
+       /////QString execute = attribute( elem, "execute-action" );               // not used
+
+       QIconSet anIcon;
+       if ( !icon.isEmpty() ) {
+          QPixmap pixmap  = myModule->getApp()->resourceMgr()->loadPixmap( myModule->name(""), icon );
+         if ( !pixmap.isNull() )
+           anIcon = QIconSet( pixmap );
+        }
+       
+       // -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 ) {
+         menu->insertItem( anIcon, label, myModule, SLOT( onGUIEvent(int) ), QKeySequence( accel ), id, pos );
+       }
+      }
+      else if ( aTagName == "submenu" ) {
+       // create sub-menu
+       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" );
+
+       QIconSet anIcon;
+       if ( !icon.isEmpty() ) {
+         QPixmap pixmap  = myModule->getApp()->resourceMgr()->loadPixmap( myModule->name(""), icon );
+         if ( !pixmap.isNull() )
+           anIcon = QIconSet( pixmap );
+        }
+
+       QPopupMenu* newPopup = new QPopupMenu( menu, label );
+       menu->insertItem( anIcon, label, newPopup, id, pos );
+       insertPopupItems( node, newPopup );
+      }
+      else if ( aTagName == "separator" ) {
+       // create menu separator
+       int     pos     = checkInt( attribute( elem, "pos-id" ) );
+       menu->insertSeparator( pos );
+      }
+    }
+    node = node.nextSibling();
+  }
+}
diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx
new file mode 100644 (file)
index 0000000..1956ec3
--- /dev/null
@@ -0,0 +1,83 @@
+//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : SALOME_PYQT_PyInterp.cxx
+//  Author : Christian CAREMOLI, Paul RASCLE, EDF
+//  Module : SALOME
+//  $Header$
+
+#include "SALOME_PYQT_PyInterp.h" // this include must be first (see PyInterp_base.h)!
+#include "utilities.h"
+#include "Container_init_python.hxx"
+
+using namespace std;
+
+
+/*!
+ * 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_base()
+{
+}
+
+SALOME_PYQT_PyInterp::~SALOME_PYQT_PyInterp()
+{
+}
+
+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
+  */
+  SCRUTE(KERNEL_PYTHON::_gtstate);
+  _tstate = KERNEL_PYTHON::_gtstate;
+  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/SalomePyQt/SalomePyQt.cxx b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx
new file mode 100644 (file)
index 0000000..d7b887f
--- /dev/null
@@ -0,0 +1,1255 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+//=============================================================================
+// File      : SalomePyQt.cxx
+// Created   : 25/04/05
+// Author    : Vadim SANDLER
+// Project   : SALOME
+// Copyright : 2003-2005 CEA/DEN, EDF R&D
+// $Header   : $
+//=============================================================================
+
+#include "SALOME_PYQT_Module.h" // this include must be first!!!
+#include "SalomePyQt.h"
+
+#include <qapplication.h>
+#include <qmenubar.h>
+#include <qwidget.h>
+#include <qpopupmenu.h>
+#include <qimage.h>
+#include <qstringlist.h>
+
+#include "SALOME_Event.hxx"
+
+#include "SUIT_Session.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_Tools.h"
+#include "STD_MDIDesktop.h"
+#include "SalomeApp_Application.h"
+#include "SalomeApp_Study.h"
+#include "LightApp_SelectionMgr.h"
+#include "OB_Browser.h"
+#include "QtxAction.h"
+
+using namespace std;
+
+//====================================================================================
+// static functions
+//====================================================================================
+/*!
+  getApplication()
+  Returns active application object [ static ]
+*/
+static SalomeApp_Application* getApplication() {
+  if ( SUIT_Session::session() )
+    return dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+  return NULL;
+}
+
+/*!
+  getActiveStudy()
+  Gets active study or 0 if there is no study opened [ static ]
+*/
+static SalomeApp_Study* getActiveStudy()
+{
+  if ( getApplication() )
+    return dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
+  return 0;
+}
+
+//====================================================================================
+// SALOME_Selection class.
+//====================================================================================
+static QMap<SalomeApp_Application*, SALOME_Selection*> SelMap;
+
+/*!
+  SALOME_Selection::GetSelection
+  Creates or finds the selection object (one per study).
+*/
+SALOME_Selection* SALOME_Selection::GetSelection( SalomeApp_Application* app )
+{
+  SALOME_Selection* sel = 0;
+  if ( app && SelMap.find( app ) != SelMap.end() )
+    sel = SelMap[ app ];
+  else 
+    sel = SelMap[ app ] = new SALOME_Selection( app );
+  return sel;
+}
+
+/*!
+  SALOME_Selection::SALOME_Selection
+  Selection constructor.
+*/
+SALOME_Selection::SALOME_Selection( QObject* p ) : QObject( p ), mySelMgr( 0 )
+{
+  SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( p );
+  if ( app ) {
+    mySelMgr = app->selectionMgr();
+    connect( mySelMgr, SIGNAL( selectionChanged() ), this, SIGNAL( currentSelectionChanged() ) );
+    connect( mySelMgr, SIGNAL( destroyed() ),        this, SLOT  ( onSelMgrDestroyed() ) );
+  }
+}
+/*!
+  SALOME_Selection::~SALOME_Selection
+  Selection destructor. Removes selection object from the map.
+*/
+SALOME_Selection::~SALOME_Selection()
+{
+  SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( parent() );
+  if ( app && SelMap.find( app ) != SelMap.end() )
+    SelMap.remove( app );
+}
+
+/*!
+  SALOME_Selection::onSelMgrDestroyed
+  Watches for the selection manager destroying when study is closed.
+*/
+void SALOME_Selection::onSelMgrDestroyed()
+{
+  mySelMgr = 0;
+}
+
+/*!
+  SALOME_Selection::Clear
+  Clears the selection.
+*/
+void SALOME_Selection::Clear()
+{
+  class TEvent: public SALOME_Event {
+    LightApp_SelectionMgr* mySelMgr;
+  public:
+    TEvent( LightApp_SelectionMgr* selMgr ) 
+      : mySelMgr( selMgr ) {}
+    virtual void Execute() {
+      if ( mySelMgr )
+        mySelMgr->clearSelected();
+    }
+  };
+  ProcessVoidEvent( new TEvent( mySelMgr ) );
+}
+
+/*!
+  SALOME_Selection::ClearIObjects
+  Clears the selection.
+*/
+void SALOME_Selection::ClearIObjects()
+{
+  Clear();
+}
+
+/*!
+  SALOME_Selection::ClearFilters
+  Removes all selection filters.
+*/
+void SALOME_Selection::ClearFilters()
+{
+  class TEvent: public SALOME_Event {
+    LightApp_SelectionMgr* mySelMgr;
+  public:
+    TEvent( LightApp_SelectionMgr* selMgr ) 
+      : mySelMgr( selMgr ) {}
+    virtual void Execute() {
+      if ( mySelMgr )
+        mySelMgr->clearFilters();
+    }
+  };
+  ProcessVoidEvent( new TEvent( mySelMgr ) );
+}
+
+//====================================================================================
+// SalomePyQt class
+//====================================================================================
+
+/*!
+  SalomePyQt::getDesktop
+  Gets desktop. Returns 0 in error.
+*/
+class TGetDesktopEvent: public SALOME_Event {
+public:
+  typedef QWidget* TResult;
+  TResult myResult;
+  TGetDesktopEvent() : myResult( 0 ) {}
+  virtual void Execute() {
+    if ( getApplication() )
+      myResult = (QWidget*)( getApplication()->desktop() );
+  }
+};
+QWidget* SalomePyQt::getDesktop()
+{
+  return ProcessEvent( new TGetDesktopEvent() );
+}
+
+/*!
+  SalomePyQt::getMainFrame
+  Gets workspace widget. Returns 0 in error.
+*/
+class TGetMainFrameEvent: public SALOME_Event {
+public:
+  typedef QWidget* TResult;
+  TResult myResult;
+  TGetMainFrameEvent() : myResult( 0 ) {}
+  virtual void Execute() {
+    if ( getApplication() ) {
+      SUIT_Desktop* aDesktop = getApplication()->desktop();
+      myResult = (QWidget*)( aDesktop->centralWidget() );
+    }
+  }
+};
+QWidget* SalomePyQt::getMainFrame()
+{
+  return ProcessEvent( new TGetMainFrameEvent() );
+}
+
+/*!
+  SalomePyQt::getMainMenuBar
+  Gets main menu. Returns 0 in error.
+*/
+class TGetMainMenuBarEvent: public SALOME_Event {
+public:
+  typedef QMenuBar* TResult;
+  TResult myResult;
+  TGetMainMenuBarEvent() : myResult( 0 ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      myResult = anApp->desktop()->menuBar();
+    }
+  }
+};
+QMenuBar* SalomePyQt::getMainMenuBar() 
+{
+  return ProcessEvent( new TGetMainMenuBarEvent() );
+}
+
+/*!
+  SalomePyQt::getPopupMenu
+  Gets an main menu's child popup menu by its id
+*/
+class TGetPopupMenuEvent: public SALOME_Event {
+public:
+  typedef QPopupMenu* TResult;
+  TResult  myResult;
+  MenuName myMenuName;
+  TGetPopupMenuEvent( const MenuName menu ) : myResult( 0 ), myMenuName( menu ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      QMenuBar* menuBar = anApp->desktop()->menuBar();
+      if ( menuBar ) {
+        QString menu;
+        switch( myMenuName) {
+        case File:
+          menu = QObject::tr( "MEN_DESK_FILE" );        break;
+        case View:
+          menu = QObject::tr( "MEN_DESK_VIEW" );        break;
+        case Edit:
+          menu = QObject::tr( "MEN_DESK_EDIT" );        break;
+        case Preferences:
+          menu = QObject::tr( "MEN_DESK_PREFERENCES" ); break;
+        case Tools:
+          menu = QObject::tr( "MEN_DESK_TOOLS" );       break;
+        case Window:
+          menu = QObject::tr( "MEN_DESK_WINDOW" );      break;
+        case Help:
+          menu = QObject::tr( "MEN_DESK_HELP" );        break;
+        }
+        for ( int i = 0; i < menuBar->count() && !myResult; i++ ) {
+          QMenuItem* item = menuBar->findItem( menuBar->idAt( i ) );
+         if ( item && item->text() == menu && item->popup() )
+            myResult = item->popup();
+        }
+      }
+    }
+  }
+};
+QPopupMenu* SalomePyQt::getPopupMenu( const MenuName menu )
+{
+  return ProcessEvent( new TGetPopupMenuEvent( menu ) );
+}
+
+/*!
+  SalomePyQt::getStudyId
+  Returns active study's ID or 0 if there is no active study.
+*/
+class TGetStudyIdEvent: public SALOME_Event {
+public:
+  typedef int TResult;
+  TResult myResult;
+  TGetStudyIdEvent() : myResult( 0 ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
+      myResult = aStudy->studyDS()->StudyId();
+    }
+  }
+};
+int SalomePyQt::getStudyId()
+{
+  return ProcessEvent( new TGetStudyIdEvent() );
+}
+
+/*!
+  SalomePyQt::getSelection
+  Creates a Selection object (to provide a compatibility with previous SALOME GUI).
+*/
+class TGetSelectionEvent: public SALOME_Event {
+public:
+  typedef SALOME_Selection* TResult;
+  TResult myResult;
+  TGetSelectionEvent() : myResult( 0 ) {}
+  virtual void Execute() {
+    myResult = SALOME_Selection::GetSelection( getApplication() );
+  }
+};
+SALOME_Selection* SalomePyQt::getSelection()
+{
+  return ProcessEvent( new TGetSelectionEvent() );
+}
+
+/*!
+  SalomePyQt::putInfo
+  Puts an information message to the desktop's status bar
+  (with optional delay parameter given in seconds)
+*/
+class TPutInfoEvent: public SALOME_Event {
+  QString myMsg;
+  int     mySecs;
+public:
+  TPutInfoEvent( const QString& msg, const int sec = 0 ) : myMsg( msg ), mySecs( sec ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      anApp->putInfo( myMsg, mySecs * 1000 );
+    }
+  }
+};
+void SalomePyQt::putInfo( const QString& msg, const int sec )
+{
+  ProcessVoidEvent( new TPutInfoEvent( msg, sec ) );
+}
+
+/*!
+  SalomePyQt::getActiveComponent
+  Returns an active component name or empty string if there is no active component
+*/
+class TGetActiveComponentEvent: public SALOME_Event {
+public:
+  typedef QString TResult;
+  TResult myResult;
+  TGetActiveComponentEvent() {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      if ( CAM_Module* mod = anApp->activeModule() ) {
+        myResult = mod->name("");
+      }
+    }
+  }
+};
+const QString SalomePyQt::getActiveComponent()
+{
+  return ProcessEvent( new TGetActiveComponentEvent() );
+}
+
+/*!
+  SalomePyQt::updateObjBrowser
+  Updates an Object Browser of a given study.
+  If <studyId> <= 0 the active study's object browser is updated.
+  <updateSelection> parameter is obsolete parameter and currently not used. To be removed lately.
+*/
+void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection )
+{  
+  class TEvent: public SALOME_Event {
+    int  myStudyId;
+    bool myUpdateSelection;
+  public:
+    TEvent( const int studyId, bool updateSelection ) 
+      : myStudyId( studyId ), myUpdateSelection( updateSelection ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        if ( getActiveStudy() && myStudyId <= 0 )
+          myStudyId = getActiveStudy()->id();
+       if ( myStudyId > 0 ) {
+          QPtrList<SUIT_Application> apps = SUIT_Session::session()->applications();
+          QPtrListIterator<SUIT_Application> it( apps );
+         for( ; it.current(); ++it ) {
+            SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( it.current() );
+            if ( anApp && anApp->activeStudy() && anApp->activeStudy()->id() == myStudyId )
+             anApp->updateObjectBrowser();
+          }
+        }
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( studyId, updateSelection ) );
+}
+
+const char* DEFAULT_SECTION = "SalomePyQt";
+
+/*!
+  SalomePyQt::addStringSetting
+  Adds a string setting to the application preferences
+  <autoValue> parameter is obsolete parameter and currently not used. To be removed lately.
+  This function is obsolete. Use addSetting() instead.
+*/
+void SalomePyQt::addStringSetting( const QString& name, const QString& value, bool autoValue )
+{
+  class TEvent: public SALOME_Event {
+    QString myName;
+    QString myValue;
+    bool    myAutoValue;
+  public:
+    TEvent( const QString& name, const QString& value, bool autoValue ) 
+      : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       QStringList sl = QStringList::split( ":", myName );
+       QString _sec = sl.count() > 1 ? sl[ 0 ].stripWhiteSpace() : QString( DEFAULT_SECTION );
+       QString _nam = sl.count() > 1 ? sl[ 1 ].stripWhiteSpace() : sl.count() > 0 ? sl[ 0 ].stripWhiteSpace() : QString( "" );
+       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+          resMgr->setValue( _sec, _nam, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( name, value, autoValue ) );
+}
+
+/*!
+  SalomePyQt::addIntSetting
+  Adds an integer setting to the application preferences
+  <autoValue> parameter is obsolete parameter and currently not used. To be removed lately.
+  This function is obsolete. Use addSetting() instead.
+*/
+void SalomePyQt::addIntSetting( const QString& name, const int value, bool autoValue)
+{
+  class TEvent: public SALOME_Event {
+    QString myName;
+    int     myValue;
+    bool    myAutoValue;
+  public:
+    TEvent( const QString& name, const int value, bool autoValue ) 
+      : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       QStringList sl = QStringList::split( ":", myName );
+       QString _sec = sl.count() > 1 ? sl[ 0 ].stripWhiteSpace() : QString( DEFAULT_SECTION );
+       QString _nam = sl.count() > 1 ? sl[ 1 ].stripWhiteSpace() : sl.count() > 0 ? sl[ 0 ].stripWhiteSpace() : QString( "" );
+       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+          resMgr->setValue( _sec, _nam, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( name, value, autoValue ) );
+}
+
+/*!
+  SalomePyQt::addDoubleSetting
+  Adds an double setting to the application preferences
+  <autoValue> parameter is obsolete parameter and currently not used. To be removed lately.
+  This function is obsolete. Use addSetting() instead.
+*/
+void SalomePyQt::addDoubleSetting( const QString& name, const double value, bool autoValue )
+{
+  class TEvent: public SALOME_Event {
+    QString myName;
+    double  myValue;
+    bool    myAutoValue;
+  public:
+    TEvent( const QString& name, const double value, bool autoValue ) 
+      : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       QStringList sl = QStringList::split( ":", myName );
+       QString _sec = sl.count() > 1 ? sl[ 0 ].stripWhiteSpace() : QString( DEFAULT_SECTION );
+       QString _nam = sl.count() > 1 ? sl[ 1 ].stripWhiteSpace() : sl.count() > 0 ? sl[ 0 ].stripWhiteSpace() : QString( "" );
+       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+          resMgr->setValue( _sec, _nam, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( name, value, autoValue ) );
+}
+
+/*!
+  SalomePyQt::removeSettings
+  Removes a setting from the application preferences
+  This function is obsolete. Use removeSetting() instead.
+*/
+void SalomePyQt::removeSettings( const QString& name )
+{
+  class TEvent: public SALOME_Event {
+    QString myName;
+  public:
+    TEvent( const QString& name ) : myName( name ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       QStringList sl = QStringList::split( ":", myName );
+       QString _sec = sl.count() > 1 ? sl[ 0 ].stripWhiteSpace() : QString( DEFAULT_SECTION );
+       QString _nam = sl.count() > 1 ? sl[ 1 ].stripWhiteSpace() : sl.count() > 0 ? sl[ 0 ].stripWhiteSpace() : QString( "" );
+       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+          resMgr->remove( _sec, _nam );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( name ) );
+}
+
+/*!
+  SalomePyQt::getSetting
+  Gets a setting value (as string)
+  This function is obsolete. Use stringSetting(), integerSetting(), 
+  boolSetting(), stringSetting() or colorSetting() instead.
+*/
+class TGetSettingEvent: public SALOME_Event {
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString myName;
+  TGetSettingEvent( const QString& name ) : myName( name ) {}
+  virtual void Execute() {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      QStringList sl = QStringList::split( ":", myName );
+      QString _sec = sl.count() > 1 ? sl[ 0 ].stripWhiteSpace() : QString( DEFAULT_SECTION );
+      QString _nam = sl.count() > 1 ? sl[ 1 ].stripWhiteSpace() : sl.count() > 0 ? sl[ 0 ].stripWhiteSpace() : QString( "" );
+      myResult = ( !_sec.isEmpty() && !_nam.isEmpty() ) ? resMgr->stringValue( _sec, _nam, "" ) : QString( "" );
+    }
+  }
+};
+QString SalomePyQt::getSetting( const QString& name )
+{
+  return ProcessEvent( new TGetSettingEvent( name ) );
+}
+
+/*!
+  SalomePyQt::addSetting
+  Adds a double setting to the application preferences
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const double value )
+{
+  class TEvent: public SALOME_Event {
+    QString mySection;
+    QString myName;
+    double  myValue;
+  public:
+    TEvent( const QString& section, const QString& name, double value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->setValue( mySection, myName, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name, value ) );
+}
+
+/*!
+  SalomePyQt::addSetting
+  Adds an integer setting to the application preferences
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const int value )
+{
+  class TEvent: public SALOME_Event {
+    QString mySection;
+    QString myName;
+    int     myValue;
+  public:
+    TEvent( const QString& section, const QString& name, int value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->setValue( mySection, myName, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name, value ) );
+}
+
+/*!
+  SalomePyQt::addSetting
+  Adds a string setting to the application preferences
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const QString& value )
+{
+  class TEvent: public SALOME_Event {
+    QString mySection;
+    QString myName;
+    QString myValue;
+  public:
+    TEvent( const QString& section, const QString& name, const QString& value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->setValue( mySection, myName, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name, value ) );
+}
+
+/*!
+  SalomePyQt::addSetting
+  Adds a color setting to the application preferences
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const QColor& value )
+{
+  class TEvent: public SALOME_Event {
+    QString mySection;
+    QString myName;
+    QColor  myValue;
+  public:
+    TEvent( const QString& section, const QString& name, const QColor& value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->setValue( mySection, myName, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name, value ) );
+}
+
+/*!
+  SalomePyQt::integerSetting
+  Gets an integer setting from the application preferences
+*/
+class TGetIntSettingEvent: public SALOME_Event {
+public:
+  typedef int TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetIntSettingEvent( const QString& section, const QString& name, const int def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->integerValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+int SalomePyQt::integerSetting( const QString& section, const QString& name, const int def )
+{
+  return ProcessEvent( new TGetIntSettingEvent( section, name, def ) );
+}
+
+/*!
+  SalomePyQt::doubleSetting
+  Gets a double setting from the application preferences
+*/
+class TGetDblSettingEvent: public SALOME_Event {
+public:
+  typedef double TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetDblSettingEvent( const QString& section, const QString& name, const double def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->doubleValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+double SalomePyQt::doubleSetting( const QString& section, const QString& name, const int def )
+{
+  return ProcessEvent( new TGetDblSettingEvent( section, name, def ) );
+}
+
+/*!
+  SalomePyQt::boolSetting
+  Gets a boolean setting from the application preferences
+*/
+class TGetBoolSettingEvent: public SALOME_Event {
+public:
+  typedef bool TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetBoolSettingEvent( const QString& section, const QString& name, const bool def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->booleanValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+bool SalomePyQt::boolSetting( const QString& section, const QString& name, const bool def )
+{
+  return ProcessEvent( new TGetBoolSettingEvent( section, name, def ) );
+}
+
+/*!
+  SalomePyQt::stringSetting
+  Gets a string setting from the application preferences
+*/
+class TGetStrSettingEvent: public SALOME_Event {
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetStrSettingEvent( const QString& section, const QString& name, const QString& def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->stringValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+QString SalomePyQt::stringSetting( const QString& section, const QString& name, const QString& def )
+{
+  return ProcessEvent( new TGetStrSettingEvent( section, name, def ) );
+}
+
+/*!
+  SalomePyQt::colorSetting
+  Gets a color setting from the application preferences
+*/
+class TGetColorSettingEvent: public SALOME_Event {
+public:
+  typedef QColor TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetColorSettingEvent( const QString& section, const QString& name, const QColor& def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->colorValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+QColor SalomePyQt::colorSetting ( const QString& section, const QString& name, const QColor& def )
+{
+  return ProcessEvent( new TGetColorSettingEvent( section, name, def ) );
+}
+
+/*!
+  SalomePyQt::removeSetting
+  Removes a setting from the application preferences
+*/
+void SalomePyQt::removeSetting( const QString& section, const QString& name )
+{
+  class TEvent: public SALOME_Event {
+    QString mySection;
+    QString myName;
+  public:
+    TEvent( const QString& section, const QString& name ) : mySection( section ), myName( name ) {}
+    virtual void Execute() {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+       if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->remove( mySection, myName );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name ) );
+}
+
+/*!
+  SalomePyQt::getFileName
+  Displays 'Open/Save file' dialog box and returns a user's choice (file name)
+*/
+class TGetFileNameEvent: public SALOME_Event {
+public:
+  typedef QString TResult;
+  TResult     myResult;
+  QWidget*    myParent;
+  QString     myInitial;
+  QStringList myFilters;
+  QString     myCaption;
+  bool        myOpen;
+  TGetFileNameEvent( QWidget*           parent, 
+                    const QString&     initial, 
+                    const QStringList& filters, 
+                    const QString&     caption,
+                    bool               open ) 
+    : myParent ( parent ), 
+      myInitial( initial ), 
+      myFilters( filters ), 
+      myCaption( caption ), 
+      myOpen ( open ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      myResult = anApp->getFileName( myOpen, myInitial, myFilters.join(";;"), myCaption, myParent );
+    }
+  }
+};
+QString SalomePyQt::getFileName( QWidget*           parent, 
+                                const QString&     initial, 
+                                const QStringList& filters, 
+                                const QString&     caption,
+                                bool               open )
+{
+  return ProcessEvent( new TGetFileNameEvent( parent, initial, filters, caption, open ) );
+}
+
+/*!
+  SalomePyQt::getOpenFileNames
+  Displays 'Open files' dialog box and returns a user's choice (a list of file names)
+*/
+class TGetOpenFileNamesEvent: public SALOME_Event {
+public:
+  typedef QStringList TResult;
+  TResult     myResult;
+  QWidget*    myParent;
+  QString     myInitial;
+  QStringList myFilters;
+  QString     myCaption;
+  TGetOpenFileNamesEvent( QWidget*           parent, 
+                         const QString&     initial, 
+                         const QStringList& filters, 
+                         const QString&     caption ) 
+    : myParent ( parent ), 
+      myInitial( initial ), 
+      myFilters( filters ), 
+      myCaption( caption ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      myResult = anApp->getOpenFileNames( myInitial, myFilters.join(";;"), myCaption, myParent );
+    }
+  }
+};
+QStringList SalomePyQt::getOpenFileNames( QWidget*           parent, 
+                                         const QString&     initial, 
+                                         const QStringList& filters, 
+                                         const QString&     caption )
+{
+  return ProcessEvent( new TGetOpenFileNamesEvent( parent, initial, filters, caption ) );
+}
+
+/*!
+  SalomePyQt::getExistingDirectory
+  Displays 'Get Directory' dialog box and returns a user's choice (a directory name)
+*/
+class TGetExistingDirectoryEvent: public SALOME_Event {
+public:
+  typedef QString TResult;
+  TResult     myResult;
+  QWidget*    myParent;
+  QString     myInitial;
+  QString     myCaption;
+  TGetExistingDirectoryEvent( QWidget*           parent, 
+                             const QString&     initial, 
+                             const QString&     caption ) 
+    : myParent ( parent ), 
+      myInitial( initial ), 
+      myCaption( caption ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      myResult = anApp->getDirectory( myInitial, myCaption, myParent );
+    }
+  }
+};
+QString SalomePyQt::getExistingDirectory( QWidget*       parent,
+                                         const QString& initial,
+                                         const QString& caption )
+{
+  return ProcessEvent( new TGetExistingDirectoryEvent( parent, initial, caption ) );
+}
+
+/*!
+  SalomePyQt::helpContext
+  Opens external browser to display 'context help' information
+  current implementation does nothing.
+*/
+void SalomePyQt::helpContext( const QString& source, const QString& context ) {
+  class TEvent: public SALOME_Event {
+    QString mySource;
+    QString myContext;
+  public:
+    TEvent( const QString& source, const QString& context ) 
+      : mySource( source ), myContext( context ) {}
+    virtual void Execute() {
+      if ( /*SalomeApp_Application* anApp =*/ getApplication() ) {
+       // VSR: TODO
+        // anApp->helpContext( mySource, myContext );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( source, context ) );
+}
+
+/*!
+  SalomePyQt::dumpView
+  Dumps the contents of the currently active view to the image file 
+  in the given format (JPEG, PNG, BMP are supported)
+*/
+class TDumpViewEvent: public SALOME_Event {
+public:
+  typedef bool TResult;
+  TResult myResult;
+  QString myFileName;
+  TDumpViewEvent( const QString& filename ) 
+    : myResult ( false ), myFileName( filename ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      SUIT_ViewManager* vm = anApp->activeViewManager();
+      if ( vm ) { 
+        SUIT_ViewWindow* vw = vm->getActiveView();
+       if ( vw ) {
+          QImage im = vw->dumpView();
+         if ( !im.isNull() && !myFileName.isEmpty() ) {
+            QString fmt = SUIT_Tools::extension( myFileName ).upper();
+           if ( fmt.isEmpty() ) fmt = QString( "BMP" ); // default format
+           if ( fmt == "JPG" )  fmt = "JPEG";
+           myResult = im.save( myFileName, fmt.latin1() );
+          }
+       }
+      }
+    }
+  }
+};
+bool SalomePyQt::dumpView( const QString& filename )
+{
+  return ProcessEvent( new TDumpViewEvent( filename ) );
+}
+
+/*!
+  SalomePyQt::createTool
+  These methods allow operating with the toolbars:
+  - create a new toolbar or get the existing one (the toolbar name is passed as parameter);
+    this method returns an id of the toolbar;
+  - add action with given id (must be created previously) and optional index to the existing toolbar
+    (toobar is identified either by its id or by its name)
+    these methods return an id of the action.
+  If error occurs, the -1 value is returned.
+*/
+class CrTool
+{
+public:
+  CrTool( const QString& tBar ) 
+    : myCase( 0 ), myTbName( tBar ) {}
+  CrTool( const int id, const int tBar, const int idx ) 
+    : myCase( 1 ), myId( id ), myTbId( tBar ), myIndex( idx ) {}
+  CrTool( const int id, const QString& tBar, const int idx )
+    : myCase( 2 ), myId( id ), myTbName( tBar ), myIndex( idx ) {}
+  CrTool( QtxAction* action, const int tbId, const int id, const int idx )
+    : myCase( 3 ), myAction( action ), myTbId( tbId ), myId( id ), myIndex( idx ) {}
+  CrTool( QtxAction* action, const QString& tBar, const int id, const int idx )
+    : myCase( 4 ), myAction( action ), myTbName( tBar ), myId( id ), myIndex( idx ) {}
+
+  int execute( SALOME_PYQT_Module* module ) const
+  {
+    if ( module ) {
+      switch ( myCase ) {
+      case 0:
+        return module->createTool( myTbName );
+      case 1:
+        return module->createTool( myId, myTbId, myIndex );
+      case 2:
+        return module->createTool( myId, myTbName, myIndex );
+      case 3:
+        return module->createTool( myAction, myTbId, myId, myIndex );
+      case 4:
+        return module->createTool( myAction, myTbName, myId, myIndex );
+      }
+    }
+    return -1;
+  }
+private:
+   int        myCase;
+   QString    myTbName;
+   int        myTbId;
+   QtxAction* myAction;
+   int        myId;
+   int        myIndex;
+};
+class TCreateToolEvent: public SALOME_Event {
+public:
+  typedef int TResult;
+  TResult myResult;
+  const CrTool& myCrTool;
+  TCreateToolEvent( const CrTool& crTool ) 
+    : myResult( -1 ), myCrTool( crTool ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      SALOME_PYQT_Module* module = SALOME_PYQT_Module::getInitModule();
+      if ( !module )
+        module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+      myResult = myCrTool.execute( module );
+    }
+  }
+};
+// create new toolbar or get existing by name 
+int SalomePyQt::createTool( const QString& tBar )
+{
+  return ProcessEvent( new TCreateToolEvent( CrTool( tBar ) ) );
+}
+// add action with id and index to the existing tollbar
+int SalomePyQt::createTool( const int id, const int tBar, const int idx )
+{
+  return ProcessEvent( new TCreateToolEvent( CrTool( id, tBar, idx ) ) );
+}
+// add action with id and index to the existing tollbar
+int SalomePyQt::createTool( const int id, const QString& tBar, const int idx )
+{
+  return ProcessEvent( new TCreateToolEvent( CrTool( id, tBar, idx ) ) );
+}
+// add action with id and index to the existing tollbar
+int SalomePyQt::createTool( QtxAction* a, const int tBar, const int id, const int idx )
+{
+  return ProcessEvent( new TCreateToolEvent( CrTool( a, tBar, id, idx ) ) );
+}
+// add action with id and index to the existing tollbar
+int SalomePyQt::createTool( QtxAction* a, const QString& tBar, const int id, const int idx )
+{
+  return ProcessEvent( new TCreateToolEvent( CrTool( a, tBar, id, idx ) ) );
+}
+
+/*!
+  SalomePyQt::createMenu
+  These methods allow operating with the main menu:
+  - create a new menu or submenu or get the existing one (the parent menu name or id is passed as parameter, 
+    if it is empty or -1, it means that main menu is created, otherwise submenu is created);
+    this method returns an id of the menu/submenu;
+  - add action with given id (must be created previously) and optional index and group number to the existing menu
+    or submenu (menu name or id us passed as parameter)
+    these methods return an id of the action.
+  If error occurs, the -1 value is returned.
+*/
+class CrMenu
+{
+public:
+  CrMenu( const QString& subMenu, const int menu, const int group, const int idx ) 
+    : myCase( 0 ), mySubMenuName( subMenu ), myMenuId( menu ), myGroup( group ), myIndex( idx ) {}
+  CrMenu( const QString& subMenu, const QString& menu, const int group, const int idx ) 
+    : myCase( 1 ), mySubMenuName( subMenu ), myMenuName( menu ), myGroup( group ), myIndex( idx ) {}
+  CrMenu( const int id, const int menu, const int group, const int idx ) 
+    : myCase( 2 ), myId( id ), myMenuId( menu ), myGroup( group ), myIndex( idx ) {}
+  CrMenu( const int id, const QString& menu, const int group, const int idx ) 
+    : myCase( 3 ), myId( id ), myMenuName( menu ), myGroup( group ), myIndex( idx ) {}
+  CrMenu( QtxAction* action, const int menu, const int id, const int group, const int idx ) 
+    : myCase( 4 ), myAction( action ), myMenuId( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
+  CrMenu( QtxAction* action, const QString& menu, const int id, const int group, const int idx ) 
+    : myCase( 5 ), myAction( action ), myMenuName( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
+
+  int execute( SALOME_PYQT_Module* module ) const
+  {
+    if ( module ) {
+      switch ( myCase ) {
+      case 0:
+        return module->createMenu( mySubMenuName, myMenuId, -1, myGroup, myIndex );
+      case 1:
+        return module->createMenu( mySubMenuName, myMenuName, -1, myGroup, myIndex );
+      case 2:
+        return module->createMenu( myId, myMenuId, myGroup, myIndex );
+      case 3:
+        return module->createMenu( myId, myMenuName, myGroup, myIndex );
+      case 4:
+        return module->createMenu( myAction, myMenuId, myId, myGroup, myIndex );
+      case 5:
+        return module->createMenu( myAction, myMenuName, myId, myGroup, myIndex );
+      }
+    }
+    return -1;
+  }
+private:
+   int        myCase;
+   QString    myMenuName;
+   int        myMenuId;
+   QString    mySubMenuName;
+   int        myGroup;
+   QtxAction* myAction;
+   int        myId;
+   int        myIndex;
+};
+class TCreateMenuEvent: public SALOME_Event {
+public:
+  typedef int TResult;
+  TResult myResult;
+  const CrMenu& myCrMenu;
+  TCreateMenuEvent( const CrMenu& crMenu ) 
+    : myResult( -1 ), myCrMenu( crMenu ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      SALOME_PYQT_Module* module = SALOME_PYQT_Module::getInitModule();
+      if ( !module )
+        module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+      myResult = myCrMenu.execute( module );
+    }
+  }
+};
+int SalomePyQt::createMenu( const QString& subMenu, const int menu, const int group, const int idx )
+{
+  return ProcessEvent( new TCreateMenuEvent( CrMenu( subMenu, menu, group, idx ) ) );
+}
+
+int SalomePyQt::createMenu( const QString& subMenu, const QString& menu, const int group, const int idx )
+{
+  return ProcessEvent( new TCreateMenuEvent( CrMenu( subMenu, menu, group, idx ) ) );
+}
+
+int SalomePyQt::createMenu( const int id, const int menu, const int group, const int idx )
+{
+  return ProcessEvent( new TCreateMenuEvent( CrMenu( id, menu, group, idx ) ) );
+}
+
+int SalomePyQt::createMenu( const int id, const QString& menu, const int group, const int idx )
+{
+  return ProcessEvent( new TCreateMenuEvent( CrMenu( id, menu, group, idx ) ) );
+}
+
+int SalomePyQt::createMenu( QtxAction* a, const int menu, const int id, const int group, const int idx )
+{
+  return ProcessEvent( new TCreateMenuEvent( CrMenu( a, menu, id, group, idx ) ) );
+}
+
+int SalomePyQt::createMenu( QtxAction* a, const QString& menu, const int id, const int group, const int idx )
+{
+  return ProcessEvent( new TCreateMenuEvent( CrMenu( a, menu, id, group, idx ) ) );
+}
+
+/*!
+  SalomePyQt::createSeparator
+  Create a separator action which can be then used in the menu or toolbar.
+*/
+class TCreateSepEvent: public SALOME_Event {
+public:
+  typedef QtxAction* TResult;
+  TResult myResult;
+  TCreateSepEvent() 
+    : myResult( 0 ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      SALOME_PYQT_Module* module = SALOME_PYQT_Module::getInitModule();
+      if ( !module )
+        module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+      if ( module )
+        myResult = (QtxAction*)module->createSeparator();
+    }
+  }
+};
+QtxAction* SalomePyQt::createSeparator()
+{
+  return ProcessEvent( new TCreateSepEvent() );
+}
+
+/*!
+  SalomePyQt::createAction
+  Create an action which can be then used in the menu or toolbar:
+  - id         : the unique id action to be registered to;
+  - menuText   : action text which should appear in menu;
+  - tipText    : text which should appear in the tooltip;
+  - statusText : text which should appear in the status bar when action is activated;
+  - icon       : the name of the icon file (the actual icon file name can be coded in the translation files);
+  - key        : the key accelrator for the action
+  - toggle     : if true the action is checkable
+*/
+class TCreateActionEvent: public SALOME_Event {
+public:
+  typedef QtxAction* TResult;
+  TResult myResult;
+  int     myId;
+  QString myMenuText;
+  QString myTipText;
+  QString myStatusText;
+  QString myIcon;
+  int     myKey;
+  bool    myToggle;
+  TCreateActionEvent( const int id, const QString& menuText, const QString& tipText, 
+                     const QString& statusText, const QString& icon, const int key, const bool toggle ) 
+    : myResult( 0 ), myId( id ), myMenuText( menuText ), myTipText( tipText ),
+      myStatusText( statusText ), myIcon( icon ), myKey( key ), myToggle( toggle ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      SALOME_PYQT_Module* module = SALOME_PYQT_Module::getInitModule();
+      if ( !module )
+        module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+      if ( module )
+        myResult = (QtxAction*)module->createAction( myId, myTipText, myIcon, myMenuText, myStatusText, myKey, myToggle );
+    }
+  }
+};
+QtxAction* SalomePyQt::createAction( const int id,           const QString& menuText, 
+                                    const QString& tipText, const QString& statusText, 
+                                    const QString& icon,    const int key, const bool toggle )
+{
+  return ProcessEvent( new TCreateActionEvent( id, menuText, tipText, statusText, icon, key, toggle ) );
+}
+
+/*!
+  SalomePyQt::action
+  Get an action by its id. Returns 0 if the action with such id was not registered.
+*/
+class TActionEvent: public SALOME_Event {
+public:
+  typedef QtxAction* TResult;
+  TResult myResult;
+  int     myId;
+  TActionEvent( const int id )
+    : myResult( 0 ), myId( id ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      SALOME_PYQT_Module* module = SALOME_PYQT_Module::getInitModule();
+      if ( !module )
+        module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+      if ( module )
+        myResult = (QtxAction*)module->action( myId );
+    }
+  }
+};
+QtxAction* SalomePyQt::action( const int id )
+{
+  return ProcessEvent( new TActionEvent( id ) );
+}
+
+/*!
+  SalomePyQt::actionId
+  Get an action id. Returns -1 if the action was not registered.
+*/
+class TActionIdEvent: public SALOME_Event {
+public:
+  typedef  int TResult;
+  TResult  myResult;
+  const QtxAction* myAction;
+  TActionIdEvent( const QtxAction* action )
+    : myResult( -1 ), myAction( action ) {}
+  virtual void Execute() {
+    if ( SalomeApp_Application* anApp = getApplication() ) {
+      SALOME_PYQT_Module* module = SALOME_PYQT_Module::getInitModule();
+      if ( !module )
+        module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+      if ( module )
+        myResult = module->actionId( myAction );
+    }
+  }
+};
+int SalomePyQt::actionId( const QtxAction* a )
+{
+  return ProcessEvent( new TActionIdEvent( a ) );
+}
diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt_v4.sip b/src/SALOME_PYQT/SalomePyQt/SalomePyQt_v4.sip
new file mode 100644 (file)
index 0000000..f306399
--- /dev/null
@@ -0,0 +1,129 @@
+//=============================================================================
+// File      : SalomePyQt_v4.sip
+// Created   : 25/04/05
+// Author    : Vadim SANDLER
+// Project   : SALOME
+// Copyright : 2003-2005 CEA/DEN, EDF R&D
+// $Header   : $
+//=============================================================================
+
+%Module SalomePyQt
+
+%Import qtmod.sip
+
+class SALOME_Selection : QObject
+{
+%TypeHeaderCode
+#include <SalomePyQt.h>
+%End
+
+public:
+  void Clear();
+  void ClearIObjects();
+  void ClearFilters();
+
+private:
+  SALOME_Selection( QObject* /TransferThis/ );
+
+signals:
+  void currentSelectionChanged();
+};
+
+enum MenuName {
+  File        = 1,
+  View        = 2,
+  Edit        = 3,
+  Preferences = 4,
+  Tools       = 5,
+  Window      = 6,
+  Help        = 7  
+};
+
+enum {
+  WT_ObjectBrowser,
+  WT_PyConsole,
+  WT_LogWindow,
+  WT_User
+};
+
+class QtxAction : QAction
+{
+%TypeHeaderCode
+#include <QtxAction.h>
+%End
+
+private:
+  QtxAction(const QtxAction &);
+};
+
+class SalomePyQt
+{
+%TypeHeaderCode
+#include <SalomePyQt.h>
+%End
+
+public:
+  static QWidget*          getDesktop();
+  static QWidget*          getMainFrame();
+  static QMenuBar*         getMainMenuBar();
+  static QPopupMenu*       getPopupMenu( const MenuName );
+  static SALOME_Selection* getSelection() /Factory/;
+  static int               getStudyId();
+  static void              putInfo( const QString&, const int = 0 );
+  static const QString     getActiveComponent();
+  static void              updateObjBrowser( const int = 0, bool = true );
+
+  static QString           getFileName         ( QWidget*, const QString&, const QStringList&, const QString&, bool ) /ReleaseGIL/ ;
+  static QStringList       getOpenFileNames    ( QWidget*, const QString&, const QStringList&, const QString& );
+  static QString           getExistingDirectory( QWidget*, const QString&, const QString& );
+
+  static void              helpContext( const QString&, const QString& );
+
+  static bool              dumpView( const QString& );
+
+  static int               createTool( const QString& );
+  static int               createTool( const int,  const int,      const int = -1 );
+  static int               createTool( const int,  const QString&, const int = -1 );
+  static int               createTool( QtxAction*, const int,      const int = -1, const int = -1 );
+  static int               createTool( QtxAction*, const QString&, const int = -1, const int = -1 );
+
+  static int               createMenu( const QString&, const int,
+                                      const int = -1, const int = -1 );
+  static int               createMenu( const QString&, const QString&, 
+                                      const int = -1, const int = -1 );
+  static int               createMenu( const int,      const int,
+                                      const int = -1, const int = -1 );
+  static int               createMenu( const int,      const QString&, 
+                                      const int = -1, const int = -1 );
+  static int               createMenu( QtxAction*,     const int,      const int = -1, 
+                                      const int = -1, const int = -1 );
+  static int               createMenu( QtxAction*,     const QString&, const int = -1, 
+                                      const int = -1, const int = -1 );
+
+  static QtxAction*        createSeparator();
+
+  static QtxAction*        createAction( const int, const QString&, 
+                                        const QString& = QString::null, const QString& = QString::null, 
+                                        const QString& = QString::null, const int = 0, const bool = false );
+
+  static QtxAction*        action( const int );
+  static int               actionId( const QtxAction* );
+
+  static void              addSetting    ( const QString&, const QString&, const double );
+  static void              addSetting    ( const QString&, const QString&, const int /Constrained/ );
+  static void              addSetting    ( const QString&, const QString&, const QString& );
+  static void              addSetting    ( const QString&, const QString&, const QColor& );
+  static int               integerSetting( const QString&, const QString&, const int = 0 );
+  static double            doubleSetting ( const QString&, const QString&, const int = 0 );
+  static bool              boolSetting   ( const QString&, const QString&, const bool = 0 );
+  static QString           stringSetting ( const QString&, const QString&, const QString& = QString("") );
+  static QColor            colorSetting  ( const QString&, const QString&, const QColor& = QColor() );
+  static void              removeSetting ( const QString&, const QString& );
+
+// obsolete
+  static void              addStringSetting( const QString&, const QString&, bool = true );
+  static void              addIntSetting   ( const QString&, const int,      bool = true );
+  static void              addDoubleSetting( const QString&, const double,   bool = true );
+  static void              removeSettings  ( const QString& );
+  static QString           getSetting      ( const QString& );
+};
diff --git a/src/SALOME_SWIG/salome_test.py b/src/SALOME_SWIG/salome_test.py
new file mode 100755 (executable)
index 0000000..75e5f0b
--- /dev/null
@@ -0,0 +1,486 @@
+#  SALOME SALOME_SWIG : binding of C++ implementation and Python
+#
+#  Copyright (C) 2003  CEA/DEN, EDF R&D
+#
+#
+#
+#  File   : salome_test.py
+#  Module : SALOME
+
+print "Test the application loading  GEOM, SMESH, VISU, MED, components and doing some"
+print "operation within the components."
+
+import salome
+from salome import sg
+import SALOMEDS
+import os
+
+import SALOME_ModuleCatalog
+
+print "======================================================================"
+print "           Get Catalog "
+print "======================================================================"
+obj = salome.naming_service.Resolve('Kernel/ModulCatalog')
+catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog)
+
+print "======================================================================"
+print "           Create Study "
+print "======================================================================"
+
+comp = catalog.GetComponent("GEOM")
+if comp is None:
+       raise RuntimeError,"Component GEOM not found in Module Catalog."
+
+import geompy
+
+print "================================="
+print "       create AttributeReal      "
+print "================================="
+A = geompy.myBuilder.FindOrCreateAttribute(geompy.father, "AttributeReal")
+if A == None :
+       raise  RuntimeError, "Can't create AttributeReal attribute"
+A = A._narrow(SALOMEDS.AttributeReal)
+A.SetValue(0.0001)
+if A.Value() != 0.0001:
+       raise  RuntimeError, "Error : wrong value of  AttributeReal"
+
+print
+print " ===========  Test Geometry  =========================="
+print
+
+print "==================================="
+print "     define a box"
+print "==================================="
+
+box = geompy.MakeBox(0., 0., 0., 100., 200., 300.)
+idbox = geompy.addToStudy(box,"box")
+
+print
+print "=============  Test SMESH  ============================="
+print
+
+import StdMeshers
+
+comp = catalog.GetComponent("SMESH")
+if comp is None:
+       raise RuntimeError,"Component SMESH not found in Module Catalog."
+
+comp = catalog.GetComponent("MED")
+if comp is None:
+       raise RuntimeError,"Component MED not found in Module Catalog."
+
+import SMESH
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+myBuilder = salome.myStudy.NewBuilder()
+
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
+
+ShapeTypeCompSolid = 1
+ShapeTypeSolid = 2
+ShapeTypeShell = 3
+ShapeTypeFace = 4
+ShapeTypeWire = 5
+ShapeTypeEdge = 6
+ShapeTypeVertex = 7
+
+# ---- define a box
+
+box = geompy.MakeBox(0., 0., 0., 100., 200., 300.)
+idbox = geompy.addToStudy(box,"box")
+
+# ---- add first face of box in study
+
+subShapeList=geompy.SubShapeAll(box,ShapeTypeFace)
+face=subShapeList[0]
+name = geompy.SubShapeName(face, box)
+print name
+idface=geompy.addToStudyInFather(box,face,name)
+
+# ---- add shell from box  in study
+
+subShellList=geompy.SubShapeAll(box,ShapeTypeShell)
+shell = subShellList[0]
+name = geompy.SubShapeName(shell, box)
+print name
+idshell=geompy.addToStudyInFather(box,shell,name)
+
+# ---- add first edge of face in study
+
+edgeList = geompy.SubShapeAll(face,ShapeTypeEdge)
+edge=edgeList[0];
+name = geompy.SubShapeName(edge, face)
+print name
+idedge=geompy.addToStudyInFather(face,edge,name)
+
+
+# ---- SMESH 
+
+# ---- create Hypothesis
+
+print "-------------------------- create Hypothesis"
+print "-------------------------- LocalLength"
+hypLen1 = smesh.CreateHypothesis( "LocalLength", "libStdMeshersEngine.so" )
+hypLen1.SetLength(100)
+print hypLen1.GetName()
+print hypLen1.GetId()
+print hypLen1.GetLength()
+
+smeshgui.SetName(salome.ObjectToID(hypLen1), "Local_Length_100")
+
+print "-------------------------- NumberOfSegments"
+hypNbSeg1= smesh.CreateHypothesis( "NumberOfSegments", "libStdMeshersEngine.so" )
+hypNbSeg1.SetNumberOfSegments(7)
+print hypNbSeg1.GetName()
+print hypNbSeg1.GetId()
+print hypNbSeg1.GetNumberOfSegments()
+
+smeshgui.SetName(salome.ObjectToID(hypNbSeg1), "NumberOfSegments_7")
+
+print "-------------------------- MaxElementArea"
+hypArea1 = smesh.CreateHypothesis( "MaxElementArea", "libStdMeshersEngine.so" )
+hypArea1.SetMaxElementArea(2500)
+print hypArea1.GetName()
+print hypArea1.GetId()
+print hypArea1.GetMaxElementArea()
+
+smeshgui.SetName(salome.ObjectToID(hypArea1), "MaxElementArea_2500")
+
+print "-------------------------- MaxElementArea"
+hypArea2 = smesh.CreateHypothesis( "MaxElementArea", "libStdMeshersEngine.so" )
+hypArea2.SetMaxElementArea(500)
+print hypArea2.GetName()
+print hypArea2.GetId()
+print hypArea2.GetMaxElementArea()
+
+smeshgui.SetName(salome.ObjectToID(hypArea2), "MaxElementArea_500")
+
+print "-------------------------- Regular_1D"
+algoReg = smesh.CreateHypothesis( "Regular_1D", "libStdMeshersEngine.so" )
+listHyp=algoReg.GetCompatibleHypothesis()
+for hyp in listHyp:
+    print hyp
+print algoReg.GetName()
+print algoReg.GetId()
+
+smeshgui.SetName(salome.ObjectToID(algoReg), "Regular_1D" )
+
+print "-------------------------- MEFISTO_2D"
+algoMef = smesh.CreateHypothesis( "MEFISTO_2D", "libStdMeshersEngine.so" )
+listHyp=algoMef.GetCompatibleHypothesis()
+for hyp in listHyp:
+    print hyp
+print algoMef.GetName()
+print algoMef.GetId()
+
+smeshgui.SetName(salome.ObjectToID(algoMef), "MEFISTO_2D" )
+
+# ---- add hypothesis to box
+
+print "-------------------------- add hypothesis to box"
+box=salome.IDToObject(idbox)
+mesh = smesh.CreateMesh(box)
+
+smeshgui.SetName( salome.ObjectToID(mesh), "MeshBox" );
+
+ret=mesh.AddHypothesis(box,algoReg)
+print ret
+ret=mesh.AddHypothesis(box,algoMef)
+print ret
+
+
+ret=mesh.AddHypothesis(box,hypNbSeg1)
+print ret
+ret=mesh.AddHypothesis(box,hypArea1)
+print ret
+
+
+# ---- add hypothesis to edge
+
+print "-------------------------- add hypothesis to edge"
+edge=salome.IDToObject(idedge)
+submesh=mesh.GetSubMesh(edge, "SubMeshEdge")
+
+ret=mesh.AddHypothesis(edge,algoReg)
+print ret
+ret=mesh.AddHypothesis(edge,hypLen1)
+print ret
+
+print "-------------------------- add hypothesis to face"
+face=salome.IDToObject(idface)
+submesh   = mesh.GetSubMesh(face, "SubMeshFace")
+
+ret=mesh.AddHypothesis(face,hypArea2)
+print ret
+
+smesh.Compute(mesh, box)
+sg.updateObjBrowser(1);
+
+print
+print "=============  Test  Supervisor  ============================="
+print
+
+comp = catalog.GetComponent("SUPERV")
+if comp is None:
+       raise RuntimeError,"Component SUPERV not found in Module Catalog."
+
+from SuperV import *
+import SALOMEDS
+myStudy = salome.myStudy
+myBuilder = myStudy.NewBuilder()
+
+SuperVision = lcc.FindOrLoadComponent("SuperVisionContainer","SUPERV")
+father = myStudy.FindComponent("SUPERV")
+if father is None:
+        father = myBuilder.NewComponent("SUPERV")
+        A1 = myBuilder.FindOrCreateAttribute(father, "AttributeName");
+        FName = A1._narrow(SALOMEDS.AttributeName)
+        FName.SetValue( salome.sg.getComponentUserName("SUPERV") )
+       A2 = myBuilder.FindOrCreateAttribute(father, "AttributePixMap");
+       aPixmap = A2._narrow(SALOMEDS.AttributePixMap);
+       aPixmap.SetPixMap( "ICON_OBJBROWSER_Supervision" );
+       myBuilder.DefineComponentInstance(father,SuperVision)
+
+def addStudy(ior):
+    dataflow = SuperVision.getStreamGraph(ior)
+    name=dataflow.Name()
+    itr = myStudy.NewChildIterator(father)
+    while itr.More():
+        item=itr.Value()
+        res,A=item.FindAttribute("AttributeName")
+        if res:
+            aName = A._narrow(SALOMEDS.AttributeName)
+            if aName.Value() == name :
+               print myBuilder.FindOrCreateAttribute(item, "AttributeIOR")
+               A  = myBuilder.FindOrCreateAttribute(item, "AttributeIOR")
+               print "A = ", A
+               if A is not None :
+                   #res,A = myBuilder.FindOrCreateAttribute(item, "AttributeIOR")
+                   anIOR  = A._narrow(SALOMEDS.AttributeIOR);
+                  print "anIOR.SetValue(dataflow.getIOR())"
+                  anIOR.SetValue(dataflow.getIOR()) 
+                return
+        itr.Next()
+    obj = myBuilder.NewObject(father)
+    A=myBuilder.FindOrCreateAttribute(obj, "AttributeName")
+    aName=A._narrow(SALOMEDS.AttributeName)
+    aName.SetValue(name)
+    A=myBuilder.FindOrCreateAttribute(obj, "AttributeIOR")
+    anIOR  = A._narrow(SALOMEDS.AttributeIOR)
+    anIOR.SetValue(dataflow.getIOR())
+
+import os
+dir= os.getenv("DATA_DIR")
+if dir == None:
+       raise RuntimeError, "DATA_DIR is not defined"
+xmlfile = dir +"/Superv/Graphs/GraphGeomEssai.xml"
+print "Load dataflow from the file : "
+print xmlfile
+print
+
+myGraph = StreamGraph ( xmlfile )
+
+# This DataFlow is "valid" : no loop, correct links between Nodes etc...
+print "myGraph.IsValid() = ", myGraph.IsValid()
+
+# Get Nodes
+myGraph.PrintNodes()
+
+# This DataFlow is "executable" : all pending Ports are defined with Datas
+print myGraph.IsExecutable()
+
+# Starts only execution of that DataFlow and gets control immediatly
+print myGraph.Run()
+
+# That DataFlow is running ==> 0 (false)
+print myGraph.IsDone()
+
+# Events of execution :
+aStatus,aNode,anEvent,aState = myGraph.Event()
+while aStatus :
+    print aNode.Thread(),aNode.SubGraph(),aNode.Name(),anEvent,aState
+    aStatus,aNode,anEvent,aState = myGraph.Event()
+print "myGraph.IsDone() = ",myGraph.IsDone()
+
+# Wait for Completion (but it is already done after event loop ...)
+print "Done : ",myGraph.DoneW()
+
+print " "
+#print "Type : print myGraph.IsDone()"
+#print "       If execution is finished ==> 1 (true)"
+res=myGraph.IsDone()
+if res != 1:
+       raise RuntimeError, "myGraph.Run() is not done"
+
+print " "
+print "Type : myGraph.PrintPorts()"
+print "       to see input and output values of the graph"
+myGraph.PrintPorts()
+
+# Export will create newsupervisionexample.xml and the corresponding .py file
+tmpdir=os.getenv("TmpDir")
+if tmpdir is None:
+       tmpdir="/tmp"
+file = tmpdir + "/newsupervisionexample"
+print "--------------\n"+file+"\n--------------\n"
+myGraph.Export(file)
+
+ior = salome.orb.object_to_string(myGraph.G)
+addStudy(ior)
+
+GraphName = myGraph.Name()
+print "Befor save ",
+#nodes = myGraph.Nodes()
+nodes = myGraph.G.Nodes().FNodes
+length_bs = len(nodes)
+print "ListOfNodes length = ", length_bs
+names=[]
+for node in nodes:
+       names.append(node.Name())
+print names
+
+# Graph creation 
+GraphInLines = StreamGraph( 'GraphInLines' )
+GraphInLines.SetName( 'GraphInLines' )
+GraphInLines.SetAuthor( '' )
+GraphInLines.SetComment( '' )
+GraphInLines.Coords( 0 , 0 )
+
+# Creation of InLine Nodes
+PyAdd = []
+PyAdd.append( 'def Add(a,b) :  ' )
+PyAdd.append( '    return a+b  ' )
+PyAdd.append( '' )
+Add = GraphInLines.INode( 'Add' , PyAdd )
+Add.InPort( 'a' , 'long' )
+Add.InPort( 'b' , 'long' )
+Add.OutPort( 'f' , 'long' )
+Add.SetName( 'Add' )
+Add.SetAuthor( '' )
+Add.SetComment( 'Python function' )
+Add.Coords( 351 , 77 )
+PySub = []
+PySub.append( 'def Sub(a,b) : ' )
+PySub.append( '    return a-b ' )
+PySub.append( '' )
+Sub = GraphInLines.INode( 'Sub' , PySub )
+Sub.InPort( 'a' , 'long' )
+Sub.InPort( 'b' , 'long' )
+Sub.OutPort( 'f' , 'long' )
+Sub.SetName( 'Sub' )
+Sub.SetAuthor( '' )
+Sub.SetComment( 'Python function' )
+Sub.Coords( 86 , 333 )
+PyMul = []
+PyMul.append( 'def Mul(a,b) : ' )
+PyMul.append( '    return a*b ' )
+Mul = GraphInLines.INode( 'Mul' , PyMul )
+Mul.InPort( 'a' , 'long' )
+Mul.InPort( 'b' , 'long' )
+Mul.OutPort( 'Result' , 'long' )
+Mul.SetName( 'Mul' )
+Mul.SetAuthor( '' )
+Mul.SetComment( 'Python function' )
+Mul.Coords( 616 , 247 )
+
+# Creation of intermediate Output variables and of Control Links
+Addf = Add.Port( 'f' )
+Mula = GraphInLines.Link( Addf , Mul.Port( 'a' ) )
+Mula.AddCoord( 1 , 570 , 356 )
+Mula.AddCoord( 2 , 570 , 186 )
+Subf = Sub.Port( 'f' )
+Mulb = GraphInLines.Link( Subf , Mul.Port( 'b' ) )
+Mulb.AddCoord( 1 , 282 , 376 )
+Mulb.AddCoord( 2 , 282 , 442 )
+Addb = GraphInLines.Link( Subf , Add.Port( 'b' ) )
+Addb.AddCoord( 1 , 283 , 209 )
+Addb.AddCoord( 2 , 283 , 374 )
+Addb.AddCoord( 3 , 283 , 442 )
+
+# Creation of Input datas
+Adda = Add.Input( 'a' , 1)
+Suba = Sub.Input( 'a' , 3)
+Subb = Sub.Input( 'b' , 4)
+
+# Creation of Output variables
+MulResult = Mul.Port( 'Result' )
+
+GraphInLines.Run()
+
+GraphInLines.DoneW()
+
+GraphInLines.PrintPorts()
+
+sg.updateObjBrowser(1);
+
+print
+print "=============  Test  VISU  and MED ============================="
+print
+
+comp = catalog.GetComponent("VISU")
+if comp is None:
+       raise RuntimeError,"Component VISU not found in Module Catalog."
+
+import sys
+import SALOMEDS
+import SALOME
+import SALOME_MED
+import VISU
+
+import visu_gui
+
+medFileName = "pointe.med"
+medFile = os.getenv('DATA_DIR') + '/MedFiles/' + medFileName
+print "Load ", medFile
+
+studyCurrent = salome.myStudyName
+
+med_comp = salome.lcc.FindOrLoadComponent("FactoryServer", "MED")
+myVisu = salome.lcc.FindOrLoadComponent("FactoryServer", "VISU")
+
+try:
+    if os.access(medFile, os.R_OK) :
+       if not os.access(medFile, os.W_OK) :
+              import random
+              medFileNew = "/tmp/" + str(random.randint(0,1000000)) + "_" + medFileName
+              print " -- Copy " + medFile + " to " + medFileNew
+              os.system("cp "+ medFile + " " + medFileNew)
+              medFile = medFileNew
+              os.system("chmod 755 " + medFile)
+
+       if os.access(medFile, os.W_OK) :
+           med_comp.readStructFileWithFieldType(medFile,studyCurrent)
+           med_obj = visu_gui.visu.getMedObjectFromStudy()
+           print "med_obj - ", med_obj
+
+           myField1 = visu_gui.visu.getFieldObjectFromStudy(2,1)
+           aMeshName = "maa1"
+           anEntity = VISU.NODE
+          aTimeStampId = -1
+                  
+           myResult1 = myVisu.ImportMedField(myField1)
+           aMesh1 = myVisu.MeshOnEntity(myResult1, aMeshName, anEntity);
+           
+          aScalarMap1= myVisu.ScalarMapOnField(myResult1, aMeshName, anEntity, myField1.getName(), aTimeStampId)
+          
+          myResult2 = myVisu.ImportFile(medFile);
+          aMesh2 = myVisu.MeshOnEntity(myResult2, aMeshName, anEntity);
+           
+          aTimeStampId = 3
+          aScalarMap2= myVisu.ScalarMapOnField(myResult2, aMeshName, anEntity, myField1.getName(), aTimeStampId)
+                  
+          sg.updateObjBrowser(0)
+       else :  print "We have no permission to rewrite medFile, so readStructFileWithFieldType can't open this file";
+    else :  print  "We have no permission to read medFile, it will not be opened"; 
+
+except:
+    if sys.exc_type == SALOME.SALOME_Exception :
+        print "There is no permission to read " + medFile
+    else :
+        print sys.exc_type 
+        print sys.exc_value
+        print sys.exc_traceback
+
+sg.updateObjBrowser(1);
diff --git a/src/STD/STD_Application.cxx b/src/STD/STD_Application.cxx
new file mode 100755 (executable)
index 0000000..3e955e6
--- /dev/null
@@ -0,0 +1,881 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "STD_Application.h"
+
+#include "STD_MDIDesktop.h"
+
+#include "STD_CloseDlg.h"
+
+#include <SUIT_Tools.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_Session.h>
+#include <SUIT_ViewModel.h>
+#include <SUIT_Operation.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+
+#include <QtxDockAction.h>
+#include <QtxActionMenuMgr.h>
+#include <QtxActionToolMgr.h>
+#include <QtxPopupMenu.h>
+
+#include <qmenubar.h>
+#include <qtoolbar.h>
+#include <qpopupmenu.h>
+#include <qstatusbar.h>
+#include <qfiledialog.h>
+#include <qapplication.h>
+
+#include <iostream>
+
+/*!Create and return new instance of STD_Application*/
+extern "C" STD_EXPORT SUIT_Application* createApplication()
+{
+  return new STD_Application();
+}
+
+/*!Constructor.*/
+STD_Application::STD_Application()
+: SUIT_Application(),
+myEditEnabled( true ),
+myActiveViewMgr( 0 )
+{
+  STD_MDIDesktop* desk = new STD_MDIDesktop();
+
+  setDesktop( desk );
+}
+
+/*!Destructor.*/
+STD_Application::~STD_Application()
+{
+}
+
+/*! \retval QString "StdApplication"*/
+QString STD_Application::applicationName() const
+{
+  return QString( "StdApplication" );
+}
+
+/*!Start STD_Application*/
+void STD_Application::start()
+{
+  createActions();
+
+  updateDesktopTitle();
+  updateCommandsStatus();
+  setEditEnabled( myEditEnabled );
+
+  loadPreferences();
+
+  SUIT_Application::start();
+}
+
+/*!
+  Close the Application
+*/
+void STD_Application::closeApplication()
+{
+  if ( desktop() )
+    savePreferences();
+
+  SUIT_Application::closeApplication();
+}
+
+/*!Event on closing desktop*/
+void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
+{
+  if ( SUIT_Session::session()->applications().count() < 2 )
+  {
+    onExit();
+    return;
+  }
+
+  if ( !isPossibleToClose() )
+  {
+    e->ignore();
+    return;
+  }
+
+  SUIT_Study* study = activeStudy();
+
+  if ( study )
+    study->closeDocument();
+
+  setActiveStudy( 0 );
+  delete study;
+
+  savePreferences();
+
+  setDesktop( 0 );
+
+  closeApplication();
+}
+
+/*!Create actions, menus and tools*/
+void STD_Application::createActions()
+{
+  SUIT_Desktop* desk = desktop();
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+  if ( !desk || !resMgr )
+    return;
+
+  // Create actions
+
+  createAction( FileNewId, tr( "TOT_DESK_FILE_NEW" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_FILE_NEW" ) ),
+                tr( "MEN_DESK_FILE_NEW" ), tr( "PRP_DESK_FILE_NEW" ),
+                CTRL+Key_N, desk, false, this, SLOT( onNewDoc() ) );
+
+  createAction( FileOpenId, tr( "TOT_DESK_FILE_OPEN" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
+                tr( "MEN_DESK_FILE_OPEN" ), tr( "PRP_DESK_FILE_OPEN" ),
+                CTRL+Key_O, desk, false, this, SLOT( onOpenDoc() ) );
+
+  createAction( FileCloseId, tr( "TOT_DESK_FILE_CLOSE" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_FILE_CLOSE" ) ),
+                tr( "MEN_DESK_FILE_CLOSE" ), tr( "PRP_DESK_FILE_CLOSE" ),
+                CTRL+Key_W, desk, false, this, SLOT( onCloseDoc() ) );
+
+  createAction( FileExitId, tr( "TOT_DESK_FILE_EXIT" ), QIconSet(),
+                tr( "MEN_DESK_FILE_EXIT" ), tr( "PRP_DESK_FILE_EXIT" ),
+                CTRL+Key_Q, desk, false, this, SLOT( onExit() ) );
+
+  createAction( FileSaveId, tr( "TOT_DESK_FILE_SAVE" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_FILE_SAVE" ) ),
+                tr( "MEN_DESK_FILE_SAVE" ), tr( "PRP_DESK_FILE_SAVE" ),
+                CTRL+Key_S, desk, false, this, SLOT( onSaveDoc() ) );
+
+  createAction( FileSaveAsId, tr( "TOT_DESK_FILE_SAVEAS" ), QIconSet(),
+                tr( "MEN_DESK_FILE_SAVEAS" ), tr( "PRP_DESK_FILE_SAVEAS" ),
+                CTRL+Key_A, desk, false, this, SLOT( onSaveAsDoc() ) );
+
+  createAction( EditCopyId, tr( "TOT_DESK_EDIT_COPY" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_EDIT_COPY" ) ),
+                tr( "MEN_DESK_EDIT_COPY" ), tr( "PRP_DESK_EDIT_COPY" ),
+                CTRL+Key_C, desk, false, this, SLOT( onCopy() ) );
+
+  createAction( EditPasteId, tr( "TOT_DESK_EDIT_PASTE" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_EDIT_PASTE" ) ),
+                tr( "MEN_DESK_EDIT_PASTE" ), tr( "PRP_DESK_EDIT_PASTE" ),
+                CTRL+Key_V, desk, false, this, SLOT( onPaste() ) );
+
+  QAction* a = createAction( ViewStatusBarId, tr( "TOT_DESK_VIEW_STATUSBAR" ),
+                             QIconSet(), tr( "MEN_DESK_VIEW_STATUSBAR" ),
+                             tr( "PRP_DESK_VIEW_STATUSBAR" ), SHIFT+Key_S, desk, true );
+  a->setOn( desk->statusBar()->isVisibleTo( desk ) );
+  connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onViewStatusBar( bool ) ) );
+
+  createAction( NewWindowId, tr( "TOT_DESK_NEWWINDOW" ), QIconSet(),
+                tr( "MEN_DESK_NEWWINDOW" ), tr( "PRP_DESK_NEWWINDOW" ), 0, desk  );
+
+  createAction( HelpAboutId, tr( "TOT_DESK_HELP_ABOUT" ), QIconSet(),
+                tr( "MEN_DESK_HELP_ABOUT" ), tr( "PRP_DESK_HELP_ABOUT" ),
+                SHIFT+Key_A, desk, false, this, SLOT( onHelpAbout() ) );
+
+  //SRN: BugID IPAL9021, add an action "Load"
+  createAction( FileLoadId, tr( "TOT_DESK_FILE_LOAD" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
+               tr( "MEN_DESK_FILE_LOAD" ), tr( "PRP_DESK_FILE_LOAD" ),
+               CTRL+Key_L, desk, false, this, SLOT( onLoadDoc() ) );
+  //SRN: BugID IPAL9021: End
+
+  QtxDockAction* da = new QtxDockAction( tr( "TOT_DOCK_WINDOWS" ), tr( "MEN_DOCK_WINDOWS" ), desk );
+  registerAction( ViewWindowsId, da );
+  da->setAutoPlace( false );
+
+  // Create menus
+
+  int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1, -1, 0 );
+  int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 );
+  int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1, -1, 10 );
+  int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
+
+  // Create menu items
+
+  createMenu( FileNewId, fileMenu, 0 );
+  createMenu( FileOpenId, fileMenu, 0 );
+  createMenu( FileLoadId, fileMenu, 0 );  //SRN: BugID IPAL9021, add a menu item "Load"
+  createMenu( FileCloseId, fileMenu, 0 );
+  createMenu( separator(), fileMenu, -1, 0 );
+  createMenu( FileSaveId, fileMenu, 0 );
+  createMenu( FileSaveAsId, fileMenu, 0 );
+  createMenu( separator(), fileMenu, -1, 0 );
+
+  createMenu( separator(), fileMenu );
+  createMenu( FileExitId, fileMenu );
+
+  createMenu( EditCopyId, editMenu );
+  createMenu( EditPasteId, editMenu );
+  createMenu( separator(), editMenu );
+
+  createMenu( ViewWindowsId, viewMenu );
+  createMenu( ViewStatusBarId, viewMenu );
+  createMenu( separator(), viewMenu );
+
+  createMenu( HelpAboutId, helpMenu );
+  createMenu( separator(), helpMenu );
+
+  // Create tool bars
+
+  int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) );
+
+  // Create tool items
+
+  createTool( FileNewId, stdTBar );
+  createTool( FileOpenId, stdTBar );
+  createTool( FileSaveId, stdTBar );
+  createTool( FileCloseId, stdTBar );
+  createTool( separator(), stdTBar );
+  createTool( EditCopyId, stdTBar );
+  createTool( EditPasteId, stdTBar );
+}
+
+/*!Opens new application*/
+void STD_Application::onNewDoc()
+{
+  QApplication::setOverrideCursor( Qt::waitCursor );
+
+  if ( !activeStudy() )
+  {
+    createEmptyStudy();
+    activeStudy()->createDocument();
+    studyCreated( activeStudy() );
+  }
+  else
+  {
+    SUIT_Application* aApp = startApplication( 0, 0 );
+    if ( aApp->inherits( "STD_Application" ) )
+      ((STD_Application*)aApp)->onNewDoc();
+    else
+    {
+      aApp->createEmptyStudy();
+      aApp->activeStudy()->createDocument();
+    }
+  }
+
+  QApplication::restoreOverrideCursor();
+}
+
+/*!Put file name from file dialog to onOpenDoc(const QString&) function*/
+void STD_Application::onOpenDoc()
+{
+  // It is preferrable to use OS-specific file dialog box here !!!
+  QString aName = getFileName( true, QString::null, getFileFilter(), QString::null, 0 );
+  if ( aName.isNull() )
+    return;
+
+  onOpenDoc( aName );
+}
+
+/*! \retval true, if document was opened successful, else false.*/
+bool STD_Application::onOpenDoc( const QString& aName )
+{
+  QApplication::setOverrideCursor( Qt::waitCursor );
+
+  bool res = true;
+  if ( !activeStudy() )
+  {
+    // if no study - open in current desktop
+    res = useFile( aName );
+  }
+  else
+  {
+    // if study exists - open in new desktop. Check: is the same file is opened?
+    SUIT_Session* aSession = SUIT_Session::session();
+    QPtrList<SUIT_Application> aAppList = aSession->applications();
+    bool isAlreadyOpen = false;
+    SUIT_Application* aApp = 0;
+    for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
+    {
+      aApp = it.current();
+      if ( aApp->activeStudy()->studyName() == aName )
+        isAlreadyOpen = true;
+    }
+    if ( !isAlreadyOpen )
+    {
+      aApp = startApplication( 0, 0 );
+      if ( aApp )
+        res = aApp->useFile( aName );
+      if ( !res )
+        aApp->closeApplication();
+    }
+    else
+      aApp->desktop()->setActiveWindow();
+  }
+
+  QApplication::restoreOverrideCursor();
+
+  return res;
+}
+
+/*! called on loading the existent study */
+void STD_Application::onLoadDoc()
+{
+}
+
+/*! \retval true, if document was loaded successful, else false.*/
+bool STD_Application::onLoadDoc( const QString& aName )
+{
+  bool res = true;
+  if ( !activeStudy() )
+  {
+    // if no study - load in current desktop
+    res = useStudy( aName );
+  }
+  else
+  {
+    // if study exists - load in new desktop. Check: is the same file is loaded?
+    SUIT_Session* aSession = SUIT_Session::session();
+    QPtrList<SUIT_Application> aAppList = aSession->applications();
+    bool isAlreadyOpen = false;
+    SUIT_Application* aApp = 0;
+    for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
+    {
+      aApp = it.current();
+      if ( aApp->activeStudy()->studyName() == aName )
+        isAlreadyOpen = true;
+    }
+    if ( !isAlreadyOpen )
+    {
+      aApp = startApplication( 0, 0 );
+      if ( aApp )
+        res = aApp->useStudy( aName );
+    }
+    else
+      aApp->desktop()->setActiveWindow();
+  }
+  return res;
+}
+
+/*!Virtual function. Not implemented here.*/
+void STD_Application::beforeCloseDoc( SUIT_Study* )
+{
+}
+
+/*!Virtual function. Not implemented here.*/
+void STD_Application::afterCloseDoc()
+{
+}
+
+/*!Close document, if it's possible.*/
+void STD_Application::onCloseDoc( bool ask )
+{
+  if ( ask && !isPossibleToClose() )
+    return;
+
+  SUIT_Study* study = activeStudy();
+
+  beforeCloseDoc( study );
+
+  if ( study )
+    study->closeDocument(myClosePermanently);
+
+  clearViewManagers();
+
+  setActiveStudy( 0 );
+  delete study;
+
+  int aNbStudies = 0;
+  QPtrList<SUIT_Application> apps = SUIT_Session::session()->applications();
+  for ( unsigned i = 0; i < apps.count(); i++ )
+    aNbStudies += apps.at( i )->getNbStudies();
+
+  // STV: aNbStudies - number of currently existing studies (exclude currently closed)
+  // STV: aNbStudies should be compared with 0.
+  if ( aNbStudies )
+  {
+    savePreferences();
+    setDesktop( 0 );
+  }
+  else
+  {
+    updateDesktopTitle();
+    updateCommandsStatus();
+  }
+
+  afterCloseDoc();
+
+  if ( !desktop() )
+    closeApplication();
+}
+
+/*!Check the application on closing.
+ * \retval true if possible, else false
+ */
+bool STD_Application::isPossibleToClose()
+{
+  myClosePermanently = true; //SRN: BugID: IPAL9021
+  if ( activeStudy() )
+  {
+    activeStudy()->abortAllOperations();
+    if ( activeStudy()->isModified() )
+    {
+      QString sName = activeStudy()->studyName().stripWhiteSpace();
+      QString msg = sName.isEmpty() ? tr( "INF_DOC_MODIFIED" ) : tr ( "INF_DOCUMENT_MODIFIED" ).arg( sName );
+
+      //SRN: BugID: IPAL9021: Begin
+      STD_CloseDlg dlg(desktop());
+      switch( dlg.exec() )
+      {
+      case 1:
+        if ( activeStudy()->isSaved() )
+          onSaveDoc();
+        else if ( !onSaveAsDoc() )
+          return false;
+        break;
+      case 2:
+        break;
+      case 3:
+             myClosePermanently = false;
+        break;
+      case 4:
+      default:
+        return false;
+      }
+     //SRN: BugID: IPAL9021: End
+    }
+  }
+  return true;
+}
+
+/*!Save document if all ok, else error message.*/
+void STD_Application::onSaveDoc()
+{
+  if ( !activeStudy() )
+    return;
+
+  bool isOk = false;
+  if ( activeStudy()->isSaved() )
+  {
+    putInfo( tr( "INF_DOC_SAVING" ) + activeStudy()->studyName() );
+
+    QApplication::setOverrideCursor( Qt::waitCursor );
+
+    isOk = activeStudy()->saveDocument();
+
+    QApplication::restoreOverrideCursor();
+
+    if ( !isOk )
+    {
+      putInfo( "" );
+      SUIT_MessageBox::error1( desktop(), tr( "TIT_FILE_SAVEAS" ),
+                                                tr( "MSG_CANT_SAVE" ).arg( activeStudy()->studyName() ), tr( "BUT_OK" ) );
+    }
+    else
+      putInfo( tr( "INF_DOC_SAVED" ).arg( "" ) );
+  }
+
+  if ( isOk )
+    studySaved( activeStudy() );
+  else
+    onSaveAsDoc();
+}
+
+/*! \retval TRUE, if doument saved successful, else FALSE.*/
+bool STD_Application::onSaveAsDoc()
+{
+  SUIT_Study* study = activeStudy();
+  if ( !study )
+    return false;
+
+  bool isOk = false;
+  while ( !isOk )
+  {
+    QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
+    if ( aName.isNull() )
+      return false;
+
+    QApplication::setOverrideCursor( Qt::waitCursor );
+
+    putInfo( tr( "INF_DOC_SAVING" ) + aName );
+    isOk = study->saveDocumentAs( aName );
+
+    putInfo( isOk ? tr( "INF_DOC_SAVED" ).arg( aName ) : "" );
+
+    QApplication::restoreOverrideCursor();
+
+    if ( !isOk )
+      SUIT_MessageBox::error1( desktop(), tr( "ERROR" ),
+                             tr( "INF_DOC_SAVING_FAILS" ).arg( aName ), tr( "BUT_OK" ) );
+  }
+
+  studySaved( activeStudy() );
+
+  return isOk;
+}
+
+/*!Closing session.*/
+void STD_Application::onExit()
+{
+  int aAnswer = SUIT_MessageBox::info2( desktop(), tr( "INF_DESK_EXIT" ), tr( "QUE_DESK_EXIT" ),
+                                        tr( "BUT_OK" ), tr( "BUT_CANCEL" ), 1, 2, 2 );
+  if ( aAnswer == 1 )
+    SUIT_Session::session()->closeSession();
+}
+
+/*!Virtual slot. Not implemented here.*/
+void STD_Application::onCopy()
+{
+}
+
+/*!Virtual slot. Not implemented here.*/
+void STD_Application::onPaste()
+{
+}
+
+/*!Sets \a theEnable for menu manager and for tool manager.*/
+void STD_Application::setEditEnabled( bool theEnable )
+{
+  myEditEnabled = theEnable;
+
+  QtxActionMenuMgr* mMgr = desktop()->menuMgr();
+  QtxActionToolMgr* tMgr = desktop()->toolMgr();
+
+  for ( int i = EditCopyId; i <= EditPasteId; i++ )
+  {
+    mMgr->setShown( i, myEditEnabled );
+    tMgr->setShown( i, myEditEnabled );
+  }
+}
+
+/*!\retval true, if document opened successful, else false.*/
+bool STD_Application::useFile(const QString& theFileName)
+{
+  bool res = SUIT_Application::useFile( theFileName );
+
+  if ( res )
+    studyOpened( activeStudy() );
+
+  return res;
+}
+
+/*!Update desktop title.*/
+void STD_Application::updateDesktopTitle()
+{
+  QString aTitle = applicationName();
+  QString aVer = applicationVersion();
+  if ( !aVer.isEmpty() )
+    aTitle += QString( " " ) + aVer;
+
+  if ( activeStudy() )
+  {
+    QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
+    if ( !sName.isEmpty() )
+      aTitle += QString( " - [%1]" ).arg( sName );
+  }
+
+  desktop()->setCaption( aTitle );
+}
+
+/*!Update commands status.*/
+void STD_Application::updateCommandsStatus()
+{
+  bool aHasStudy = activeStudy() != 0;
+  bool aIsNeedToSave = false;
+  if ( aHasStudy )
+    aIsNeedToSave = !activeStudy()->isSaved() || activeStudy()->isModified();
+
+  if ( action( FileSaveId ) )
+    action( FileSaveId )->setEnabled( aIsNeedToSave );
+  if ( action( FileSaveAsId ) )
+    action( FileSaveAsId )->setEnabled( aHasStudy );
+  if ( action( FileCloseId ) )
+    action( FileCloseId )->setEnabled( aHasStudy );
+  if ( action( NewWindowId ) )
+    action( NewWindowId )->setEnabled( aHasStudy );
+}
+
+/*!\retval SUIT_ViewManager by viewer manager type name.*/
+SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
+{
+  SUIT_ViewManager* vm = 0;
+  for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current() && !vm; ++it )
+  {
+    if ( it.current()->getType() == vmType )
+      vm = it.current();
+  }
+  return vm;
+}
+
+/*! \param vmType - input view manager type name
+ * \param lst - output list of view managers with types \a vmType.
+ */
+void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst ) const
+{
+  for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
+    if ( it.current()->getType() == vmType )
+      lst.append( it.current() );
+}
+
+/*!\param lst - output list of all view managers.*/
+void STD_Application::viewManagers( ViewManagerList& lst ) const
+{
+  for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
+    lst.append( it.current() );
+}
+
+/*!\retval ViewManagerList - const list of all view managers.*/
+ViewManagerList STD_Application::viewManagers() const
+{
+  ViewManagerList lst;
+  viewManagers( lst );
+  return lst;
+}
+
+/*!\retval SUIT_ViewManager - return pointer to active view manager.*/
+SUIT_ViewManager* STD_Application::activeViewManager() const
+{
+  return myActiveViewMgr;
+}
+
+/*!Add view manager to view managers list, if it not already there.*/
+void STD_Application::addViewManager( SUIT_ViewManager* vm )
+{
+  if ( !vm )
+    return;
+
+  if ( !containsViewManager( vm ) )
+  {
+    myViewMgrs.append( vm );
+    connect( vm, SIGNAL( activated( SUIT_ViewManager* ) ),
+             this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
+    vm->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
+
+    emit viewManagerAdded( vm );
+  }
+/*
+  if ( !activeViewManager() && myViewMgrs.count() == 1 )
+    setActiveViewManager( vm );
+*/
+}
+
+/*!Remove view manager from view managers list.*/
+void STD_Application::removeViewManager( SUIT_ViewManager* vm )
+{
+  if ( !vm )
+    return;
+
+  vm->closeAllViews();
+
+  emit viewManagerRemoved( vm );
+
+  vm->disconnectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
+  vm->disconnect();
+  myViewMgrs.removeRef( vm );
+
+  if ( myActiveViewMgr == vm )
+    myActiveViewMgr = 0;
+}
+
+/*!Remove all view managers from view managers list.*/
+void STD_Application::clearViewManagers()
+{
+  ViewManagerList lst;
+  viewManagers( lst );
+
+  for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
+    removeViewManager( it.current() );
+}
+
+/*!\retval TRUE, if view manager \a vm, already in view manager list (\a myViewMgrs).*/
+bool STD_Application::containsViewManager( SUIT_ViewManager* vm ) const
+{
+  return myViewMgrs.contains( vm ) > 0;
+}
+
+/*!Private slot, sets active manager to \vm, if \vm in view managers list.*/
+void STD_Application::onViewManagerActivated( SUIT_ViewManager* vm )
+{
+  setActiveViewManager( vm );
+}
+
+/*!Sets status bar show, if \on = true, else status bar hide.*/
+void STD_Application::onViewStatusBar( bool on )
+{
+  if ( on )
+    desktop()->statusBar()->show();
+  else
+    desktop()->statusBar()->hide();
+}
+
+/*!Call SUIT_MessageBox::info1(...) with about information.*/
+void STD_Application::onHelpAbout()
+{
+  SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" );
+}
+
+/*!Create empty study. \n
+ * Create new view manager and adding it to view managers list.
+ */
+void STD_Application::createEmptyStudy()
+{
+  SUIT_Application::createEmptyStudy();
+
+  SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), desktop(), new SUIT_ViewModel() );
+
+  addViewManager( vm );
+}
+
+/*!Sets active manager to \vm, if \vm in view managers list.*/
+void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
+{
+  if ( !containsViewManager( vm ) )
+    return;
+
+  myActiveViewMgr = vm;
+  emit viewManagerActivated( vm );
+}
+
+/*!Public slot. */
+void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextMenuEvent* e )
+{
+  QtxPopupMenu* popup = new QtxPopupMenu();
+  // fill popup by own items
+  QString title;
+  contextMenuPopup( client->popupClientType(), popup, title );
+  popup->setTitleText( title );
+
+  popup->insertSeparator();
+  // add items from popup client
+  client->contextMenuPopup( popup );
+
+  SUIT_Tools::simplifySeparators( popup );
+
+  if ( popup->count() )
+    popup->exec( e->globalPos() );
+  delete popup;
+}
+
+#include <qregexp.h>
+
+/*!\retval QString - return file name from dialog.*/
+QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters,
+                                     const QString& caption, QWidget* parent )
+{
+  if ( !parent )
+    parent = desktop();
+  if ( open )
+  {
+    return QFileDialog::getOpenFileName( initial, filters, parent, 0, caption );
+  }
+  else
+  {
+    QString aName;
+    QString aUsedFilter;
+    QString anOldPath = initial;
+
+    bool isOk = false;
+    while ( !isOk )
+    {
+      // It is preferrable to use OS-specific file dialog box here !!!
+      aName = QFileDialog::getSaveFileName( anOldPath, filters, parent, 0, caption, &aUsedFilter );
+
+      if ( aName.isNull() )
+        isOk = true;
+      else
+      {
+             int aEnd = aUsedFilter.findRev( ')' );
+             int aStart = aUsedFilter.findRev( '(', aEnd );
+             QString wcStr = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
+
+        int idx = 0;
+        QStringList extList;
+        QRegExp rx( "[\b\\*]*\\.([\\w]+)" );
+        while ( ( idx = rx.search( wcStr, idx ) ) != -1 )
+        {
+          extList.append( rx.cap( 1 ) );
+          idx += rx.matchedLength();
+        }
+
+        if ( !extList.isEmpty() && !extList.contains( QFileInfo( aName ).extension() ) )
+          aName += QString( ".%1" ).arg( extList.first() );
+
+             if ( QFileInfo( aName ).exists() )
+        {
+               int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
+                                                                             tr( "MSG_FILE_EXISTS" ).arg( aName ),
+                                                                             tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
+               if ( aAnswer == 3 )
+          {     // cancelled
+            aName = QString::null;
+                 isOk = true;
+          }
+               else if ( aAnswer == 2 ) // not save to this file
+                 anOldPath = aName;             // not to return to the same initial dir at each "while" step
+               else                     // overwrite the existing file
+                 isOk = true;
+        }
+             else
+               isOk = true;
+      }
+    }
+    return aName;
+  }
+}
+
+/*!\retval QString - return directory name from dialog.*/
+QString STD_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
+{
+  if ( !parent )
+    parent = desktop();
+  return QFileDialog::getExistingDirectory( initial, parent, 0, caption, true );
+}
+
+void STD_Application::setDesktop( SUIT_Desktop* desk )
+{
+  SUIT_Desktop* prev = desktop();
+
+  SUIT_Application::setDesktop( desk );
+
+  if ( prev != desk && desk )
+    connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
+             this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
+}
+
+/*!
+  Allow to load preferences before the desktop will be shown.
+*/
+void STD_Application::loadPreferences()
+{
+}
+
+/*!
+  Allow to save preferences before the application will be closed.
+*/
+void STD_Application::savePreferences()
+{
+}
+
+void STD_Application::studyCreated( SUIT_Study* )
+{
+  updateDesktopTitle();
+  updateCommandsStatus();
+}
+
+void STD_Application::studyOpened( SUIT_Study* )
+{
+  updateDesktopTitle();
+  updateCommandsStatus();
+}
+
+void STD_Application::studySaved( SUIT_Study* )
+{
+  updateDesktopTitle();
+  updateCommandsStatus();
+}
diff --git a/src/STD/STD_Application.h b/src/STD/STD_Application.h
new file mode 100755 (executable)
index 0000000..c8e3b4a
--- /dev/null
@@ -0,0 +1,159 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef STD_APPLICATION_H
+#define STD_APPLICATION_H
+
+#include "STD.h"
+
+#include <SUIT_Application.h>
+
+#include <SUIT_Desktop.h>
+#include <SUIT_ViewManager.h>
+
+#include <qmap.h>
+#include <qptrlist.h>
+
+class QToolBar;
+class QtxAction;
+class QPopupMenu;
+class SUIT_Operation;
+class SUIT_ViewWindow;
+class SUIT_ToolWindow;
+
+typedef QPtrList<SUIT_ViewManager> ViewManagerList;
+
+#if defined WIN32
+#pragma warning( disable: 4251 )
+#endif
+
+class STD_EXPORT STD_Application : public SUIT_Application
+{
+  Q_OBJECT
+
+public:
+  STD_Application();
+  virtual ~STD_Application();
+
+  virtual QString       applicationName() const;
+
+  virtual bool          isPossibleToClose();
+  virtual bool          useFile( const QString& );
+
+  virtual void          createEmptyStudy();
+
+  void                  setEditEnabled( const bool );
+  bool                  isEditEnabled() const { return myEditEnabled; }
+
+  void                  clearViewManagers();
+  virtual void          addViewManager( SUIT_ViewManager* );
+  virtual void          removeViewManager( SUIT_ViewManager* );
+
+  SUIT_ViewManager*     activeViewManager() const;
+  SUIT_ViewManager*     viewManager( const QString& ) const;
+
+  bool                  containsViewManager( SUIT_ViewManager* ) const;
+
+  ViewManagerList       viewManagers() const;
+  void                  viewManagers( ViewManagerList& ) const;
+  void                  viewManagers( const QString&, ViewManagerList& ) const;
+
+  virtual QString       getFileFilter() const { return QString::null; }
+  virtual QString       getFileName( bool open, const QString& initial, const QString& filters, 
+                                    const QString& caption, QWidget* parent );
+  QString               getDirectory( const QString& initial, const QString& caption, QWidget* parent );
+
+  virtual void          start();
+
+  virtual void          closeApplication();
+
+  virtual void          contextMenuPopup( const QString&, QPopupMenu*, QString& ) {}
+
+signals:
+  /*!emit that view manager added*/
+  void                  viewManagerAdded( SUIT_ViewManager* );
+  /*!emit that view manager removed*/
+  void                  viewManagerRemoved( SUIT_ViewManager* );
+  /*!emit that view manager activated*/
+  void                  viewManagerActivated( SUIT_ViewManager* );
+
+public slots:
+  virtual void          onNewDoc();
+  virtual void          onCloseDoc( bool ask = true );
+  virtual void          onSaveDoc();
+  virtual bool          onSaveAsDoc();
+
+  virtual void          onOpenDoc();
+  virtual bool          onOpenDoc( const QString& );
+
+  virtual void          onLoadDoc();
+  virtual bool          onLoadDoc( const QString& );
+
+  virtual void          onExit();
+
+  virtual void          onCopy();
+  virtual void          onPaste();
+
+  virtual void          onViewStatusBar( bool );
+
+  virtual void          onHelpAbout();
+
+  virtual void          onDesktopClosing( SUIT_Desktop*, QCloseEvent* );
+  virtual void          onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* );
+
+private slots:
+  virtual void          onViewManagerActivated( SUIT_ViewManager* );
+
+protected:
+  enum {  FileNewId, FileOpenId, FileCloseId, FileSaveId, FileSaveAsId,
+          FileExitId, EditCutId, EditCopyId, EditPasteId, ViewStatusBarId,
+          NewWindowId, HelpAboutId, ViewWindowsId, FileLoadId, UserID };
+protected:
+  virtual void          createActions();
+  virtual void          updateDesktopTitle();
+  virtual void          updateCommandsStatus();
+
+  virtual void          setDesktop( SUIT_Desktop* );
+
+  virtual void          loadPreferences();
+  virtual void          savePreferences();
+
+  virtual void          studySaved( SUIT_Study* );
+  virtual void          studyOpened( SUIT_Study* );
+  virtual void          studyCreated( SUIT_Study* );
+
+  virtual void          beforeCloseDoc( SUIT_Study* theDoc );
+  virtual void          afterCloseDoc();
+
+  virtual void          setActiveViewManager( SUIT_ViewManager* );
+
+private:
+  ViewManagerList       myViewMgrs;
+  SUIT_ViewManager*     myActiveViewMgr;
+
+private:
+  bool                  myEditEnabled;
+  bool                  myClosePermanently;
+};
+
+#if defined WIN32
+#pragma warning( default: 4251 )
+#endif
+
+#endif
diff --git a/src/STD/STD_TabDesktop.cxx b/src/STD/STD_TabDesktop.cxx
new file mode 100644 (file)
index 0000000..24dfd5c
--- /dev/null
@@ -0,0 +1,199 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "STD_TabDesktop.h"
+
+#include <SUIT_Session.h>
+#include <SUIT_ViewWindow.h>
+#include <SUIT_ResourceMgr.h>
+
+#include <QtxAction.h>
+#include <QtxWorkstack.h>
+#include <QtxActionMenuMgr.h>
+#include <QtxWorkstackAction.h>
+
+#include <qvbox.h>
+#include <qmenubar.h>
+#include <qworkspace.h>
+#include <qobjectlist.h>
+
+#include <stdarg.h>
+
+/*!Constructor.Create new instances of QVBox and QtxWorkstack.*/
+STD_TabDesktop::STD_TabDesktop()
+: SUIT_Desktop(),
+myWorkstack( 0 ),
+myWorkstackAction( 0 )
+{
+  QVBox* base = new QVBox( this );
+  base->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+
+  setCentralWidget( base );
+
+  myWorkstack = new QtxWorkstack( base );
+  // setting Expanding size policy for central workstack.  If there are several widgets
+  // in central area of Desktop, other widgets will be added below the workstack (CATHARE, TRIPOLI modules).  
+  // But the workstack must occupy as much space as possible -- set Expanding for it.
+  myWorkstack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+
+  myWorkstack->setAccel(QtxWorkstack::SplitVertical,   SHIFT + Key_V);
+  myWorkstack->setAccel(QtxWorkstack::SplitHorizontal, SHIFT + Key_H);
+  myWorkstack->setAccel(QtxWorkstack::Close,           SHIFT + Key_C);
+
+  connect( myWorkstack, SIGNAL( windowActivated( QWidget* ) ),
+           this, SLOT( onWindowActivated( QWidget* ) ) );
+
+  createActions();
+}
+
+/*!Destructor.*/
+STD_TabDesktop::~STD_TabDesktop()
+{
+}
+
+/*!\retval SUIT_ViewWindow - return const active window.*/
+SUIT_ViewWindow* STD_TabDesktop::activeWindow() const
+{
+  SUIT_ViewWindow* wnd = 0;
+
+  QWidget* wid = myWorkstack->activeWindow();
+  if ( wid && wid->inherits( "SUIT_ViewWindow" ) )
+    wnd = (SUIT_ViewWindow*)wid;
+
+  return wnd;
+}
+
+/*!\retval QPtrList<SUIT_ViewWindow> - return const active window list.*/
+QPtrList<SUIT_ViewWindow> STD_TabDesktop::windows() const
+{
+  QPtrList<SUIT_ViewWindow> winList;
+
+  QWidgetList children = myWorkstack->windowList();
+  for ( QWidgetListIt it( children ); it.current(); ++it )
+  {
+    if ( it.current()->inherits( "SUIT_ViewWindow" ) )
+      winList.append( (SUIT_ViewWindow*)it.current() );
+  }
+
+  return winList;
+}
+
+/*!\retval QWidget pointer - QT work stack.*/
+QWidget* STD_TabDesktop::parentArea() const
+{
+  return workstack();
+}
+
+/*!Call method perform for operation \a type.*/
+void STD_TabDesktop::windowOperation( const int type )
+{
+  myWorkstackAction->perform( operationFlag( type ) );
+}
+
+/*!Sets window operations by \a first ... parameters.*/
+void STD_TabDesktop::setWindowOperations( const int first, ... )
+{
+  va_list ints;
+       va_start( ints, first );
+
+       QValueList<int> typeList;
+
+       int cur = first;
+       while ( cur )
+       {
+         typeList.append( cur );
+               cur = va_arg( ints, int );
+  }
+
+       setWindowOperations( typeList );
+}
+
+/*!Sets window operations by variable \a opList - operation list.*/
+void STD_TabDesktop::setWindowOperations( const QValueList<int>& opList )
+{
+  int flags = 0;
+
+  for ( QValueList<int>::const_iterator it = opList.begin(); it != opList.end(); ++it )
+    flags = flags | operationFlag( *it );
+
+  myWorkstackAction->setItems( flags );
+}
+
+/*!\retval QtxWorkstack pointer - QT work stack.*/
+QtxWorkstack* STD_TabDesktop::workstack() const
+{
+  return myWorkstack;
+}
+
+/*!Emit window activated.*/
+void STD_TabDesktop::onWindowActivated( QWidget* w )
+{
+  if ( w && w->inherits( "SUIT_ViewWindow" ) )
+    emit windowActivated( (SUIT_ViewWindow*)w );
+}
+
+/*!Create actions for window.*/
+void STD_TabDesktop::createActions()
+{
+  if ( myWorkstackAction )
+    return;
+
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  if ( !resMgr )
+    return;
+
+  myWorkstackAction = new QtxWorkstackAction( workstack(), this );
+
+  myWorkstackAction->setItems( QtxWorkstackAction::Split | QtxWorkstackAction::Windows );
+
+  // Split Horizontal
+  myWorkstackAction->setIconSet( QtxWorkstackAction::HSplit,
+                                 resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_HSPLIT" ) ) );
+  myWorkstackAction->setMenuText( QtxWorkstackAction::HSplit, tr( "MEN_DESK_WINDOW_HSPLIT" ) );
+  myWorkstackAction->setStatusTip( QtxWorkstackAction::HSplit, tr( "PRP_DESK_WINDOW_HSPLIT" ) );
+
+  // Split Vertical
+  myWorkstackAction->setIconSet( QtxWorkstackAction::VSplit,
+                                 resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_VSPLIT" ) ) );
+  myWorkstackAction->setMenuText( QtxWorkstackAction::VSplit, tr( "MEN_DESK_WINDOW_VSPLIT" ) );
+  myWorkstackAction->setStatusTip( QtxWorkstackAction::VSplit, tr( "PRP_DESK_WINDOW_VSPLIT" ) );
+
+  QtxActionMenuMgr* mMgr = menuMgr();
+  if ( !mMgr )
+    return;
+
+  int winMenuId = mMgr->insert( tr( "MEN_DESK_WINDOW" ), -1, 100 );
+  mMgr->insert( myWorkstackAction, winMenuId, -1 );
+  mMgr->insert( QtxActionMenuMgr::separator(), winMenuId, -1 );
+}
+
+/*!Convert STD_TabDesktop enumerations to QtxWorkstackAction*/
+int STD_TabDesktop::operationFlag( const int type ) const
+{
+  int res = 0;
+  switch ( type )
+  {
+  case VSplit:
+    res = QtxWorkstackAction::VSplit;
+    break;
+  case HSplit:
+    res = QtxWorkstackAction::HSplit;
+    break;
+  }
+  return res;
+}
diff --git a/src/STD/resources/STD_msg_en.po b/src/STD/resources/STD_msg_en.po
new file mode 100755 (executable)
index 0000000..2c5d9fd
--- /dev/null
@@ -0,0 +1,361 @@
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: example-Qt-message-extraction\n"
+"POT-Creation-Date: 1999-02-23 15:38+0200\n"
+"PO-Revision-Date: 1999-02-23 15:38+0200\n"
+"Last-Translator: \n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+msgid "INF_READY"
+msgstr "Ready"
+
+msgid "BUT_OK"
+msgstr "OK"
+
+msgid "BUT_CANCEL"
+msgstr "Cancel"
+
+msgid "BUT_CLOSE"
+msgstr "Close"
+
+msgid "BUT_HELP"
+msgstr "Help"
+
+msgid "BUT_YES"
+msgstr "Yes"
+
+msgid "BUT_NO"
+msgstr "No"
+
+msgid "BUT_APPLY"
+msgstr "Apply"
+
+msgid "ERR_ERROR"
+msgstr "Error"
+
+msgid "WRN_WARNING"
+msgstr "Warning"
+
+msgid "INF_INFO" 
+msgstr "Information"
+
+msgid "FILTER_FILES"
+msgstr "%1 Files (%2)"
+
+msgid "ALL_FILES"
+msgstr "All Files (*.*)"
+
+msgid "INF_CANCELLED"
+msgstr "Cancelled"
+
+msgid "ERR_UNKNOWN"
+msgstr "Unknown error"
+
+## ----------------------------------------------------
+
+msgid "INF_DESK_DOC_CREATE"
+msgstr "Create a new document"
+
+msgid "ERR_APP_NOAPP"
+msgstr "No application"
+
+msgid "INF_DESK_EXIT"
+msgstr "Exit"
+
+msgid "INF_DESK_TOOLBAR_STANDARD"
+msgstr "Standard"
+
+msgid "MEN_DESK_FILE"
+msgstr "&File"
+
+msgid "MEN_DESK_FILE_CLOSE"
+msgstr "&Close"
+
+msgid "MEN_DESK_FILE_EXIT"
+msgstr "E&xit"
+
+msgid "MEN_DESK_FILE_NEW"
+msgstr "&New"
+
+msgid "MEN_DESK_FILE_OPEN"
+msgstr "&Open..."
+
+msgid "MEN_DESK_FILE_PRINT"
+msgstr "&Print"
+
+msgid "MEN_DESK_FILE_SAVE"
+msgstr "&Save"
+
+msgid "MEN_DESK_FILE_SAVEAS"
+msgstr "Save &As..."
+
+msgid "MEN_DESK_EDIT"
+msgstr "&Edit"
+
+msgid "MEN_DESK_EDIT_CUT"
+msgstr "Cu&t"
+
+msgid "MEN_DESK_EDIT_COPY"
+msgstr "&Copy"
+
+msgid "MEN_DESK_EDIT_PASTE"
+msgstr "&Paste"
+
+msgid "MEN_DESK_HELP"
+msgstr "&Help"
+
+msgid "MEN_DESK_HELP_ABOUT"
+msgstr "&About..."
+
+msgid "MEN_DESK_HELP_CONTENTS"
+msgstr "&Contents"
+
+msgid "MEN_DESK_HELP_SEARCH"
+msgstr "&Search..."
+
+msgid "MEN_DESK_VIEW"
+msgstr "&View"
+
+msgid "MEN_DESK_VIEW_TOOLBARS"
+msgstr "T&oolbars"
+
+msgid "MEN_DESK_VIEW_STATUSBAR"
+msgstr "&Status Bar"
+
+msgid "MEN_DESK_VIEW_STDTOOLBAR"
+msgstr "&Standard"
+
+msgid "PRP_DESK_FILE_CLOSE"
+msgstr "Closes the active document"
+
+msgid "PRP_DESK_FILE_EXIT"
+msgstr "Exits the application"
+
+msgid "PRP_DESK_FILE_NEW"
+msgstr "Creates a new document"
+
+msgid "PRP_DESK_FILE_OPEN"
+msgstr "Opens an existing document"
+
+msgid "PRP_DESK_FILE_PRINT"
+msgstr "Prints the active document"
+
+msgid "PRP_DESK_FILE_SAVE"
+msgstr "Saves the active document"
+
+msgid "PRP_DESK_FILE_SAVEAS"
+msgstr "Saves the active document with a new name"
+
+msgid "PRP_DESK_EDIT_CUT"
+msgstr "Cuts the selection and puts it to the Clipboard"
+
+msgid "PRP_DESK_EDIT_COPY"
+msgstr "Copy the selection to the Clipboard"
+
+msgid "PRP_DESK_EDIT_PASTE"
+msgstr "Inserts the Clipboard content at the insertion point"
+
+msgid "PRP_DESK_HELP_ABOUT"
+msgstr "Shows \'About\' dialog"
+
+msgid "PRP_DESK_HELP_CONTENTS"
+msgstr "Shows the whole help contents"
+
+msgid "PRP_DESK_HELP_SEARCH"
+msgstr "Searches help for a topic"
+
+msgid "PRP_DESK_VIEW_STATUSBAR"
+msgstr "Toggles status bar view on/off"
+
+msgid "PRP_DESK_VIEW_STDTOOLBAR"
+msgstr "Toggles standard toolbar on/off"
+
+msgid "QUE_DESK_EXIT"
+msgstr "Do you really want to quit ?"
+
+msgid "TOT_DESK_FILE_NEW"
+msgstr "New document"
+
+msgid "TOT_DESK_FILE_OPEN"
+msgstr "Open document"
+
+msgid "TOT_DESK_FILE_CLOSE"
+msgstr "Close document"
+
+msgid "TOT_DESK_FILE_PRINT"
+msgstr "Print document"
+
+msgid "TOT_DESK_FILE_SAVE"
+msgstr "Save document"
+
+msgid "TOT_DESK_FILE_SAVEAS"
+msgstr "Save document as..."
+
+msgid "TOT_DESK_FILE_EXIT"
+msgstr "Exit from application"
+
+msgid "TOT_DESK_EDIT_CUT"
+msgstr "Cut"
+
+msgid "TOT_DESK_EDIT_COPY"
+msgstr "Copy"
+
+msgid "TOT_DESK_EDIT_PASTE"
+msgstr "Paste"
+
+msgid "TOT_DESK_HELP_ABOUT"
+msgstr "About..."
+
+msgid "STD_Application::TOT_DOCK_WINDOWS"
+msgstr "Show / hide dockable windows and toolbars"
+
+msgid "STD_Application::MEN_DOCK_WINDOWS"
+msgstr "Windows and Toolbars"
+
+msgid "ERR_DOC_UNKNOWNTYPE_OPEN"
+msgstr "You are trying to open a document of an unknown type\n( %1 )"
+
+msgid "ERR_DOC_UNKNOWNTYPE_SAVE"
+msgstr "You are trying to save this document under an unknown type\n( %1 )"
+
+msgid "ERR_DOC_PERMISSIONDENIED_SAVE"
+msgstr "Can not save file %1. Permission denied"
+
+msgid "ERR_DOC_DIRWITHNAMEEXIST_SAVE"
+msgstr "Can not save file %1.\nDirectory with this name exist on disc. Try to use another name"
+
+msgid "QUE_DOC_FILEEXISTS"
+msgstr "The file %1 already exists.\nDo you want to overwrite it ?"
+
+msgid "ERR_DESK_NOAPP"
+msgstr "No applications registered"
+
+msgid "DESK_DEFAULTTITLE"
+msgstr "Qt Application Desktop"
+
+msgid "QUE_DOC_ALREADYOPEN"
+msgstr "The document %1 is already open.\nDo you want to reload it ?"
+
+msgid "MEN_DESK_WINDOW"
+msgstr "&Window"
+
+msgid "MEN_DESK_NEWWINDOW"
+msgstr "&New Window"
+
+msgid "TOT_DESK_NEWWINDOW"
+msgstr "Create new Window"
+
+msgid "PRP_DESK_NEWWINDOW"
+msgstr "Create new Window"
+
+msgid "MEN_DESK_WINDOW_CASCADE"
+msgstr "&Cascade"
+
+msgid "PRP_DESK_WINDOW_CASCADE"
+msgstr "Arranges the windows as overlapping tiles"
+
+msgid "MEN_DESK_WINDOW_TILE"
+msgstr "&Tile"
+
+msgid "PRP_DESK_WINDOW_TILE"
+msgstr "Arranges the windows as nonoverlapping tiles"
+
+msgid "MEN_DESK_WINDOW_HTILE"
+msgstr "Tile &Horizontally"
+
+msgid "PRP_DESK_WINDOW_HTILE"
+msgstr "Arranges the windows as nonoverlapping horizontal tiles"
+
+msgid "MEN_DESK_WINDOW_VTILE"
+msgstr "Tile &Vertically"
+
+msgid "PRP_DESK_WINDOW_VTILE"
+msgstr "Arranges the windows as nonoverlapping vertical tiles"
+
+msgid "PRP_DESK_WINDOW_ACTIVATE"
+msgstr "Activates this window"
+
+msgid "MEN_DESK_WINDOW_HSPLIT"
+msgstr "Split &Horizontally"
+
+msgid "PRP_DESK_WINDOW_HSPLIT"
+msgstr "Splits the active window on two horizontal parts"
+
+msgid "MEN_DESK_WINDOW_VSPLIT"
+msgstr "Split &Vertically"
+
+msgid "PRP_DESK_WINDOW_VSPLIT"
+msgstr "Splits the active window on two vertical parts"
+
+msgid "INF_DESK_DOCALREADYOPEN"
+msgstr "A document cannot be saved under a name of a document already opened.\nPlease, type another name for the document you want to save.\n( %1 )"
+
+msgid "MEN_DESK_FILE_MRU"
+msgstr "Recent &Files"
+
+msgid "PRP_DESK_FILE_MRU"
+msgstr "Opens a document"
+
+msgid "STD_Application::ABOUT_INFO"
+msgstr "SUIT Std application"
+
+msgid "MSG_FILE_EXISTS"
+msgstr "File \"%1\" already exists.\nDo you want to overwrite it?"
+
+msgid "MSG_CANT_SAVE"
+msgstr "Can't save file \"%1\"."
+
+msgid "TIT_FILE_SAVEAS"
+msgstr "Save As"
+
+msgid "STD_Application::INF_DOC_MODIFIED"
+msgstr "Document has been modified.\nDo you want to save changes?"
+
+msgid "STD_Application::INF_DOCUMENT_MODIFIED"
+msgstr "Document \"%1\" has been modified.\nDo you want to save changes?"
+
+msgid "STD_Application::INF_DOC_SAVED"
+msgstr "Study %1 saved"
+
+msgid "STD_Application::INF_DOC_SAVING"
+msgstr "Saving study "
+
+msgid "STD_Application::INF_DOC_SAVING_FAILS"
+msgstr "Can't save file \"%1\".\nPossible reason is permission denied or disc full.\nTry to use another file name."
+
+msgid "CLOSE_DLG_SAVE_CLOSE"
+msgstr "&Save&&Close"
+
+msgid "CLOSE_DLG_CLOSE"
+msgstr "&Close w/o saving"
+
+msgid "CLOSE_DLG_UNLOAD"
+msgstr "&Unload"
+
+msgid "TOT_DESK_FILE_LOAD"
+msgstr "Load document"
+
+msgid "PRP_DESK_FILE_LOAD"
+msgstr "Load a document"
+
+msgid "MEN_DESK_FILE_LOAD"
+msgstr "Conn&ect"    
+
+msgid "CLOSE_DLG_CAPTION"
+msgstr "Close active study"
+
+msgid "CLOSE_DLG_DESCRIPTION"
+msgstr "Do you want to close or only unload the study"
+
+msgid "DLG_LOAD_STUDY_CAPTION"
+msgstr "Load Study"
+
+msgid "MEN_STUDIES_CHOICE"
+msgstr "Choose existent study."
+
+
+
diff --git a/src/SUIT/SUIT_DataOwner.cxx b/src/SUIT/SUIT_DataOwner.cxx
new file mode 100755 (executable)
index 0000000..28ceb51
--- /dev/null
@@ -0,0 +1,172 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "SUIT_DataOwner.h"
+
+#ifndef WNT
+#include <typeinfo>
+#define _typeinfo std::type_info
+#else
+#include <typeinfo.h>
+#define _typeinfo type_info
+#endif
+
+//********************************************************************
+// SUIT_DataOwner class
+//********************************************************************
+
+
+/*! Constructor*/
+SUIT_DataOwner::SUIT_DataOwner()
+{
+}
+
+/*! Destructor*/
+SUIT_DataOwner::~SUIT_DataOwner()
+{
+}
+
+/*! operator== : compares two owners*/
+bool operator==( const SUIT_DataOwnerPtr& p1, const SUIT_DataOwnerPtr& p2 )
+{
+  if ( !p1.isNull() && !p2.isNull() )
+    return (p1->isEqual( *p2 ) && p2->isEqual( *p1 ));
+  return p1.isNull() && p2.isNull();
+}
+
+//********************************************************************
+/*! \class SUIT_DataOwnerPtrList 
+ * implements value list with unique items (uniqueness is 
+ * provided by operator==())
+ */
+//********************************************************************
+
+//====================================================================
+//! Constructor (default)
+//====================================================================
+SUIT_DataOwnerPtrList::SUIT_DataOwnerPtrList()
+  : QValueList<SUIT_DataOwnerPtr>(),
+    mySkipEqual( true )
+{
+}
+
+//====================================================================
+//! Constructor (default)
+//====================================================================
+SUIT_DataOwnerPtrList::SUIT_DataOwnerPtrList( const bool skipAllEqual )
+  : QValueList<SUIT_DataOwnerPtr>(),
+    mySkipEqual( skipAllEqual )
+{
+}
+
+//====================================================================
+//! Constructor (copy)
+//====================================================================
+SUIT_DataOwnerPtrList::SUIT_DataOwnerPtrList( const SUIT_DataOwnerPtrList& l )
+  : QValueList<SUIT_DataOwnerPtr>( l ),
+    mySkipEqual( true )
+{
+}
+
+//====================================================================
+//! Constructor (copy)
+//====================================================================
+SUIT_DataOwnerPtrList::SUIT_DataOwnerPtrList( const SUIT_DataOwnerPtrList& l, const bool skipAllEqual )
+  : QValueList<SUIT_DataOwnerPtr>(),
+    mySkipEqual( skipAllEqual )
+{
+  if ( skipAllEqual == l.mySkipEqual )
+    operator =( l );
+  else
+  {
+    SUIT_DataOwnerPtrList::const_iterator beginIt = l.begin();
+    SUIT_DataOwnerPtrList::const_iterator endIt = l.end();
+    for( ; beginIt != endIt; ++beginIt )
+      append( *beginIt );
+  }
+}
+
+#ifndef QT_NO_STL
+//====================================================================
+//! Constructor (from stl)
+//====================================================================
+SUIT_DataOwnerPtrList::SUIT_DataOwnerPtrList( const std::list<SUIT_DataOwnerPtr>& l )
+  : QValueList<SUIT_DataOwnerPtr>( l ),
+    mySkipEqual( true )
+{
+}
+#endif
+
+#ifndef QT_NO_STL
+//====================================================================
+//! Constructor (from stl)
+//====================================================================
+SUIT_DataOwnerPtrList::SUIT_DataOwnerPtrList( const std::list<SUIT_DataOwnerPtr>& l, const bool skipAllEqual )
+  : QValueList<SUIT_DataOwnerPtr>(),
+    mySkipEqual( skipAllEqual )
+{
+  std::list<SUIT_DataOwnerPtr>::const_iterator beginIt = l.begin();
+  std::list<SUIT_DataOwnerPtr>::const_iterator endIt = l.begin();
+  for( ; beginIt != endIt; ++beginIt )
+    append( *beginIt );
+}
+#endif
+
+//====================================================================
+//! Appends an item to the list
+//====================================================================
+SUIT_DataOwnerPtrList::iterator SUIT_DataOwnerPtrList::append( const SUIT_DataOwnerPtr& x )
+{
+  if( mySkipEqual && myMap.contains( x ) ) //contains uses SUIT_DataOwnerPtr::operator==
+    return myMap[ x ];
+
+  iterator it = QValueList<SUIT_DataOwnerPtr>::append( x );
+
+  if( mySkipEqual )
+    myMap.insert( x, it );
+
+  return it;
+}
+
+//====================================================================
+//! Clear list
+//====================================================================
+void SUIT_DataOwnerPtrList::clear()
+{
+  if( mySkipEqual )
+    myMap.clear();
+  QValueList<SUIT_DataOwnerPtr>::clear();
+}
+
+//====================================================================
+//! Remove an item from the list
+//====================================================================
+uint SUIT_DataOwnerPtrList::remove(const SUIT_DataOwnerPtr& x )
+{
+  if( mySkipEqual && myMap.contains(x) )
+    myMap.remove(x);
+  return QValueList<SUIT_DataOwnerPtr>::remove( x );
+}
+
+//====================================================================
+//! 
+//====================================================================
+bool operator<( const SUIT_DataOwnerPtr& p1, const SUIT_DataOwnerPtr& p2 )
+{
+  return p1.get()<p2.get();
+}
diff --git a/src/SUIT/SUIT_DataOwner.h b/src/SUIT/SUIT_DataOwner.h
new file mode 100755 (executable)
index 0000000..8f8caad
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef SUIT_DATAOWNER_H
+#define SUIT_DATAOWNER_H
+
+#include "SUIT_SmartPtr.h"
+
+#include <qvaluelist.h>
+#include <qmap.h>
+
+#ifdef WIN32
+#pragma warning( disable:4275 )
+#endif
+
+class SUIT_EXPORT SUIT_DataOwner : public RefCount 
+{
+public:
+  SUIT_DataOwner();//!< constructor
+  virtual ~SUIT_DataOwner();//!< destructor
+  //! compare function
+  virtual bool isEqual( const SUIT_DataOwner& ) const = 0;
+};
+
+/*! \typedef SUIT_DataOwnerPtr
+ * Define smart pointer for SUIT_DataOwner object
+ */
+typedef SMART(SUIT_DataOwner) SUIT_DataOwnerPtr;
+
+/*! Comparing two SUIT_DataOwnerPtr objects.*/
+bool operator==( const SUIT_DataOwnerPtr&, const SUIT_DataOwnerPtr& );
+
+/*! \class QValueList
+ *  \brief For more documentation see <a href="http://doc.trolltech.com">QT documentation</a>.
+ * QT class
+ */
+/*! \class SUIT_DataOwnerPtrList
+ * \brief Manage list of SUIT_DataOwnerPtr.
+ */
+class SUIT_EXPORT SUIT_DataOwnerPtrList : public QValueList<SUIT_DataOwnerPtr> 
+{
+public:
+  SUIT_DataOwnerPtrList();                         //!< constructor
+  SUIT_DataOwnerPtrList( const bool skipAllEqual );//!< constructor
+  SUIT_DataOwnerPtrList( const SUIT_DataOwnerPtrList& l );                         //!< copy constructor
+  SUIT_DataOwnerPtrList( const SUIT_DataOwnerPtrList& l, const bool skipAllEqual );//!< copy constructor
+#ifndef QT_NO_STL
+  SUIT_DataOwnerPtrList( const std::list<SUIT_DataOwnerPtr>& l );                         //!< copy constructor for STL list
+  SUIT_DataOwnerPtrList( const std::list<SUIT_DataOwnerPtr>& l, const bool skipAllEqual );//!< copy constructor for STL list
+#endif
+
+  iterator append      ( const SUIT_DataOwnerPtr& x );//!< append function
+  void     clear       ();
+  uint     remove      (const SUIT_DataOwnerPtr& x );
+
+private:
+  // hide this methods: only append() should be used to add items to the list
+  iterator prepend( const SUIT_DataOwnerPtr& x );//!< hide method
+  iterator insert ( iterator it, const SUIT_DataOwnerPtr& x );//!< hide method
+  void push_front ( const SUIT_DataOwnerPtr& x );//!< hide method
+  void push_back  ( const SUIT_DataOwnerPtr& x );//!< hide method
+
+private:
+  bool                              mySkipEqual;
+  QMap<SUIT_DataOwnerPtr, iterator> myMap;
+};
+
+#ifdef WIN32
+#pragma warning( default:4275 )
+#endif
+
+#endif
diff --git a/src/SUIT/SUIT_MessageBox.cxx b/src/SUIT/SUIT_MessageBox.cxx
new file mode 100755 (executable)
index 0000000..1d4d03c
--- /dev/null
@@ -0,0 +1,349 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+/********************************************************************
+**  Class:   SUIT_MessageBox
+**  Descr:   Message dialog box for SUIT-based application
+**  Module:  SUIT
+**  Created: UI team, 02.10.00
+*********************************************************************/
+
+#include "SUIT_MessageBox.h"
+#include "SUIT_OverrideCursor.h"
+
+#include <qmessagebox.h>
+#include <qapplication.h>
+
+/*!
+    Shows info message box with one button [ static ]
+*/
+int SUIT_MessageBox::info1( QWidget* parent, 
+                           const QString& caption, 
+                           const QString& text,
+                           const QString& textButton0 )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  int ret = QMessageBox::information( parent, caption, text, textButton0,
+                                     QString::null, QString::null, 0, 0 );
+  qApp->processEvents();
+  return ret;
+}
+
+/*!
+    Shows warning message box with one button [ static ]
+*/
+int SUIT_MessageBox::warn1( QWidget* parent, 
+                           const QString& caption, 
+                           const QString& text,
+                           const QString& textButton0 )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  int ret = QMessageBox::warning( parent, caption, text, textButton0,
+                                 QString::null, QString::null, 0, 0 );
+  qApp->processEvents();
+  return ret;
+}
+
+/*!
+    Shows error message box with one button [ static ]
+*/
+int SUIT_MessageBox::error1( QWidget* parent, 
+                            const QString& caption,
+                            const QString& text,
+                            const QString& textButton0 )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  int ret = QMessageBox::critical( parent, caption, text, textButton0,
+                                  QString::null, QString::null, 0, 0 );
+  qApp->processEvents();
+  return ret;
+}
+
+/*!
+    Shows question message box with one button [ static ]
+*/
+int SUIT_MessageBox::question1( QWidget* parent, 
+                               const QString& caption,
+                               const QString& text, 
+                               const QString& textButton0 )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  int ret = QMessageBox::question( parent, caption, text, textButton0,
+                                  QString::null, QString::null, 0, 0 );
+  qApp->processEvents();
+  return ret;
+}
+
+/*!
+    Shows info message box with two buttons.
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::info2( QWidget* parent, 
+                           const QString& caption,
+                           const QString& text, 
+                           const QString& textButton0,
+                           const QString& textButton1, 
+                           int idButton0, int idButton1, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::information( parent, caption, text, textButton0,
+                                     textButton1, QString::null, idDefault );
+  qApp->processEvents();
+  return ( ret == 0 ? idButton0 : idButton1 );
+}
+
+/*!
+  Shows warning message box with two buttons.
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::warn2( QWidget* parent, 
+                           const QString& caption,
+                           const QString& text,
+                           const QString& textButton0, 
+                           const QString& textButton1,
+                           int idButton0, int idButton1, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::warning( parent, caption, text, textButton0,
+                                 textButton1, QString::null, idDefault );
+  qApp->processEvents();
+  return ( ret == 0 ? idButton0 : idButton1 );
+}
+
+/*!
+    Shows error message box with two buttons
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::error2( QWidget* parent, 
+                            const QString& caption, 
+                            const QString& text,
+                            const QString& textButton0, 
+                            const QString& textButton1,
+                            int idButton0, int idButton1, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::critical( parent, caption, text, textButton0,
+                                  textButton1, QString::null, idDefault );
+  qApp->processEvents();
+  return ( ret == 0 ? idButton0 : idButton1 );
+}
+
+/*!
+    Shows question message box with two buttons
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::question2( QWidget* parent, 
+                               const QString& caption, 
+                               const QString& text,
+                               const QString& textButton0, 
+                               const QString& textButton1,
+                               int idButton0, int idButton1, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::question( parent, caption, text, textButton0,
+                                  textButton1, QString::null, idDefault );
+  qApp->processEvents();
+  return ( ret == 0 ? idButton0 : idButton1 );
+}
+
+/*!
+    Shows info message box with three buttons.
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::info3( QWidget* parent, 
+                           const QString& caption,
+                           const QString& text,
+                           const QString& textButton0, 
+                           const QString& textButton1,
+                           const QString& textButton2, 
+                           int idButton0, int idButton1,
+                           int idButton2, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else if ( idDefault == idButton2 )
+    idDefault = 2;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::information( parent, caption, text, textButton0,
+                                     textButton1, textButton2, idDefault );
+  qApp->processEvents();
+  switch ( ret )
+    {
+    case 0:
+      return idButton0;
+    case 1:
+      return idButton1;
+    case 2:
+      return idButton2;
+    }
+  return -1;
+}
+
+/*!
+    Shows warning message box with three buttons.
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::warn3( QWidget* parent, 
+                           const QString& caption, 
+                           const QString& text,
+                           const QString& textButton0, 
+                           const QString& textButton1,
+                           const QString& textButton2, 
+                           int idButton0, int idButton1,
+                           int idButton2, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else if ( idDefault == idButton2 )
+    idDefault = 2;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::warning( parent, caption, text, textButton0,
+                                 textButton1, textButton2, idDefault );
+  qApp->processEvents();
+  switch ( ret )
+    {
+    case 0:
+      return idButton0;
+    case 1:
+      return idButton1;
+    case 2:
+      return idButton2;
+    }
+  return -1;
+}
+
+/*!
+    Shows error message box with three buttons.
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::error3( QWidget* parent, 
+                            const QString& caption, 
+                            const QString& text,
+                            const QString& textButton0, 
+                            const QString& textButton1,
+                            const QString& textButton2, 
+                            int idButton0, int idButton1,
+                            int idButton2, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else if ( idDefault == idButton2 )
+    idDefault = 2;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::critical( parent, caption, text, textButton0,
+                                  textButton1, textButton2, idDefault );
+  qApp->processEvents();
+  switch ( ret )
+    {
+    case 0:
+      return idButton0;
+    case 1:
+      return idButton1;
+    case 2:
+      return idButton2;
+    }
+  return -1;
+}
+
+/*!
+    Shows question message box with three buttons.
+    Returns id of the pressed button or -1 if escaped [ static ]
+*/
+int SUIT_MessageBox::question3( QWidget* parent, 
+                               const QString& caption, 
+                               const QString& text,
+                               const QString& textButton0, 
+                               const QString& textButton1,
+                               const QString& textButton2, 
+                               int idButton0, int idButton1,
+                               int idButton2, int idDefault )
+{
+  SUIT_OverrideCursor cw( parent ? parent->cursor() : Qt::arrowCursor );
+  
+  if ( idDefault == idButton0 )
+    idDefault = 0;
+  else if ( idDefault == idButton1 )
+    idDefault = 1;
+  else if ( idDefault == idButton2 )
+    idDefault = 2;
+  else
+    idDefault = 0;
+  
+  int ret = QMessageBox::question( parent, caption, text, textButton0,
+                                  textButton1, textButton2, idDefault );
+  qApp->processEvents();
+  switch ( ret )
+    {
+    case 0:
+      return idButton0;
+    case 1:
+      return idButton1;
+    case 2:
+      return idButton2;
+    }
+  return -1;
+}
diff --git a/src/SUIT/SUIT_MessageBox.h b/src/SUIT/SUIT_MessageBox.h
new file mode 100755 (executable)
index 0000000..f8cf626
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+/********************************************************************
+**  Class:   SUIT_MessageBox
+**  Descr:   Message dialog box for SUIT-based application
+**  Module:  SUIT
+**  Created: UI team, 02.10.00
+*********************************************************************/
+#ifndef SUIT_MESSAGEBOX_H
+#define SUIT_MESSAGEBOX_H
+
+#include "SUIT.h"
+
+#include <qstring.h>
+#include <qwidget.h>
+
+#define SUIT_OK                      1
+#define SUIT_CANCEL                  2
+#define SUIT_YES                     3
+#define SUIT_NO                      4
+#define SUIT_HELP                    5
+
+class SUIT_EXPORT SUIT_MessageBox
+{
+public:
+    
+    /** @name One button message boxes.*/
+    //@{
+    static int info1 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0 );
+    static int warn1 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0 );
+    static int error1 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0 );
+    static int question1 ( QWidget* parent, const QString& caption, const QString& text,
+                          const QString& textButton0 );
+    //@}
+
+    /** @name Two buttons message boxes.*/
+    //@{
+    static int info2 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0, const QString& textButton1,
+                       int idButton0, int idButton1, int idDefault );
+    static int warn2 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0, const QString& textButton1,
+                       int idButton0, int idButton1, int idDefault );
+    static int error2 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0, const QString& textButton1,
+                       int idButton0, int idButton1, int idDefault );
+    static int question2 ( QWidget* parent, const QString& caption, const QString& text,
+                          const QString& textButton0, const QString& textButton1,
+                          int idButton0, int idButton1, int idDefault );
+    //@}
+
+    /** @name Three buttons message boxes.*/
+    //@{
+    static int info3 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0, const QString& textButton1,
+                       const QString& textButton2, int idButton0, int idButton1,
+                       int idButton2, int idDefault );
+    static int warn3 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0, const QString& textButton1,
+                       const QString& textButton2, int idButton0, int idButton1,
+                       int idButton2, int idDefault );
+    static int error3 ( QWidget* parent, const QString& caption, const QString& text,
+                       const QString& textButton0, const QString& textButton1,
+                       const QString& textButton2, int idButton0, int idButton1,
+                       int idButton2, int idDefault );
+    static int question3 ( QWidget* parent, const QString& caption, const QString& text,
+                          const QString& textButton0, const QString& textButton1,
+                          const QString& textButton2, int idButton0, int idButton1,
+                          int idButton2, int idDefault );
+    //@}
+};
+
+#endif
diff --git a/src/SUIT/SUIT_SelectionMgr.cxx b/src/SUIT/SUIT_SelectionMgr.cxx
new file mode 100755 (executable)
index 0000000..98a33e8
--- /dev/null
@@ -0,0 +1,329 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "SUIT_SelectionMgr.h"
+
+/*!\class SUIT_SelectionMgr
+ * Provide selection manager. Manipulate by selection filters, modes, data owners.
+ */
+
+/*!constructor. initialize myIterations and myIsSelChangeEnabled.*/
+SUIT_SelectionMgr::SUIT_SelectionMgr( const bool Feedback, QObject* p )
+: QObject( p ),
+myIterations( Feedback ? 1 : 0 ),
+myIsSelChangeEnabled( true )
+{
+}
+
+/*!destructor. mySelectors auto delete.*/
+SUIT_SelectionMgr::~SUIT_SelectionMgr()
+{
+  mySelectors.setAutoDelete( true );
+}
+
+/*!Add selector \a sel to selectors list,if it's not exists in list.*/
+void SUIT_SelectionMgr::installSelector( SUIT_Selector* sel )
+{
+  if ( sel && !mySelectors.contains( sel ) )
+    mySelectors.append( sel );
+}
+
+/*!Remove selector \a sel from list.*/
+void SUIT_SelectionMgr::removeSelector( SUIT_Selector* sel )
+{
+  mySelectors.remove( sel );
+}
+
+/*!Gets selectors list to \a lst.*/
+void SUIT_SelectionMgr::selectors( QPtrList<SUIT_Selector>& lst ) const
+{
+  lst.clear();
+  for ( SelectorListIterator it( mySelectors ); it.current(); ++it )
+    lst.append( it.current() );
+}
+
+/*!Gets selectors list to \a lst with type \a typ.*/
+void SUIT_SelectionMgr::selectors( const QString& typ, QPtrList<SUIT_Selector>& lst ) const
+{
+  lst.clear();
+  for ( SelectorListIterator it( mySelectors ); it.current(); ++it )
+  {
+    if ( it.current()->type() == typ )
+      lst.append( it.current() );
+  }
+}
+
+/*! Sets ebabled to \a on for all data owners with type \a typ.
+*/
+void SUIT_SelectionMgr::setEnabled( const bool on, const QString& typ )
+{
+  for ( SelectorListIterator it( mySelectors ); it.current(); ++it )
+  {
+    if ( typ.isEmpty() || it.current()->type() == typ )
+      it.current()->setEnabled( on );
+  }
+}
+
+/*! Gets selected data owners from list with type \a type to list \a lst.
+*/
+void SUIT_SelectionMgr::selected( SUIT_DataOwnerPtrList& lst, const QString& type ) const
+{
+  lst.clear();
+
+  for ( SelectorListIterator it( mySelectors ); it.current(); ++it )
+  {
+    if ( !type.isEmpty() && it.current()->type() != type )
+      continue;
+    SUIT_DataOwnerPtrList curList;
+    it.current()->selected( curList );
+    for ( SUIT_DataOwnerPtrList::const_iterator itr = curList.begin(); itr != curList.end(); ++itr )
+      lst.append( *itr );
+  }
+}
+
+/*! Sets selected data owners from \a lst and append to list, if \a append - true.
+*/
+void SUIT_SelectionMgr::setSelected( const SUIT_DataOwnerPtrList& lst, const bool append )
+{
+  SUIT_DataOwnerPtrList owners;
+  filterOwners( lst, owners );
+
+  for ( SelectorListIterator it( mySelectors ); it.current(); ++it )
+  {
+    if ( append )
+    {
+      SUIT_DataOwnerPtrList current;
+      it.current()->selected( current );
+      for ( SUIT_DataOwnerPtrList::const_iterator it = current.begin(); it != current.end(); ++it )
+        owners.append( *it );
+    }
+    it.current()->setSelected( owners );
+  }
+}
+
+/*! Clear selected data owners.
+*/
+void SUIT_SelectionMgr::clearSelected()
+{
+  setSelected( SUIT_DataOwnerPtrList() );
+}
+
+/*! On selection \a sel changed.
+*/
+void SUIT_SelectionMgr::selectionChanged( SUIT_Selector* sel )
+{
+  if ( !sel || !myIsSelChangeEnabled || !sel->isEnabled() )
+    return;
+
+  SUIT_DataOwnerPtrList owners;
+
+  myIsSelChangeEnabled = false;
+  sel->selected( owners );
+
+  SUIT_DataOwnerPtrList newOwners;
+  filterOwners( owners, newOwners );
+
+  for ( int i = 0; i < myIterations; i++ )
+  {
+    for ( SUIT_Selector* aSel = mySelectors.first(); aSel; aSel = mySelectors.next() )
+    {
+      // Temporary action(to avoid selection of the objects which don't pass the filters):
+      //if ( aSel != sel )
+           aSel->setSelected( newOwners );
+    }
+  }
+  myIsSelChangeEnabled = true;
+
+  emit selectionChanged();
+}
+
+/*!
+  Returns true if selection manger is in synchronising mode
+  (during synchonisation of the selectors selection).
+*/
+bool SUIT_SelectionMgr::isSynchronizing() const
+{
+  return !myIsSelChangeEnabled;
+}
+
+/*! Checks: Is selection manager has selection mode \a mode?
+*/
+bool SUIT_SelectionMgr::hasSelectionMode( const int mode ) const
+{
+  return mySelModes.contains( mode );
+}
+
+/*! Gets selection modes to list \a vals.
+*/
+void SUIT_SelectionMgr::selectionModes( QValueList<int>& vals ) const
+{
+  vals = mySelModes;
+}
+
+/*! Set selection mode \a mode to list of selection modes.
+*/
+void SUIT_SelectionMgr::setSelectionModes( const int mode )
+{
+  QValueList<int> lst;
+  lst.append( mode );
+  setSelectionModes( lst );
+}
+
+/*! Sets selection modes list from \a lst.
+*/
+void SUIT_SelectionMgr::setSelectionModes( const QValueList<int>& lst )
+{
+  mySelModes = lst;
+}
+
+/*! Append selection mode \a mode to list of selection modes.
+*/
+void SUIT_SelectionMgr::appendSelectionModes( const int mode )
+{
+  QValueList<int> lst;
+  lst.append( mode );
+  appendSelectionModes( lst );
+}
+
+/*! Append selection modes \a lst list.
+*/
+void SUIT_SelectionMgr::appendSelectionModes( const QValueList<int>& lst )
+{
+  QMap<int, int> map;
+  for ( QValueList<int>::const_iterator it = mySelModes.begin(); it != mySelModes.end(); ++it )
+    map.insert( *it, 0 );
+
+  for ( QValueList<int>::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
+  {
+    if ( !map.contains( *itr ) )
+      mySelModes.append( *itr );
+  }
+}
+
+/*! Remove selection mode \a mode from list.
+*/
+void SUIT_SelectionMgr::removeSelectionModes( const int mode )
+{
+  QValueList<int> lst;
+  lst.append( mode );
+  removeSelectionModes( lst );
+}
+
+/*! Remove selection modea \a lst from list.
+*/
+void SUIT_SelectionMgr::removeSelectionModes( const QValueList<int>& lst )
+{
+  QMap<int, int> map;
+  for ( QValueList<int>::const_iterator it = mySelModes.begin(); it != mySelModes.end(); ++it )
+    map.insert( *it, 0 );
+
+  for ( QValueList<int>::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
+    map.remove( *itr );
+
+  mySelModes.clear();
+  for ( QMap<int, int>::ConstIterator iter = map.begin(); iter != map.end(); ++iter )
+    mySelModes.append( iter.key() );
+}
+
+/*! Checks data owner is ok?
+*/
+bool SUIT_SelectionMgr::isOk( const SUIT_DataOwner* owner ) const
+{
+  if ( !owner )
+    return false;
+
+  bool ok = true;
+  for ( SelFilterListIterator it( myFilters ); it.current() && ok; ++it )
+    ok = it.current()->isOk( owner );
+
+  return ok;
+}
+
+/*! Checks data owner pointer is ok?
+*/
+bool SUIT_SelectionMgr::isOk( const SUIT_DataOwnerPtr& ptr ) const
+{
+  if ( ptr.isNull() )
+    return false;
+
+  return isOk( ptr.operator->() );
+}
+
+/*! Checks selection manager has filter \a f?
+*/
+bool SUIT_SelectionMgr::hasFilter( SUIT_SelectionFilter* f ) const
+{
+  return myFilters.contains( f );
+}
+
+/*! Install filter \a f and set selected, if \a update = true.
+*/
+void SUIT_SelectionMgr::installFilter( SUIT_SelectionFilter* f, const bool updateSelection )
+{
+  if ( !hasFilter( f ) )
+  {
+    SUIT_DataOwnerPtrList selOwners;
+    if( updateSelection )
+      selected( selOwners );
+      
+    myFilters.append( f );
+    
+    if( updateSelection )
+      setSelected( selOwners );
+  }
+}
+
+/*! Remove filter \a f from filters list.
+*/
+void SUIT_SelectionMgr::removeFilter( SUIT_SelectionFilter* f )
+{
+  myFilters.remove( f );
+}
+
+/*! Clear filters list.
+*/
+void SUIT_SelectionMgr::clearFilters()
+{
+  myFilters.clear();
+}
+
+/*! Sets auto delete filter.
+*/
+bool SUIT_SelectionMgr::autoDeleteFilter() const
+{
+  return myFilters.autoDelete();
+}
+
+/*! Sets auto delete filter to \a on.
+*/
+void SUIT_SelectionMgr::setAutoDeleteFilter( const bool on )
+{
+  myFilters.setAutoDelete( on );
+}
+
+/*! Gets good data owners list to \a out from \a in.
+*/
+void SUIT_SelectionMgr::filterOwners( const SUIT_DataOwnerPtrList& in, SUIT_DataOwnerPtrList& out ) const
+{
+  out.clear();
+  for ( SUIT_DataOwnerPtrList::const_iterator it = in.begin(); it != in.end(); ++it )
+  {
+    if ( isOk( *it ) )
+      out.append( *it );
+  }
+}
diff --git a/src/SUIT/SUIT_SelectionMgr.h b/src/SUIT/SUIT_SelectionMgr.h
new file mode 100755 (executable)
index 0000000..d471b2f
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef SUIT_SELECTIONMGR_H
+#define SUIT_SELECTIONMGR_H
+
+#include "SUIT_Selector.h"
+#include "SUIT_DataOwner.h"
+#include "SUIT_SelectionFilter.h"
+
+#include <qobject.h>
+#include <qptrlist.h>
+#include <qvaluelist.h>
+
+#ifdef WIN32
+#pragma warning ( disable : 4251 )
+#endif
+
+class SUIT_EXPORT SUIT_SelectionMgr : public QObject
+{
+  Q_OBJECT
+
+public:
+  SUIT_SelectionMgr( const bool = true, QObject* = 0 );
+  virtual ~SUIT_SelectionMgr();
+
+  void            clearSelected();
+  virtual void    selected( SUIT_DataOwnerPtrList&, const QString& = QString::null ) const;
+  virtual void    setSelected( const SUIT_DataOwnerPtrList&, const bool = false );
+
+  void            selectors( QPtrList<SUIT_Selector>& ) const;
+  void            selectors( const QString&, QPtrList<SUIT_Selector>& ) const;
+
+
+  void            setEnabled( const bool, const QString& = QString::null );
+
+
+  bool            hasSelectionMode( const int ) const;
+  void            selectionModes( QValueList<int>& ) const;
+
+  void            setSelectionModes( const int );
+  virtual void    setSelectionModes( const QValueList<int>& );
+
+  void            appendSelectionModes( const int );
+  virtual void    appendSelectionModes( const QValueList<int>& );
+
+  void            removeSelectionModes( const int );
+  virtual void    removeSelectionModes( const QValueList<int>& );
+
+
+  bool            isOk( const SUIT_DataOwner* ) const;
+  bool            isOk( const SUIT_DataOwnerPtr& ) const;
+
+  bool            hasFilter( SUIT_SelectionFilter* ) const;
+
+  virtual void    installFilter( SUIT_SelectionFilter*, const bool = true );
+  virtual void    removeFilter( SUIT_SelectionFilter* );
+  virtual void    clearFilters();
+
+  bool            autoDeleteFilter() const;
+  void            setAutoDeleteFilter( const bool );
+
+  bool            isSynchronizing() const;
+
+signals:
+  void            selectionChanged();
+
+protected:
+  virtual void    selectionChanged( SUIT_Selector* );
+
+  typedef QPtrListIterator<SUIT_Selector>        SelectorListIterator;
+
+  virtual void    installSelector( SUIT_Selector* );
+  virtual void    removeSelector( SUIT_Selector* );
+
+private:
+  void            filterOwners( const SUIT_DataOwnerPtrList&, SUIT_DataOwnerPtrList& ) const;
+
+  typedef QPtrList<SUIT_Selector>                SelectorList;
+  typedef QPtrList<SUIT_SelectionFilter>         SelFilterList;
+  typedef QPtrListIterator<SUIT_SelectionFilter> SelFilterListIterator;
+
+protected:
+  SelectorList    mySelectors;
+
+private:
+  SelFilterList   myFilters;
+  QValueList<int> mySelModes;
+  int             myIterations;
+  bool            myIsSelChangeEnabled;
+
+  friend class SUIT_Selector;
+};
+
+#ifdef WIN32
+#pragma warning ( default : 4251 )
+#endif
+
+#endif
diff --git a/src/SUIT/SUIT_ViewWindow.cxx b/src/SUIT/SUIT_ViewWindow.cxx
new file mode 100755 (executable)
index 0000000..bd4c32e
--- /dev/null
@@ -0,0 +1,160 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// SUIT_ViewWindow.cxx: implementation of the SUIT_ViewWindow class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "SUIT_ViewWindow.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_Application.h"
+#include "SUIT_Study.h"
+#include "SUIT_ViewManager.h"
+#include "SUIT_Tools.h"
+#include "SUIT_MessageBox.h"
+#include <qhbox.h>
+#include <qpopupmenu.h>
+#include <qapplication.h>
+#include <qimage.h>
+
+/*!\class SUIT_ViewWindow
+ * Class provide view window.
+ */
+
+/*! Dump view custom event*/
+const int DUMP_EVENT = QEvent::User + 123;
+
+/*! Constructor.*/
+SUIT_ViewWindow::SUIT_ViewWindow(SUIT_Desktop* theDesktop)
+: QMainWindow( theDesktop, "SUIT_ViewWindow", Qt::WDestructiveClose )
+{
+  myDesktop = theDesktop;
+
+  if ( myDesktop->icon() )
+    setIcon( *myDesktop->icon() );
+}
+
+/*! Destructor.*/
+SUIT_ViewWindow::~SUIT_ViewWindow()
+{
+}
+
+void SUIT_ViewWindow::setViewManager( SUIT_ViewManager* theManager )
+{
+  myManager = theManager;
+}
+
+SUIT_ViewManager* SUIT_ViewWindow::getViewManager() const
+{
+  return myManager;
+}
+
+QImage SUIT_ViewWindow::dumpView()
+{
+  return QImage();
+}
+
+bool SUIT_ViewWindow::dumpViewToFormat( const QString& fileName, const QString& format )
+{
+  QImage img = dumpView();
+  if( img.isNull() )
+    return false; 
+
+  QString fmt = format;
+  if( fmt.isEmpty() )
+    fmt = QString( "BMP" ); // default format
+  else if( fmt == "JPG" )
+    fmt = "JPEG";
+
+  QApplication::setOverrideCursor( Qt::waitCursor );
+  bool res = img.save( fileName, fmt.latin1() );
+  QApplication::restoreOverrideCursor();
+  return res;
+}
+
+/*! Close event \a theEvent.
+*/
+void SUIT_ViewWindow::closeEvent(QCloseEvent* theEvent)
+{
+  QMainWindow::closeEvent( theEvent );
+  emit closing( this );
+}
+
+/*! Context menu requested for event \a e.
+*/
+void SUIT_ViewWindow::contextMenuEvent ( QContextMenuEvent * e )
+{
+  if ( e->reason() != QContextMenuEvent::Mouse )
+    emit contextMenuRequested( e );
+}
+
+/*! Post events on dump view.
+*/
+void SUIT_ViewWindow::onDumpView()
+{
+  qApp->postEvent( this, new QPaintEvent( QRect( 0, 0, width(), height() ), TRUE ) );
+  qApp->postEvent( this, new QCustomEvent( DUMP_EVENT ) );
+}
+
+QString SUIT_ViewWindow::filter() const
+{
+  return tr( "TLT_IMAGE_FILES" );
+}
+
+/*! Reaction view window on event \a e.
+*/
+bool SUIT_ViewWindow::event( QEvent* e )
+{
+  if ( e->type() == DUMP_EVENT )
+  {
+    bool bOk = false;
+    if ( myManager && myManager->study() && myManager->study()->application() )
+    {
+      // get file name
+      SUIT_Application* app = myManager->study()->application();
+      QString fileName = app->getFileName( false, QString::null, filter(), tr( "TLT_DUMP_VIEW" ), 0 );
+      if( !fileName.isEmpty() )
+      {
+       QString fmt = SUIT_Tools::extension( fileName ).upper();
+       bOk = dumpViewToFormat( fileName, fmt );
+      }
+      else
+      {
+       bOk = true; // cancelled
+      }
+    }
+    if ( !bOk ) {
+      SUIT_MessageBox::error1( this, tr( "ERROR" ), tr( "ERR_CANT_DUMP_VIEW" ), tr( "BUT_OK" ) );
+    }
+    return TRUE;
+  }
+  return QMainWindow::event( e );
+}
+
+/*! Called by SUIT_Accel::onActivated() when a key accelerator was activated and this window was active
+*/
+void SUIT_ViewWindow::onAccelAction( int _action )
+{
+  action( _action );
+}
+
+/*! action  handle standard action (zoom, pan) or custom action.  to be redefined in successors.
+*/
+void SUIT_ViewWindow::action( const int  )
+{
+}
diff --git a/src/SUIT/SUIT_ViewWindow.h b/src/SUIT/SUIT_ViewWindow.h
new file mode 100755 (executable)
index 0000000..1ac79a5
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+// SUIT_ViewWindow.h: interface for the SUIT_ViewWindow class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_SUIT_VIEWWINDOW_H__82C3D51A_6F10_45B0_BCFE_3CB3EF596A4D__INCLUDED_)
+#define AFX_SUIT_VIEWWINDOW_H__82C3D51A_6F10_45B0_BCFE_3CB3EF596A4D__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "SUIT.h"
+
+#include <qmainwindow.h>
+
+class SUIT_Desktop;
+class SUIT_ViewManager;
+class QImage;
+
+class SUIT_EXPORT SUIT_ViewWindow: public QMainWindow 
+{
+  Q_OBJECT
+public:
+  SUIT_ViewWindow( SUIT_Desktop* );
+  virtual ~SUIT_ViewWindow();
+
+  void              setViewManager( SUIT_ViewManager* );
+  SUIT_ViewManager* getViewManager() const;
+
+  bool              event(QEvent*);
+
+  virtual QImage    dumpView();
+  virtual bool      dumpViewToFormat( const QString& fileName, const QString& format );
+
+  void              onAccelAction( int );
+
+public slots:
+  virtual void      onDumpView();
+
+signals:
+  void              closing( SUIT_ViewWindow* );
+  void              mousePressed( SUIT_ViewWindow*, QMouseEvent* );
+  void              mouseReleased( SUIT_ViewWindow*, QMouseEvent* );
+  void              mouseDoubleClicked( SUIT_ViewWindow*, QMouseEvent* );
+  void              mouseMoving( SUIT_ViewWindow*, QMouseEvent* );
+  void              wheeling( SUIT_ViewWindow*, QWheelEvent* );
+  void              keyPressed( SUIT_ViewWindow*, QKeyEvent* );
+  void              keyReleased( SUIT_ViewWindow*, QKeyEvent* );
+  void              contextMenuRequested( QContextMenuEvent *e );
+
+protected:
+  void              closeEvent( QCloseEvent* );
+  virtual void      contextMenuEvent( QContextMenuEvent* );
+  virtual QString   filter() const;
+  virtual void      action( const int );
+
+  SUIT_Desktop*     myDesktop;
+  SUIT_ViewManager* myManager;
+};
+
+#endif // !defined(AFX_SUIT_VIEWWINDOW_H__82C3D51A_6F10_45B0_BCFE_3CB3EF596A4D__INCLUDED_)
diff --git a/src/SUITApp/SUITApp.cxx b/src/SUITApp/SUITApp.cxx
new file mode 100644 (file)
index 0000000..4979067
--- /dev/null
@@ -0,0 +1,174 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#if defined WNT
+
+#undef SUIT_ENABLE_PYTHON
+//#else
+//#include "SUITconfig.h"
+#endif
+
+#include "SUITApp_Application.h"
+
+#include <SUIT_Session.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_ResourceMgr.h>
+
+
+#ifdef SUIT_ENABLE_PYTHON
+#include <Python.h>
+#endif
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <stdlib.h>
+
+QString salomeVersion()
+{
+  QString path( ::getenv( "GUI_ROOT_DIR" ) );
+  if ( !path.isEmpty() )
+    path += QDir::separator();
+
+  path += QString( "bin/salome/VERSION" );
+
+  QFile vf( path );
+  if ( !vf.open( IO_ReadOnly ) )
+    return QString::null;
+
+  QString line;
+  vf.readLine( line, 1024 );
+  vf.close();
+
+  if ( line.isEmpty() )
+    return QString::null;
+
+  while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
+    line.remove( line.length() - 1, 1 );
+
+  QString ver;
+  int idx = line.findRev( ":" );
+  if ( idx != -1 )
+    ver = line.mid( idx + 1 ).stripWhiteSpace();
+
+  return ver;
+}
+
+
+/* XPM */
+static const char* pixmap_not_found_xpm[] = {
+"16 16 3 1",
+"       c None",
+".      c #000000",
+"+      c #A80000",
+"                ",
+"                ",
+"    .     .     ",
+"   .+.   .+.    ",
+"  .+++. .+++.   ",
+"   .+++.+++.    ",
+"    .+++++.     ",
+"     .+++.      ",
+"    .+++++.     ",
+"   .+++.+++.    ",
+"  .+++. .+++.   ",
+"   .+.   .+.    ",
+"    .     .     ",
+"                ",
+"                ",
+"                "};
+
+class SUITApp_Session: public SUIT_Session
+{
+public:
+  SUITApp_Session( bool theIniFormat ) : SUIT_Session(), myIniFormat ( theIniFormat ) {}
+  virtual ~SUITApp_Session() {}
+
+protected:
+  virtual SUIT_ResourceMgr* createResourceMgr( const QString& appName ) const
+  {
+    SUIT_ResourceMgr* resMgr = 0;
+    if ( myIniFormat )
+    {
+      resMgr = new SUIT_ResourceMgr( appName );
+      resMgr->setCurrentFormat( "ini" );
+    }
+    else
+    {
+      resMgr = new SUIT_ResourceMgr( appName, QString( "%1Config" ) );
+      resMgr->setVersion( salomeVersion() );
+      resMgr->setCurrentFormat( "xml" );
+    }
+
+    if ( resMgr )
+    {
+      static QPixmap defaultPixmap( pixmap_not_found_xpm );
+      resMgr->setDefaultPixmap( defaultPixmap );
+      resMgr->setOption( "translators", QString( "%P_msg_%L.qm|%P_icons.qm|%P_images.qm" ) );
+    }
+    return resMgr;
+  }
+
+private:
+  bool  myIniFormat;
+};
+
+int main( int args, char* argv[] )
+{
+#ifdef SUIT_ENABLE_PYTHON
+  Py_Initialize();
+  PySys_SetArgv( args, argv );
+#endif
+
+  QStringList argList;
+  bool noExceptHandling = false;
+  bool iniFormat = false;
+  for ( int i = 1; i < args /*&& !noExceptHandling*/; i++ )
+  {
+    if ( !strcmp( argv[i], "/noexcepthandling" ) )
+      noExceptHandling = true;
+    else if ( !strcmp( argv[i], "--format=ini") )
+      iniFormat = true;
+    else
+      argList.append( QString( argv[i] ) );
+  }
+
+  SUITApp_Application app( args, argv );
+
+  int result = -1;
+  if ( !argList.isEmpty() )
+  {
+    SUITApp_Session* aSession = new SUITApp_Session( iniFormat );
+    SUIT_Application* theApp = aSession->startApplication( argList.first() );
+    if ( theApp )
+    {
+      if ( !noExceptHandling )
+        app.setHandler( aSession->handler() );
+
+//      if ( !app.mainWidget() )
+//        app.setMainWidget( theApp->desktop() );
+
+      result = app.exec();
+    }
+    delete aSession;
+  }
+
+  return result;
+}
diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx
new file mode 100644 (file)
index 0000000..690b13b
--- /dev/null
@@ -0,0 +1,833 @@
+// File:      SalomeApp_Application.cxx
+// Created:   10/22/2004 3:23:45 PM
+// Author:    Sergey LITONIN
+// Copyright (C) CEA 2004
+
+#include "SalomeApp_PyInterp.h" // WARNING! This include must be the first!
+
+#include "SalomeApp_Application.h"
+
+#include "SalomeApp_Study.h"
+#include "SalomeApp_DataModel.h"
+#include "SalomeApp_DataObject.h"
+#include "SalomeApp_EventFilter.h"
+
+#include "SalomeApp_StudyPropertiesDlg.h"
+
+#include "SalomeApp_CheckFileDlg.h"
+
+#include "LightApp_Application.h"
+#include "LightApp_Preferences.h"
+#include "LightApp_WidgetContainer.h"
+#include "LightApp_SelectionMgr.h"
+
+#include "STD_LoadStudiesDlg.h"
+
+#include <SUIT_Tools.h>
+#include <SUIT_Session.h>
+
+#include <QtxMRUAction.h>
+
+#include <OB_Browser.h>
+#include <OB_ListItem.h>
+
+#include <PythonConsole_PyConsole.h>
+
+#include <SUIT_FileDlg.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_ActionOperation.h>
+
+#include <Utils_ORB_INIT.hxx>
+#include <Utils_SINGLETON.hxx>
+#include <SALOME_ModuleCatalog_impl.hxx>
+#include <SALOME_LifeCycleCORBA.hxx>
+
+#include <qmap.h>
+#include <qaction.h>
+#include <qcombobox.h>
+#include <qlistbox.h>
+#include <qregexp.h>
+
+#include "SALOMEDS_StudyManager.hxx"
+#include "SALOMEDS_SObject.hxx"
+
+#include "SALOME_ListIteratorOfListIO.hxx"
+#include "SALOME_ListIO.hxx"
+
+#include "ToolsGUI_CatalogGeneratorDlg.h"
+#include "ToolsGUI_RegWidget.h"
+
+/*!Create new instance of SalomeApp_Application.*/
+extern "C" SALOMEAPP_EXPORT SUIT_Application* createApplication()
+{
+  return new SalomeApp_Application();
+}
+
+/*
+  Class       : SalomeApp_Application
+  Description : Application containing SalomeApp module or LightApp module
+*/
+
+/*!Constructor.*/
+SalomeApp_Application::SalomeApp_Application()
+: LightApp_Application()
+{
+}
+
+/*!Destructor.
+ *\li Destroy event filter.
+ */
+SalomeApp_Application::~SalomeApp_Application()
+{
+  // Do not destroy. It's a singleton !
+  //SalomeApp_EventFilter::Destroy();
+}
+
+/*!Start application.*/
+void SalomeApp_Application::start()
+{
+  LightApp_Application::start();
+
+  SalomeApp_EventFilter::Init();
+}
+
+/*!Create actions:*/
+void SalomeApp_Application::createActions()
+{
+  LightApp_Application::createActions();
+
+  SUIT_Desktop* desk = desktop();
+  
+  //! Dump study
+  createAction( DumpStudyId, tr( "TOT_DESK_FILE_DUMP_STUDY" ), QIconSet(),
+               tr( "MEN_DESK_FILE_DUMP_STUDY" ), tr( "PRP_DESK_FILE_DUMP_STUDY" ),
+               CTRL+Key_D, desk, false, this, SLOT( onDumpStudy() ) );
+    
+  //! Load script
+  createAction( LoadScriptId, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), QIconSet(),
+               tr( "MEN_DESK_FILE_LOAD_SCRIPT" ), tr( "PRP_DESK_FILE_LOAD_SCRIPT" ),
+               CTRL+Key_T, desk, false, this, SLOT( onLoadScript() ) );
+
+  //! Properties
+  createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIconSet(),
+               tr( "MEN_DESK_PROPERTIES" ), tr( "PRP_DESK_PROPERTIES" ),
+               CTRL+Key_P, desk, false, this, SLOT( onProperties() ) );
+
+  //! Catalog Generator
+  createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ),  QIconSet(),
+               tr( "MEN_DESK_CATALOG_GENERATOR" ), tr( "PRP_DESK_CATALOG_GENERATOR" ),
+               SHIFT+Key_G, desk, false, this, SLOT( onCatalogGen() ) );
+
+  //! Registry Display
+  createAction( RegDisplayId, tr( "TOT_DESK_REGISTRY_DISPLAY" ),  QIconSet(),
+               tr( "MEN_DESK_REGISTRY_DISPLAY" ), tr( "PRP_DESK_REGISTRY_DISPLAY" ),
+               SHIFT+Key_D, desk, false, this, SLOT( onRegDisplay() ) );
+
+  int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
+
+  createMenu( DumpStudyId, fileMenu, 10, -1 );
+  createMenu( separator(), fileMenu, -1, 15, -1 );
+  createMenu( LoadScriptId, fileMenu, 10, -1 );
+  createMenu( separator(), fileMenu, -1, 15, -1 );
+  createMenu( PropertiesId, fileMenu, 10, -1 );
+  createMenu( separator(), fileMenu, -1, 15, -1 );
+
+  int toolsMenu = createMenu( tr( "MEN_DESK_TOOLS" ), -1, -1, 50 );
+  createMenu( CatalogGenId, toolsMenu, 10, -1 );
+  createMenu( RegDisplayId, toolsMenu, 10, -1 );
+  createMenu( separator(), toolsMenu, -1, 15, -1 );
+}
+
+/*! Purpose : SLOT. Open new document with \a aName.*/
+bool SalomeApp_Application::onOpenDoc( const QString& aName )
+{
+  bool res = false, toOpen = true, isAlreadyOpen = false;
+
+  // Look among opened studies
+  if (activeStudy()) { // at least one study is opened
+    SUIT_Session* aSession = SUIT_Session::session();
+    QPtrList<SUIT_Application> aAppList = aSession->applications();
+    QPtrListIterator<SUIT_Application> it (aAppList);
+    SUIT_Application* aApp = 0;
+    // iterate on all applications
+    for (; (aApp = it.current()) && !isAlreadyOpen; ++it) {
+      if (aApp->activeStudy()->studyName() == aName) {
+        isAlreadyOpen = true; // Already opened, ask user what to do
+
+        // The document ... is already open.
+        // Do you want to reload it?
+        int aAnswer = SUIT_MessageBox::warn2(desktop(), tr("WRN_WARNING"),
+                                             tr("QUE_DOC_ALREADYOPEN").arg(aName),
+                                             tr("BUT_YES"), tr("BUT_NO"), 1, 2, 2);
+        if (aAnswer == 1) { // reload
+          if (activeStudy()->studyName() == aName && aAppList.count() > 1) {
+            // Opened in THIS (active) application.
+            STD_Application* app1 = (STD_Application*)aAppList.at(0);
+            STD_Application* app2 = (STD_Application*)aAppList.at(1);
+            if (!app1 || !app2) {
+              // Error
+              return false;
+            }
+            if (app1->activeStudy()->studyName() == aName) {
+              // app1 is this application, we need another one
+              app1 = app2;
+            }
+            // Close document of this application. This application will be destroyed.
+            onCloseDoc(/*ask = */false);
+            // Open the file with another application, as this one will be destroyed.
+            return app1->onOpenDoc(aName);
+          } else {
+            // Opened in another application.
+            STD_Application* app = (STD_Application*)aApp;
+            if (app)
+              app->onCloseDoc(/*ask = */false);
+          }
+        } else { // do not reload
+          // OK, the study will not be reloaded, but we call
+          // CAM_Application::onOpenDoc( aName ) all the same.
+          // It will activate a desktop of the study <aName>.
+        }
+      }
+    }
+  }
+
+  // Look among unloaded studies
+  if (!isAlreadyOpen) {
+    std::vector<std::string> List = studyMgr()->GetOpenStudies();
+
+    QString studyName;
+    for (unsigned int ind = 0; ind < List.size() && !isAlreadyOpen; ind++) {
+      studyName = List[ind].c_str();
+      if (aName == studyName) {
+        // Already exists unloaded, ask user what to do
+        isAlreadyOpen = true;
+
+        // The document ... already exists in the study manager.
+        // Do you want to reload it?
+        int aAnswer = SUIT_MessageBox::warn2(desktop(), tr("WRN_WARNING"),
+                                             tr("QUE_DOC_ALREADYEXIST").arg(aName),
+                                             tr("BUT_YES"), tr("BUT_NO"), 1, 2, 2);
+        if (aAnswer == 1) {
+          _PTR(Study) aStudy = studyMgr()->GetStudyByName(aName.latin1());
+          if (aStudy)
+            studyMgr()->Close(aStudy);
+        } else {
+          toOpen = false;
+        }
+      }
+    }
+  }
+
+  if (toOpen)
+    res = CAM_Application::onOpenDoc( aName );
+
+  QAction* a = action( MRUId );
+  if ( a && a->inherits( "QtxMRUAction" ) )
+  {
+    QtxMRUAction* mru = (QtxMRUAction*)a;
+    if ( res )
+      mru->insert( aName );
+    else
+      mru->remove( aName );
+  }
+  return res;
+}
+
+/*!SLOT. Load document.*/
+void SalomeApp_Application::onLoadDoc()
+{
+  QString name, studyname, ext;
+
+  STD_LoadStudiesDlg aDlg( desktop(), TRUE);
+
+  std::vector<std::string> List = studyMgr()->GetOpenStudies();
+
+  SUIT_Session* aSession = SUIT_Session::session();
+  QPtrList<SUIT_Application> aAppList = aSession->applications();
+  SUIT_Application* aApp = 0;
+
+  for (unsigned int ind = 0; ind < List.size(); ind++) {
+     studyname = List[ind].c_str();
+     //Add to list only unloaded studies
+     bool isAlreadyOpen = false;
+     for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
+       {
+        aApp = it.current();
+        if(!aApp || !aApp->activeStudy()) continue;
+        if ( aApp->activeStudy()->studyName() == studyname ) isAlreadyOpen = true;
+       }
+
+     if ( !isAlreadyOpen ) aDlg.ListComponent->insertItem( studyname );
+  }
+
+  int retVal = aDlg.exec();
+  studyname = aDlg.ListComponent->currentText();
+
+  if (retVal == QDialog::Rejected)
+    return;
+
+  if ( studyname.isNull() || studyname.isEmpty() )
+    return;
+
+  name = studyname;
+  name.replace( QRegExp(":"), "/" );
+
+  if( LightApp_Application::onLoadDoc( name ) )
+  {
+     updateWindows();
+     updateViewManagers();
+     updateObjectBrowser(true);
+  }
+}
+
+
+/*!SLOT. Load document with \a aName.*/
+bool SalomeApp_Application::onLoadDoc( const QString& aName )
+{
+  return LightApp_Application::onLoadDoc( aName );
+}
+
+/*!SLOT. Copy objects to study maneger from selection maneger..*/
+void SalomeApp_Application::onCopy()
+{
+  SALOME_ListIO list;
+  LightApp_SelectionMgr* mgr = selectionMgr();
+  mgr->selectedObjects(list);
+  
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
+  if(study == NULL) return;
+  
+  _PTR(Study) stdDS = study->studyDS();
+  if(!stdDS) return;
+
+  SALOME_ListIteratorOfListIO it( list );
+  if(it.More())
+    {
+      _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
+      try {
+       studyMgr()->Copy(so);
+       onSelectionChanged();
+      }
+      catch(...) {
+      }
+    }
+}
+
+/*!SLOT. Paste objects to study maneger from selection manager.*/
+void SalomeApp_Application::onPaste()
+{
+  SALOME_ListIO list;
+  LightApp_SelectionMgr* mgr = selectionMgr();
+  mgr->selectedObjects(list);
+
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
+  if(study == NULL) return;
+
+  _PTR(Study) stdDS = study->studyDS();
+  if(!stdDS) return;
+
+  SALOME_ListIteratorOfListIO it( list );
+  if(it.More())
+    {
+      _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
+      try {
+       studyMgr()->Paste(so);
+       updateObjectBrowser( true );
+       updateActions(); //SRN: BugID IPAL9377, case 3
+      }
+      catch(...) {
+      }
+    }
+}
+
+/*!Sets enable or disable some actions on selection changed.*/
+void SalomeApp_Application::onSelectionChanged()
+{
+   SALOME_ListIO list;
+   LightApp_SelectionMgr* mgr = selectionMgr();
+   mgr->selectedObjects(list);
+
+   bool canCopy  = false;
+   bool canPaste = false;
+
+   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
+   if (study != NULL) {
+     _PTR(Study) stdDS = study->studyDS();
+
+     if (stdDS) {
+       SALOME_ListIteratorOfListIO it ( list );
+
+       if (it.More() && list.Extent() == 1) {
+         _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
+
+         if ( so ) {
+           SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(so.get());
+
+           if ( aSO ) {
+             canCopy = studyMgr()->CanCopy(so);
+             canPaste = studyMgr()->CanPaste(so);
+           }
+         }
+       }
+     }
+   }
+
+   action(EditCopyId)->setEnabled(canCopy);
+   action(EditPasteId)->setEnabled(canPaste);
+}
+
+/*!Delete references.*/
+void SalomeApp_Application::onDeleteInvalidReferences()
+{
+  SALOME_ListIO aList;
+  LightApp_SelectionMgr* mgr = selectionMgr();
+  mgr->selectedObjects( aList, QString::null, false );
+
+  if( aList.IsEmpty() )
+    return;
+
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
+  _PTR(Study) aStudyDS = aStudy->studyDS();
+  _PTR(StudyBuilder) aStudyBuilder = aStudyDS->NewBuilder();
+  _PTR(SObject) anObj;
+
+  for( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
+    if ( it.Value()->hasEntry() )
+    {
+      _PTR(SObject) aSObject = aStudyDS->FindObjectID( it.Value()->getEntry() ), aRefObj = aSObject;
+      while( aRefObj && aRefObj->ReferencedObject( anObj ) )
+       aRefObj = anObj;
+
+      if( aRefObj && aRefObj!=aSObject && QString( aRefObj->GetName().c_str() ).isEmpty() )
+        aStudyBuilder->RemoveReference( aSObject );
+    }
+  updateObjectBrowser();
+}
+
+/*!Private SLOT. */
+void SalomeApp_Application::onOpenWith()
+{
+  QApplication::setOverrideCursor( Qt::waitCursor );
+  SALOME_ListIO aList;
+  LightApp_SelectionMgr* mgr = selectionMgr();
+  mgr->selectedObjects(aList);
+  if (aList.Extent() != 1)
+    {
+      QApplication::restoreOverrideCursor();
+      return;
+    }
+  Handle(SALOME_InteractiveObject) aIObj = aList.First();
+  QString aModuleName(aIObj->getComponentDataType());
+  QString aModuleTitle = moduleTitle(aModuleName);
+  activateModule(aModuleTitle);
+  QApplication::restoreOverrideCursor();
+}
+
+//=======================================================================
+// name    : createNewStudy
+/*! Purpose : Create new study*/
+//=======================================================================
+SUIT_Study* SalomeApp_Application::createNewStudy()
+{
+  SalomeApp_Study* aStudy = new SalomeApp_Study( this );
+
+  // Set up processing of major study-related events
+  connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
+  connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
+  connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
+  connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
+
+  return aStudy;
+}
+
+//=======================================================================
+// name    : updateCommandsStatus
+/*! Purpose : Enable/Disable menu items and toolbar buttons. Rebuild menu*/
+//=======================================================================
+void SalomeApp_Application::updateCommandsStatus()
+{
+  LightApp_Application::updateCommandsStatus();
+
+  // Dump study menu
+  QAction* a = action( DumpStudyId );
+  if ( a )
+    a->setEnabled( activeStudy() );
+
+  // Load script menu
+  a = action( LoadScriptId );
+  if ( a )
+    a->setEnabled( activeStudy() );
+
+  a = action( PropertiesId );
+  if( a )
+    a->setEnabled( activeStudy() );
+
+  // update state of Copy/Paste menu items
+  onSelectionChanged();
+}
+
+/*!Private SLOT. On dump study.*/
+void SalomeApp_Application::onDumpStudy( )
+{
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
+  if ( !appStudy ) return;
+  _PTR(Study) aStudy = appStudy->studyDS();
+
+  QStringList aFilters;
+  aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
+
+  SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( desktop(), false, tr("PUBLISH_IN_STUDY"), true, true);
+  fd->setCaption( tr( "TOT_DESK_FILE_DUMP_STUDY" ) );
+  fd->setFilters( aFilters );
+  fd->SetChecked(true);
+  fd->exec();
+  QString aFileName = fd->selectedFile();
+  bool toPublish = fd->IsChecked();
+  delete fd;
+
+  if(!aFileName.isEmpty()) {
+    QFileInfo aFileInfo(aFileName);
+    bool res = aStudy->DumpStudy( aFileInfo.dirPath( true ).latin1(), aFileInfo.baseName().latin1(), toPublish );
+    if ( !res )
+    SUIT_MessageBox::warn1 ( desktop(),
+                            QObject::tr("WRN_WARNING"),
+                            tr("WRN_DUMP_STUDY_FAILED"),
+                            QObject::tr("BUT_OK") );
+  }
+}
+
+/*!Private SLOT. On load script.*/
+void SalomeApp_Application::onLoadScript( )
+{
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
+  if ( !appStudy ) return;
+  _PTR(Study) aStudy = appStudy->studyDS();
+
+  if ( aStudy->GetProperties()->IsLocked() ) {
+    SUIT_MessageBox::warn1 ( desktop(),
+                            QObject::tr("WRN_WARNING"),
+                            QObject::tr("WRN_STUDY_LOCKED"),
+                            QObject::tr("BUT_OK") );
+    return;
+  }
+
+  QStringList filtersList;
+  filtersList.append(tr("PYTHON_FILES_FILTER"));
+  filtersList.append(tr("ALL_FILES_FILTER"));
+
+  QString aFile = SUIT_FileDlg::getFileName( desktop(), "", filtersList, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), true, true );
+
+  if ( !aFile.isEmpty() )
+  {
+    QString command = QString("execfile(\"%1\")").arg(aFile);
+
+    PythonConsole* pyConsole = pythonConsole();
+
+    if ( pyConsole )
+      pyConsole->exec( command );
+  }
+}
+
+/*!Gets file filter.
+ *\retval QString "(*.hdf)"
+ */
+QString SalomeApp_Application::getFileFilter() const
+{
+  return "(*.hdf)";
+}
+
+/*!Create window.*/
+QWidget* SalomeApp_Application::createWindow( const int flag )
+{
+  QWidget* wid = 0;
+  if ( flag != WT_PyConsole ) wid = LightApp_Application::createWindow(flag);
+
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+
+  if ( flag == WT_ObjectBrowser )
+  {
+    OB_Browser* ob = (OB_Browser*)wid;
+    connect( ob->listView(), SIGNAL( doubleClicked( QListViewItem* ) ), this, SLOT( onDblClick( QListViewItem* ) ) );
+    bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false ),
+         autoSizeFirst = resMgr->booleanValue( "ObjectBrowser", "auto_size_first", true );
+    for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
+    {
+      ob->addColumn( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), i );
+      ob->setColumnShown( i, resMgr->booleanValue( "ObjectBrowser",
+                                                   QString().sprintf( "visibility_column_%d", i ), true ) );
+    }
+    ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
+    ob->listView()->setColumnWidthMode( 0, autoSizeFirst ? QListView::Maximum : QListView::Manual );
+    ob->resize( desktop()->width()/3, ob->height() );
+  }
+  else if ( flag == WT_PyConsole )
+  {
+    PythonConsole* pyCons = new PythonConsole( desktop(), new SalomeApp_PyInterp() );
+    pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
+    wid = pyCons;
+    pyCons->resize( pyCons->width(), desktop()->height()/4 );
+    //pyCons->connectPopupRequest(this, SLOT(onConnectPopupRequest(SUIT_PopupClient*, QContextMenuEvent*)));
+  }
+  return wid;
+}
+
+/*!Create preferences.*/
+void SalomeApp_Application::createPreferences( LightApp_Preferences* pref )
+{
+  LightApp_Application::createPreferences(pref);
+
+  if ( !pref )
+    return;
+
+  int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
+  int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
+  int defCols = pref->addPreference( tr( "PREF_GROUP_DEF_COLUMNS" ), obTab );
+  for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
+  {
+    pref->addPreference( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), defCols,
+                         LightApp_Preferences::Bool, "ObjectBrowser", QString().sprintf( "visibility_column_%d", i ) );
+  }
+  pref->setItemProperty( defCols, "columns", 1 );
+}
+
+/*!Update desktop title.*/
+void SalomeApp_Application::updateDesktopTitle() {
+  QString aTitle = applicationName();
+  QString aVer = applicationVersion();
+  if ( !aVer.isEmpty() )
+    aTitle += QString( " " ) + aVer;
+
+  if ( activeStudy() )
+  {
+    QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
+    if ( !sName.isEmpty() ) {
+      SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
+      if ( study ) {
+        _PTR(Study) stdDS = study->studyDS();
+        if(stdDS) {
+         if ( stdDS->GetProperties()->IsLocked() ) {
+           aTitle += QString( " - [%1 (%2)]").arg( sName ).arg( tr( "STUDY_LOCKED" ) );
+         } else {
+           aTitle += QString( " - [%1]" ).arg( sName );
+         }
+        }
+      }
+    }
+  }
+
+  desktop()->setCaption( aTitle );
+}
+
+/*!Gets CORBA::ORB_var*/
+CORBA::ORB_var SalomeApp_Application::orb()
+{
+  ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
+  static CORBA::ORB_var _orb = init( qApp->argc(), qApp->argv() );
+  return _orb;
+}
+
+/*!Create and return SALOMEDS_StudyManager.*/
+SALOMEDSClient_StudyManager* SalomeApp_Application::studyMgr()
+{
+  static SALOMEDSClient_StudyManager* _sm = new SALOMEDS_StudyManager();
+  return _sm;
+}
+
+/*!Create and return SALOME_NamingService.*/
+SALOME_NamingService* SalomeApp_Application::namingService()
+{
+  static SALOME_NamingService* _ns = new SALOME_NamingService( orb() );
+  return _ns;
+}
+
+/*!Create and return SALOME_LifeCycleCORBA.*/
+SALOME_LifeCycleCORBA* SalomeApp_Application::lcc()
+{
+  static SALOME_LifeCycleCORBA* _lcc = new SALOME_LifeCycleCORBA( namingService() );
+  return _lcc;
+}
+
+/*!Return default engine IOR for light modules*/
+QString SalomeApp_Application::defaultEngineIOR()
+{
+  /// Look for a default module engine (needed for CORBAless modules to use SALOMEDS persistence)
+  QString anIOR( "" );
+  CORBA::Object_ptr anEngine = namingService()->Resolve( "/SalomeAppEngine" );
+  if ( !CORBA::is_nil( anEngine ) )
+    anIOR = orb()->object_to_string( anEngine );
+  return anIOR;
+}
+
+/*!Private SLOT. On preferences.*/
+void SalomeApp_Application::onProperties()
+{
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
+  if( !study )
+    return;
+
+  _PTR(StudyBuilder) SB = study->studyDS()->NewBuilder();
+  SB->NewCommand();
+
+  SalomeApp_StudyPropertiesDlg aDlg( desktop() );
+  int res = aDlg.exec();
+  if( res==QDialog::Accepted && aDlg.isChanged() )
+    SB->CommitCommand();
+  else
+    SB->AbortCommand();
+
+  //study->updateCaptions();
+  updateDesktopTitle();
+  updateActions();
+}
+
+/*!Insert items in popup, which necessary for current application*/
+void SalomeApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
+{
+  LightApp_Application::contextMenuPopup( type, thePopup, title );
+
+  OB_Browser* ob = objectBrowser();
+  if ( !ob || type != ob->popupClientType() )
+    return;
+
+  // Get selected objects
+  SALOME_ListIO aList;
+  LightApp_SelectionMgr* mgr = selectionMgr();
+  mgr->selectedObjects( aList, QString::null, false );
+
+  // "Delete reference" item should appear only for invalid references
+
+  // isInvalidRefs will be true, if at least one of selected objects is invalid reference
+  bool isInvalidRefs = false;
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
+  _PTR(Study) aStudyDS = aStudy->studyDS();
+  _PTR(SObject) anObj;
+
+  for( SALOME_ListIteratorOfListIO it( aList ); it.More() && !isInvalidRefs; it.Next() )
+    if( it.Value()->hasEntry() )
+    {
+      _PTR(SObject) aSObject = aStudyDS->FindObjectID( it.Value()->getEntry() ), aRefObj = aSObject;
+      while( aRefObj && aRefObj->ReferencedObject( anObj ) )
+       aRefObj = anObj;
+
+      if( aRefObj && aRefObj!=aSObject && QString( aRefObj->GetName().c_str() ).isEmpty() )
+       isInvalidRefs = true;
+    }
+
+  // Add "Delete reference" item to popup
+  if ( isInvalidRefs )
+  {
+    thePopup->insertSeparator();
+    thePopup->insertItem( tr( "MEN_DELETE_INVALID_REFERENCE" ), this, SLOT( onDeleteInvalidReferences() ) );
+    return;
+  }
+
+  aList.Clear();
+  mgr->selectedObjects( aList );
+
+  // "Activate module" item should appear only if it's necessary
+  if (aList.Extent() != 1)
+    return;
+  Handle(SALOME_InteractiveObject) aIObj = aList.First();
+  QString aModuleName(aIObj->getComponentDataType());
+  QString aModuleTitle = moduleTitle(aModuleName);
+  CAM_Module* currentModule = activeModule();
+  if (currentModule && currentModule->moduleName() == aModuleTitle)
+    return;
+  thePopup->insertItem( tr( "MEN_OPENWITH" ), this, SLOT( onOpenWith() ) );
+}
+
+/*!Update obect browser:
+ 1.if 'updateModels' true, update existing data models;
+ 2. update "non-existing" (not loaded yet) data models;
+ 3. update object browser if it existing */
+void SalomeApp_Application::updateObjectBrowser( const bool updateModels )
+{
+  // update existing data models (already loaded SComponents)
+  LightApp_Application::updateObjectBrowser(updateModels);
+
+  // update "non-existing" (not loaded yet) data models
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
+  if ( study )
+  {
+    _PTR(Study) stdDS = study->studyDS();
+    if( stdDS )
+    {
+      for ( _PTR(SComponentIterator) it ( stdDS->NewComponentIterator() ); it->More(); it->Next() ) 
+      {
+       _PTR(SComponent) aComponent ( it->Value() );
+
+       if ( aComponent->ComponentDataType() == "Interface Applicative" )
+         continue; // skip the magic "Interface Applicative" component
+
+        SalomeApp_DataModel::BuildTree( aComponent, study->root(), study, /*skipExisitng=*/true );
+      }
+    }
+  }
+
+  if ( objectBrowser() )
+  {
+    objectBrowser()->updateGeometry();
+    objectBrowser()->updateTree( 0, false );
+  }
+}
+
+/*!Display Catalog Genenerator dialog */
+void SalomeApp_Application::onCatalogGen()
+{
+  ToolsGUI_CatalogGeneratorDlg aDlg( desktop() );
+  aDlg.exec();
+}
+
+/*!Display Registry Display dialog */
+void SalomeApp_Application::onRegDisplay()
+{
+  CORBA::ORB_var anOrb = orb();
+  ToolsGUI_RegWidget* regWnd = ToolsGUI_RegWidget::GetRegWidget( anOrb, desktop(), "Registry" );
+  regWnd->show();
+  regWnd->raise();
+  regWnd->setActiveWindow();
+}
+
+/*!find original object by double click on item */
+void SalomeApp_Application::onDblClick( QListViewItem* it )
+{
+  OB_ListItem* item = dynamic_cast<OB_ListItem*>( it );
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
+
+  if( study && item )
+  {
+    SalomeApp_DataObject* obj = dynamic_cast<SalomeApp_DataObject*>( item->dataObject() );
+    if( !obj )
+      return;
+
+    QString entry = obj->entry();
+    _PTR(SObject) sobj = study->studyDS()->FindObjectID( entry.latin1() ), ref;
+
+    if( sobj && sobj->ReferencedObject( ref ) )
+    {
+      entry = ref->GetID().c_str();
+      QListViewItemIterator anIt( item->listView() );
+      for( ; anIt.current(); anIt++ )
+      {
+       OB_ListItem* item = dynamic_cast<OB_ListItem*>( anIt.current() );
+       if( !item )
+         continue;
+
+       SalomeApp_DataObject* original = dynamic_cast<SalomeApp_DataObject*>( item->dataObject() );
+       if( original->entry()!=entry )
+         continue;
+
+       OB_Browser* br = objectBrowser();
+       br->setSelected( original );
+       SUIT_DataObject* p = original->parent();
+       while( p )
+       {
+         br->setOpen( p );
+         p = p->parent();
+       }
+       break;
+      }
+    }
+  }
+}
diff --git a/src/SalomeApp/SalomeApp_Application.h b/src/SalomeApp/SalomeApp_Application.h
new file mode 100644 (file)
index 0000000..2462e55
--- /dev/null
@@ -0,0 +1,103 @@
+// File:      SalomeApp_Application.h
+// Created:   10/22/2004 3:37:25 PM
+// Author:    Sergey LITONIN
+// Copyright (C) CEA 2004
+
+#ifndef SALOMEAPP_APPLICATION_H
+#define SALOMEAPP_APPLICATION_H
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "SalomeApp.h"
+#include <LightApp_Application.h>
+
+#include <CORBA.h>
+
+#include <SALOMEconfig.h>
+//#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include <SALOME_NamingService.hxx>
+
+#include "SALOMEDSClient.hxx"
+
+class QAction;
+class QComboBox;
+class QDockWindow;
+
+class LightApp_Preferences;
+class SalomeApp_Module;
+
+class SALOME_LifeCycleCORBA;
+
+class QListViewItem;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+/*!
+  Description : Application containing SalomeApp module or LightApp module
+*/
+
+class SALOMEAPP_EXPORT SalomeApp_Application : public LightApp_Application
+{
+  Q_OBJECT
+
+public:
+  enum { DumpStudyId = LightApp_Application::UserID, LoadScriptId, PropertiesId,
+         CatalogGenId, RegDisplayId, UserID };
+
+public:
+  SalomeApp_Application();
+  virtual ~SalomeApp_Application();
+
+  virtual void                        updateObjectBrowser( const bool = true );
+
+  virtual QString                     getFileFilter() const;
+
+  virtual void                        start();
+
+  virtual void                        contextMenuPopup( const QString&, QPopupMenu*, QString& );
+
+  static CORBA::ORB_var               orb();
+  static SALOMEDSClient_StudyManager* studyMgr();
+  static SALOME_NamingService*        namingService();
+  static SALOME_LifeCycleCORBA*       lcc();
+  static QString                      defaultEngineIOR();
+
+public slots:
+  virtual bool                        onOpenDoc( const QString& );
+  virtual void                        onLoadDoc();
+  virtual bool                        onLoadDoc( const QString& );
+  virtual void                        onCopy();
+  virtual void                        onPaste();
+
+protected:
+  virtual void                        createActions();
+  virtual SUIT_Study*                 createNewStudy();
+  virtual QWidget*                    createWindow( const int );
+
+  virtual void                        updateCommandsStatus();
+  virtual void                        onSelectionChanged();
+
+  virtual void                        createPreferences( LightApp_Preferences* );
+  virtual void                        updateDesktopTitle();
+
+private slots:
+  void                                onDeleteInvalidReferences();
+  void                                onDblClick( QListViewItem* );
+  void                                onProperties();
+  void                                onDumpStudy();
+  void                                onLoadScript(); 
+
+  void                                onCatalogGen();
+  void                                onRegDisplay();
+  void                                onOpenWith();
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/SalomeApp/SalomeApp_DataObject.cxx b/src/SalomeApp/SalomeApp_DataObject.cxx
new file mode 100644 (file)
index 0000000..938754e
--- /dev/null
@@ -0,0 +1,373 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#include "SalomeApp_DataObject.h"
+
+#include "SalomeApp_Study.h"
+#include "LightApp_RootObject.h"
+
+#include <SUIT_Application.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_DataObjectKey.h>
+
+#include <qobject.h>
+
+#include <SALOMEDSClient_AttributeReal.hxx>
+#include <SALOMEDSClient_AttributeInteger.hxx>
+#include <SALOMEDSClient_AttributeComment.hxx>
+#include <SALOMEDSClient_AttributeTableOfReal.hxx>
+#include <SALOMEDSClient_AttributeTableOfInteger.hxx>
+
+/*
+       Class: SalomeApp_DataObject
+       Level: Public
+*/
+/*!Constructor. Initialize by \a parent*/
+SalomeApp_DataObject::SalomeApp_DataObject( SUIT_DataObject* parent )
+: LightApp_DataObject( parent ),
+  CAM_DataObject( parent ),
+  myEntry( "" ),
+  myName( "" )
+{
+}
+
+/*!Constructor. Initialize by \a parent and SObject*/
+SalomeApp_DataObject::SalomeApp_DataObject( const _PTR(SObject)& sobj, SUIT_DataObject* parent )
+: LightApp_DataObject( parent ),
+  CAM_DataObject( parent ),
+  myName( "" )
+{
+  myObject = sobj;
+  myEntry = myObject->GetID().c_str();
+}
+
+/*!Destructor. Do nothing.*/
+SalomeApp_DataObject::~SalomeApp_DataObject()
+{
+}
+
+/*!Gets object ID.
+ *\retval QString
+ */
+QString SalomeApp_DataObject::entry() const
+{
+ if ( myObject )
+    return myObject->GetID().c_str();
+  return QString::null;
+  //return myEntry;
+}
+
+/*!Gets name of object.*/
+QString SalomeApp_DataObject::name() const
+{
+  //if ( myName.isEmpty() )
+  {
+    QString str;
+    if ( myObject )
+      str = myObject->GetName().c_str();
+
+    if ( str.isEmpty() )
+    {
+      _PTR(SObject) refObj = referencedObject();
+      if ( refObj )
+        str = refObj->GetName().c_str();
+    }
+
+    if ( isReference() )
+      {
+        if ( !(QString(referencedObject()->GetName().c_str()).isEmpty()) )
+         str = QString( "* " ) + str;
+        else
+         str = QString( "<Invalid Reference>" );
+      }
+    SalomeApp_DataObject* that = (SalomeApp_DataObject*)this;
+    that->myName = str;
+  }
+  return myName;
+}
+
+/*!Gets icon picture of object.*/
+QPixmap SalomeApp_DataObject::icon() const
+{
+  _PTR(GenericAttribute) anAttr;
+  if ( myObject && myObject->FindAttribute( anAttr, "AttributePixMap" ) ){
+    _PTR(AttributePixMap) aPixAttr ( anAttr );
+    if ( aPixAttr->HasPixMap() ){
+      QString pixmapName = QObject::tr( aPixAttr->GetPixMap().c_str() );
+      LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() );
+      if ( aRoot && aRoot->study() ) {
+       QPixmap pixmap = aRoot->study()->application()->resourceMgr()->loadPixmap( componentDataType(), pixmapName, false ); 
+       return pixmap;
+      }
+    }
+  }
+  return QPixmap();
+}
+
+/*!Gets text value for one of entity:
+ *\li Value           (id = SalomeApp_DataObject::CT_Value)
+ *\li Entry           (id = SalomeApp_DataObject::CT_Entry)
+ *\li IOR             (id = SalomeApp_DataObject::CT_IOR)
+ *\li Reference entry (id = SalomeApp_DataObject::CT_RefEntry)
+ */
+QString SalomeApp_DataObject::text( const int id ) const
+{
+  QString txt;
+  switch ( id )
+  {
+  case CT_Value:
+#ifndef WNT
+    if ( componentObject() != this )
+#else
+    if ( componentObject() != (SUIT_DataObject*)this )
+#endif
+      txt = value( referencedObject() );
+    break;
+  case CT_Entry:
+    txt = entry( object() );
+    break;
+  case CT_IOR:
+    txt = ior( referencedObject() );
+    break;
+  case CT_RefEntry:
+    if ( isReference() )
+      txt = entry( referencedObject() );
+    break;
+  }
+  return txt;
+}
+
+/*!Get color value for one of entity:
+ *\li Text color
+ *\li Highlight color
+ *\li Higlighted text color
+ */
+QColor SalomeApp_DataObject::color( const ColorRole cr ) const
+{
+  QColor clr;
+  switch ( cr )
+  {
+  case Text:
+    if ( isReference() )
+      {
+       if ( !(QString(referencedObject()->GetName().c_str()).isEmpty()) )
+         clr = QColor( 255, 0, 0 );
+       else
+         clr = QColor( 200, 200, 200 );
+      }
+    else if ( myObject )
+    {
+      _PTR(GenericAttribute) anAttr;
+      if ( myObject->FindAttribute( anAttr, "AttributeTextColor" ) )
+      {
+       _PTR(AttributeTextColor) aColAttr = anAttr;
+       clr = QColor( (int)aColAttr->TextColor().R, (int)aColAttr->TextColor().G, (int)aColAttr->TextColor().B );
+      }
+    }
+    break;
+  case Highlight:
+    if ( isReference() )
+      {
+       if ( !(QString(referencedObject()->GetName().c_str()).isEmpty()) )
+         clr = QColor( 255, 0, 0 );
+       else
+         clr = QColor( 200, 200, 200 );
+      }
+    break;
+  case HighlightedText:
+    if ( isReference() )
+      clr = QColor( 255, 255, 255 );
+    break;
+  }
+  return clr;
+}
+
+/*!Gets tooltip.*/
+QString SalomeApp_DataObject::toolTip() const
+{
+  //return object()->Name();
+  return QString( "Object \'%1\', module \'%2\', ID=%3" ).arg( name() ).arg( componentDataType() ).arg( entry() );
+}
+
+/*!Get component type.*/
+QString SalomeApp_DataObject::componentDataType() const
+{
+  //  if ( myCompDataType.isEmpty() ) {
+    const SalomeApp_DataObject* compObj = dynamic_cast<SalomeApp_DataObject*>( componentObject() );
+    if ( compObj && compObj->object() )
+    {
+      _PTR(SComponent) aComp( compObj->object() );
+      if ( aComp ) {
+        SalomeApp_DataObject* that = (SalomeApp_DataObject*)this;
+        that->myCompDataType = aComp->ComponentDataType().c_str();
+      }
+    }
+    //  }
+  return myCompDataType;
+}
+
+/*!Gets object.*/
+_PTR(SObject) SalomeApp_DataObject::object() const
+{
+  return myObject;
+}
+
+/*!Checks: Is object reference.*/
+bool SalomeApp_DataObject::isReference() const
+{
+  bool isRef = false;
+  if ( myObject )
+  {
+    _PTR(SObject) refObj;
+    isRef = myObject->ReferencedObject( refObj );
+  }
+  return isRef;
+}
+
+/*!Gets reference object.*/
+_PTR(SObject) SalomeApp_DataObject::referencedObject() const
+{
+  _PTR(SObject) refObj;
+  _PTR(SObject) obj = myObject;
+  while ( obj && obj->ReferencedObject( refObj ) )
+    obj = refObj;
+
+  return obj;
+}
+
+/*!Gets IOR*/
+QString SalomeApp_DataObject::ior( const _PTR(SObject)& obj ) const
+{
+  QString txt;
+  if ( obj )
+  {
+    _PTR(GenericAttribute) attr;
+    if ( obj->FindAttribute( attr, "AttributeIOR" ) )
+    {
+      _PTR(AttributeIOR) iorAttr = attr;
+      if ( iorAttr )
+      {
+       std::string str = iorAttr->Value();
+       txt = QString( str.c_str() );
+      }
+    }
+  }
+  return txt;
+}
+
+/*!Gets Entry*/
+QString SalomeApp_DataObject::entry( const _PTR(SObject)& obj ) const
+{
+  QString txt;
+  if ( obj )
+  {
+    std::string str = obj->GetID();
+    txt = QString( str.c_str() );
+  }
+  return txt;
+}
+
+/*!Value*/
+QString SalomeApp_DataObject::value( const _PTR(SObject)& obj ) const
+{
+  if ( !obj )
+    return QString::null;
+
+  QString val;
+  _PTR(GenericAttribute) attr;
+
+  if ( obj->FindAttribute( attr, "AttributeInteger" ) )
+  {
+    _PTR(AttributeInteger) intAttr = attr;
+    if ( intAttr )
+      val = QString::number( intAttr->Value() );
+  }
+  else if ( obj->FindAttribute( attr, "AttributeReal" ) )
+  {
+    _PTR(AttributeReal) realAttr = attr;
+    if ( realAttr )
+      val = QString::number( realAttr->Value() );
+  }
+  else if ( obj->FindAttribute( attr, "AttributeTableOfInteger" ) )
+  {
+    _PTR(AttributeTableOfInteger) tableAttr = attr;
+    std::string title = tableAttr->GetTitle();
+    val = QString( title.c_str() );
+    if ( !val.isEmpty() )
+      val += QString( " " );
+    val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
+  }
+  else if ( obj->FindAttribute( attr, "AttributeTableOfReal" ) )
+  {
+    _PTR(AttributeTableOfReal) tableAttr = attr;
+    std::string title = tableAttr->GetTitle();
+    val = QString( title.c_str() );
+    if ( !val.isEmpty() )
+      val += QString( " " );
+    val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
+  }
+  else if ( obj->FindAttribute( attr, "AttributeComment") )
+  {
+    _PTR(AttributeComment) comm = attr;
+    std::string str = comm->Value();
+    val = QString( str.c_str() );
+  }
+
+  return val;
+}
+
+/*
+       Class: SalomeApp_ModuleObject
+       Level: Public
+*/
+
+/*!Constructor.Initialize by \a parent.*/
+SalomeApp_ModuleObject::SalomeApp_ModuleObject( SUIT_DataObject* parent )
+: SalomeApp_DataObject( parent ),
+  CAM_RootObject( parent ),
+  CAM_DataObject( parent )
+{
+}
+
+/*!Constructor.Initialize by \a parent and SObject.*/
+SalomeApp_ModuleObject::SalomeApp_ModuleObject( const _PTR(SObject)& sobj, SUIT_DataObject* parent )
+: SalomeApp_DataObject( sobj, parent ),
+  CAM_RootObject( 0, parent ),
+  CAM_DataObject( parent )
+{
+}
+
+/*!Constructor.Initialize by \a parent and CAM_DataModel.*/
+SalomeApp_ModuleObject::SalomeApp_ModuleObject( CAM_DataModel* dm, const _PTR(SObject)& sobj, SUIT_DataObject* parent )
+: SalomeApp_DataObject( sobj, parent ),
+  CAM_RootObject( dm, parent ),
+  CAM_DataObject( parent )
+{
+}
+
+/*!Destructor. Do nothing.*/
+SalomeApp_ModuleObject::~SalomeApp_ModuleObject()
+{
+}
+
+/*!Returns module name */
+QString SalomeApp_ModuleObject::name() const
+{
+  return SalomeApp_DataObject::name();
+}
+
diff --git a/src/SalomeApp/SalomeApp_DataObject.h b/src/SalomeApp/SalomeApp_DataObject.h
new file mode 100644 (file)
index 0000000..15a1d96
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// 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/
+//
+#ifndef SALOMEAPP_DATAOBJECT_H
+#define SALOMEAPP_DATAOBJECT_H
+
+#include "SalomeApp.h"
+
+#include "LightApp_DataObject.h"
+#include "CAM_RootObject.h"
+
+#include "SALOMEDSClient.hxx"
+
+class SalomeApp_Study;
+
+class SALOMEAPP_EXPORT SalomeApp_DataObject : public LightApp_DataObject
+{
+
+public:
+  enum { CT_Value, CT_Entry, CT_IOR, CT_RefEntry };
+
+public:
+  SalomeApp_DataObject( SUIT_DataObject* = 0 );
+  SalomeApp_DataObject( const _PTR(SObject)&, SUIT_DataObject* = 0 );
+  virtual ~SalomeApp_DataObject();
+    
+  virtual QString                 name() const;
+  virtual QPixmap                 icon() const;
+  virtual QString                 toolTip() const;
+
+  virtual QString                 text( const int ) const;
+  virtual QColor                  color( const ColorRole ) const;
+
+  virtual QString                 entry() const;
+
+  /*! location of corresponding SALOMEDS::SObject  */
+  virtual _PTR(SObject)           object() const;
+
+  bool                            isReference() const;
+  _PTR(SObject)                   referencedObject() const;
+
+  /*! GEOM, SMESH, VISU, etc.*/
+  virtual QString                 componentDataType() const;
+
+private:
+  QString                         ior( const _PTR(SObject)& ) const;
+  QString                         entry( const _PTR(SObject)& ) const;
+  QString                         value( const _PTR(SObject)& ) const;
+
+private:
+  _PTR(SObject)                   myObject;
+  QString                         myEntry;
+  QString                         myName;
+};
+
+/*!
+ * SalomeApp_ModuleObject - class for optimized access to DataModel from
+ * SalomeApp_DataObject instances - see also CAM_RootObject.h
+ */
+
+class SALOMEAPP_EXPORT SalomeApp_ModuleObject : public SalomeApp_DataObject,
+                                                public CAM_RootObject
+{
+public:
+  SalomeApp_ModuleObject( SUIT_DataObject* = 0 );
+  SalomeApp_ModuleObject( const _PTR(SObject)&, SUIT_DataObject* = 0 );
+  SalomeApp_ModuleObject( CAM_DataModel*, const _PTR(SObject)&, SUIT_DataObject* = 0 );
+  virtual ~SalomeApp_ModuleObject();
+
+  virtual QString        name() const;
+};
+
+#endif
diff --git a/src/SalomeApp/SalomeApp_Module.cxx b/src/SalomeApp/SalomeApp_Module.cxx
new file mode 100644 (file)
index 0000000..9284a57
--- /dev/null
@@ -0,0 +1,99 @@
+// File:      SalomeApp_Module.cxx
+// Created:   10/25/2004 11:39:56 AM
+// Author:    Sergey LITONIN
+// Copyright (C) CEA 2004
+
+#include "SalomeApp_Module.h"
+#include "SalomeApp_DataModel.h"
+#include "SalomeApp_Application.h"
+#include "SalomeApp_Study.h"
+
+#include "LightApp_Selection.h"
+#include "LightApp_Operation.h"
+#include "LightApp_Preferences.h"
+
+#include "CAM_DataModel.h"
+
+#include "OB_Browser.h"
+
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
+#include <SALOME_InteractiveObject.hxx>
+
+#include <SUIT_Session.h>
+
+#include <qstring.h>
+#include <qmap.h>
+
+/*!Constructor.*/
+SalomeApp_Module::SalomeApp_Module( const QString& name )
+: LightApp_Module( name )
+{
+}
+
+/*!Destructor.*/
+SalomeApp_Module::~SalomeApp_Module()
+{
+}
+
+/*!Gets application.*/
+SalomeApp_Application* SalomeApp_Module::getApp() const
+{
+  return (SalomeApp_Application*)application();
+}
+
+/*!Create new instance of data model and return it.*/
+CAM_DataModel* SalomeApp_Module::createDataModel()
+{
+  return new SalomeApp_DataModel(this);
+}
+
+/*!Create and return instance of LightApp_Selection.*/
+LightApp_Selection* SalomeApp_Module::createSelection() const
+{
+  return LightApp_Module::createSelection();
+}
+
+void SalomeApp_Module::extractContainers( const SALOME_ListIO& source, SALOME_ListIO& dest ) const
+{
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
+  if( !study )
+  {
+    dest = source;
+    return;
+  }
+
+  SALOME_ListIteratorOfListIO anIt( source );
+  for( ; anIt.More(); anIt.Next() )
+  {
+    Handle( SALOME_InteractiveObject ) obj = anIt.Value();
+    if( obj->hasEntry() )
+    {
+      _PTR(SObject) SO = study->studyDS()->FindObjectID( obj->getEntry() );
+      if( SO && QString( SO->GetID().c_str() ) == SO->GetFatherComponent()->GetID().c_str() )
+      { //component is selected
+       _PTR(SComponent) SC( SO->GetFatherComponent() );
+       _PTR(ChildIterator) anIter ( study->studyDS()->NewChildIterator( SC ) );
+       anIter->InitEx( true );
+       while( anIter->More() )
+       {
+         _PTR(SObject) valSO ( anIter->Value() );
+         _PTR(SObject) refSO;
+         if( !valSO->ReferencedObject( refSO ) )
+         {
+           QString id = valSO->GetID().c_str(),
+                   comp = SC->ComponentDataType().c_str(),
+                   val = valSO->GetName().c_str();
+
+           Handle( SALOME_InteractiveObject ) new_obj =
+             new SALOME_InteractiveObject( id.latin1(), comp.latin1(), val.latin1() );
+           dest.Append( new_obj );
+         }
+         anIter->Next();
+       }
+       continue;
+      }
+    }
+    dest.Append( obj );
+  }
+}
diff --git a/src/SalomeApp/SalomeApp_Module.h b/src/SalomeApp/SalomeApp_Module.h
new file mode 100644 (file)
index 0000000..433d918
--- /dev/null
@@ -0,0 +1,50 @@
+// File:      SalomeApp_Module.h
+// Created:   10/25/2004 11:33:06 AM
+// Author:    Sergey LITONIN
+// Copyright (C) CEA 2004
+
+#ifndef SALOMEAPP_MODULE_H
+#define SALOMEAPP_MODULE_H
+
+#include "SalomeApp.h"
+
+#include <LightApp_Module.h>
+
+#include <string>
+
+class CAM_DataModel;
+class SalomeApp_Application;
+class LightApp_Operation;
+class LightApp_Selection;
+class SALOME_ListIO;
+class QString;
+
+/*!
+ * \brief Base class for all salome modules
+*/
+class SALOMEAPP_EXPORT SalomeApp_Module : public LightApp_Module
+{
+  Q_OBJECT
+
+public:
+  SalomeApp_Module( const QString& );
+  virtual ~SalomeApp_Module();
+
+  /*! engineIOR() should be a pure virtual method, to avoid logical errors!\n
+   * Implementation in derived classes can return the following values:\n
+   * module`s engine IOR - means that this is a standard SALOME module with a CORBA engine
+   * \li "" (empty string)   - means that this not correct SALOME module
+   */
+  virtual QString                     engineIOR() const = 0;
+  
+  /*! Convenient shortcuts*/
+
+  SalomeApp_Application*              getApp() const;
+
+protected:
+  virtual CAM_DataModel*              createDataModel();
+  virtual LightApp_Selection*         createSelection() const;
+  virtual void                        extractContainers( const SALOME_ListIO&, SALOME_ListIO& ) const;
+};
+
+#endif
diff --git a/src/SalomeApp/SalomeApp_PyInterp.cxx b/src/SalomeApp/SalomeApp_PyInterp.cxx
new file mode 100755 (executable)
index 0000000..19bc575
--- /dev/null
@@ -0,0 +1,123 @@
+//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+//
+//  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SalomeApp_PyInterp.cxx
+//  Author : Nicolas REJNERI
+//  Module : SALOME
+//  $Header$
+
+#include "SalomeApp_PyInterp.h"
+
+#include <utilities.h>
+#include <Container_init_python.hxx>
+
+#include <string>
+#include <vector>
+
+#include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
+
+#include <cStringIO.h>
+using namespace std;
+
+/*!
+ * constructor : multi Python interpreter, one per SALOME study.
+ * calls initialize method defined in base class, which calls virtual methods
+ * initstate & initcontext redefined here.
+ */
+SalomeApp_PyInterp::SalomeApp_PyInterp(): PythonConsole_PyInterp()
+{
+}
+
+/*!
+ * Destructor.
+ */
+SalomeApp_PyInterp::~SalomeApp_PyInterp()
+{
+}
+/*!\class SalomeApp_PyInterp
+ * EDF-CCAR
+ * When SALOME uses multi Python interpreter feature,
+ * Every study has its own interpreter and thread state (_tstate = Py_NewInterpreter())
+ * This is fine because every study has its own modules (sys.modules) stdout and stderr
+ * BUT some Python modules must be imported only once. In multi interpreter context Python
+ * modules (*.py) are imported several times.
+ * The pyqt module must be imported only once because it registers classes in a C module.
+ * It's quite the same with omniorb modules (internals and generated with omniidl)
+ * This problem is handled with "shared modules" defined in salome_shared_modules.py
+ * These "shared modules" are imported only once and only copied in all the other interpreters
+ * BUT it's not the only problem. Every interpreter has its own __builtin__ module. That's fine
+ * but if we have copied some modules and imported others problems may arise with operations that
+ * are not allowed in restricted execution environment. So we must impose that all interpreters
+ * have identical __builtin__ module.
+ * That's all, for the moment ...
+ */
+
+
+bool SalomeApp_PyInterp::initContext()
+{
+  /*!
+   * The GIL is assumed to be held
+   * It is the caller responsability caller to acquire the GIL
+   * It will still be held on initContext output
+   */
+  if ( !PythonConsole_PyInterp::initContext() )
+    return false;
+
+  // Import special module to change the import mechanism
+  PyObjWrapper m1( PyImport_ImportModule( "import_hook" ) );
+  if ( !m1 )
+  {
+    MESSAGE( "initContext: problem with import_hook import" );
+    PyErr_Print();
+    ASSERT( 0 );
+    return false;
+  }
+
+  // Call init_shared_modules to initialize the shared import mechanism for modules 
+  //that must not be imported twice
+  PyObjWrapper m2( PyObject_CallMethod( m1, "init_shared_modules", "O", KERNEL_PYTHON::salome_shared_modules_module ) );
+  if ( !m2 )
+  {
+    MESSAGE( "initContext: problem with init_shared_modules call" );
+    PyErr_Print();
+    ASSERT( 0 );
+    return false;
+  }
+
+  return true;
+}
+
+void SalomeApp_PyInterp::init_python()
+{
+  /*
+   * Do nothing
+   * The initialization has been done in main
+   */
+  MESSAGE("PyInterp_base::init_python");
+  ASSERT(KERNEL_PYTHON::_gtstate); // initialisation in main
+  SCRUTE(KERNEL_PYTHON::_gtstate);
+  _gtstate=KERNEL_PYTHON::_gtstate;
+  _interp=KERNEL_PYTHON::_interp;
+}
+
diff --git a/src/SalomeApp/resources/SalomeApp_msg_en.po b/src/SalomeApp/resources/SalomeApp_msg_en.po
new file mode 100644 (file)
index 0000000..a739779
--- /dev/null
@@ -0,0 +1,192 @@
+// File:      CATHAREGUI_msg_en.po
+// Created:   10/25/2004 12:46:36 PM
+// Author:    Sergey LITONIN
+// Copyright (C) CEA 2004
+
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2002-02-22 16:56:46 CET\n"
+"PO-Revision-Date: 2004-02-17 11:17+0300\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+//=======================================================================================
+
+msgid "BUT_OK"
+msgstr "&OK"
+
+msgid "BUT_NEW"
+msgstr "&New"
+
+msgid "BUT_OPEN"
+msgstr "&Open"
+
+msgid "BUT_LOAD"
+msgstr "&Load"
+
+msgid "BUT_CANCEL"
+msgstr "&Cancel"
+
+//=======================================================================================
+
+msgid "SalomeApp_Application::PYTHON_CONSOLE"
+msgstr "Python Console"
+
+msgid "SalomeApp_Application::TOT_DESK_FILE_DUMP_STUDY"
+msgstr "Dump study"
+
+msgid "SalomeApp_Application::MEN_DESK_FILE_DUMP_STUDY"
+msgstr "&Dump study..."
+
+msgid "SalomeApp_Application::PRP_DESK_FILE_DUMP_STUDY"
+msgstr "Dumps study to the python script"
+
+msgid "SalomeApp_Application::TOT_DESK_FILE_LOAD_SCRIPT"
+msgstr "Load python script"
+
+msgid "SalomeApp_Application::MEN_DESK_FILE_LOAD_SCRIPT"
+msgstr "Load scrip&t..."
+
+msgid "SalomeApp_Application::PRP_DESK_FILE_LOAD_SCRIPT"
+msgstr "Loads python script from file"
+
+msgid "SalomeApp_Application::TOT_FILE_DESK_PREFERENCES"
+msgstr "Preferences"
+
+msgid "SalomeApp_Application::MEN_DESK_TOOLS"
+msgstr "&Tools"
+
+msgid "SalomeApp_Application::TOT_DESK_CATALOG_GENERATOR"
+msgstr "Catalog generator"
+
+msgid "SalomeApp_Application::MEN_DESK_CATALOG_GENERATOR"
+msgstr "Catalog &generator"
+
+msgid "SalomeApp_Application::PRP_DESK_CATALOG_GENERATOR"
+msgstr "Generates XML catalog of a component's interface"
+
+msgid "SalomeApp_Application::TOT_DESK_REGISTRY_DISPLAY"
+msgstr "Registry display"
+
+msgid "SalomeApp_Application::MEN_DESK_REGISTRY_DISPLAY"
+msgstr "Registry &display"
+
+msgid "SalomeApp_Application::PRP_DESK_REGISTRY_DISPLAY"
+msgstr "Displays content of the Registry CORBA server"
+
+msgid "SalomeApp_Application::TOT_DESK_MRU"
+msgstr "Most recently used"
+
+msgid "SalomeApp_Application::MEN_DESK_MRU"
+msgstr "Most recently used"
+
+msgid "SalomeApp_Application::TOT_DESK_PROPERTIES"
+msgstr "Study properties"
+
+msgid "SalomeApp_Application::MEN_DESK_PROPERTIES"
+msgstr "Pro&perties..."
+
+msgid "SalomeApp_Application::PRP_DESK_PROPERTIES"
+msgstr "Edits study properties"
+
+msgid "SalomeApp_Application::PREF_CATEGORY_SALOME"
+msgstr "SALOME"
+
+msgid "SalomeApp_Application::PREF_TAB_OBJBROWSER"
+msgstr "Object browser"
+
+msgid "SalomeApp_Application::MEN_OPENWITH"
+msgstr "Activate Module"
+
+msgid "SalomeApp_Application::MEN_DELETE_INVALID_REFERENCE"
+msgstr "Delete Invalid Reference"
+
+//=======================================================================================
+
+msgid "SalomeApp_Application::MEN_WINDOWS_NEW"
+msgstr "New window"
+
+msgid "SalomeApp_Application::MEN_VIEW_WNDS"
+msgstr "Windows"
+
+//=======================================================================================
+
+msgid "SalomeApp_Application::PREF_GROUP_DEF_COLUMNS"
+msgstr "Default columns"
+
+msgid "SalomeApp_Application::PREF_OBJ_BROWSER_SETTINGS"
+msgstr "Settings"
+
+//=======================================================================================
+
+msgid "SalomeApp_Application::OBJ_BROWSER_NAME"
+msgstr "Object"
+
+msgid "SalomeApp_Application::OBJ_BROWSER_COLUMN_0"
+msgstr "Value"
+
+msgid "SalomeApp_Application::OBJ_BROWSER_COLUMN_1"
+msgstr "Entry"
+
+msgid "SalomeApp_Application::OBJ_BROWSER_COLUMN_2"
+msgstr "IOR"
+
+msgid "SalomeApp_Application::OBJ_BROWSER_COLUMN_3"
+msgstr "Reference entry"
+
+msgid "SalomeApp_Application::ALL_FILES_FILTER"
+msgstr "All files (*.*)"
+
+msgid "SalomeApp_Application::PYTHON_FILES_FILTER"
+msgstr "PYTHON Files (*.py)"
+
+msgid "SalomeApp_Application::STUDY_LOCKED"
+msgstr "LOCKED"
+
+msgid "SalomeApp_Application::QUE_DOC_ALREADYEXIST"
+msgstr "The document %1 already exists in study manager.\nDo you want to reload it ?"
+
+//=======================================================================================
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_MODE_FROM_SCRATCH"
+msgstr "from scratch"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_MODE_FROM_COPYFROM"
+msgstr "copy from"
+
+msgid "SalomeApp_StudyPropertiesDlg::TLT_STUDY_PROPERTIES"
+msgstr "Study Properties"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_AUTHOR"
+msgstr "Author"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_DATE"
+msgstr "Created"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_MODE"
+msgstr "Mode"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_LOCKED"
+msgstr "Locked"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_MODIFIED"
+msgstr "Modified"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_MODIFICATIONS"
+msgstr "Modifications"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_YES"
+msgstr "Yes"
+
+msgid "SalomeApp_StudyPropertiesDlg::PRP_NO"
+msgstr "No"
+
+//=======================================================================================
+
+msgid "SalomeApp_Application::PUBLISH_IN_STUDY"
+msgstr "Publish in study"
+
+msgid "SalomeApp_Application::WRN_DUMP_STUDY_FAILED"
+msgstr "Dump study failed"
+
diff --git a/src/Session/SALOME_Session_Server.cxx b/src/Session/SALOME_Session_Server.cxx
new file mode 100755 (executable)
index 0000000..ac77385
--- /dev/null
@@ -0,0 +1,446 @@
+// SALOME Session : implementation of Session.idl
+//
+// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SALOME_Session_Server.cxx
+// Author : Paul RASCLE, EDF
+// Module : SALOME
+
+#include <Container_init_python.hxx>
+#include "Utils_ORB_INIT.hxx"
+#include "Utils_SINGLETON.hxx"
+#include "SALOME_NamingService.hxx"
+#include "SALOMETraceCollector.hxx"
+
+#include "InquireServersQThread.h" // splash
+
+#include <iostream>
+#ifndef WNT
+#include <unistd.h>
+#endif
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qapplication.h>
+#include <qwaitcondition.h>
+
+#include "Utils_SALOME_Exception.hxx"
+#include "Utils_CorbaException.hxx"
+#include "SALOME_Event.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Session)
+#include CORBA_SERVER_HEADER(SALOMEDS)
+
+#include <utilities.h>
+#include "Session_Session_i.hxx"
+#include "Session_ServerLauncher.hxx"
+
+#include "SUIT_Tools.h"
+#include "SUIT_Session.h"
+#include "SUIT_Application.h"
+#include "SUIT_MessageBox.h"
+#include "SUIT_ResourceMgr.h"
+
+#include "SUIT_ExceptionHandler.h"
+
+extern "C" int HandleSignals( QApplication *theQApplication );
+
+/*! - read arguments, define list of server to launch with their arguments.
+ * - wait for naming service
+ * - create and run a thread for launch of all servers
+ *
+*/
+
+//! CORBA server for SALOME Session
+/*!
+ * SALOME_Session Server launches a SALOME session servant.
+ * The servant registers to the Naming Service.
+ * See SALOME_Session.idl for interface specification.
+ *
+ * Main services offered by the servant are:
+ * - launch GUI
+ * - stop Session ( must be idle )
+ * - get session state
+ */
+
+PyObject* salome_shared_modules_module = 0;
+
+void MessageOutput( QtMsgType type, const char* msg )
+{
+  switch ( type )
+  {
+  case QtDebugMsg:
+    MESSAGE( "Debug: " << msg );
+    break;
+  case QtWarningMsg:
+    MESSAGE( "Warning: " << msg );
+    break;
+  case QtFatalMsg:
+    MESSAGE( "Fatal: " << msg );
+    break;
+  }
+}
+
+/* XPM */
+static const char* pixmap_not_found_xpm[] = {
+"16 16 3 1",
+"       c None",
+".      c #000000",
+"+      c #A80000",
+"                ",
+"                ",
+"    .     .     ",
+"   .+.   .+.    ",
+"  .+++. .+++.   ",
+"   .+++.+++.    ",
+"    .+++++.     ",
+"     .+++.      ",
+"    .+++++.     ",
+"   .+++.+++.    ",
+"  .+++. .+++.   ",
+"   .+.   .+.    ",
+"    .     .     ",
+"                ",
+"                ",
+"                "};
+
+QString salomeVersion()
+{
+  QString path( ::getenv( "GUI_ROOT_DIR" ) );
+  if ( !path.isEmpty() )
+    path += QDir::separator();
+  path += QString( "bin/salome/VERSION" );
+
+  QFile vf( path );
+  if ( !vf.open( IO_ReadOnly ) )
+    return QString::null;
+
+  QString line;
+  vf.readLine( line, 1024 );
+  vf.close();
+
+  if ( line.isEmpty() )
+    return QString::null;
+
+  while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
+    line.remove( line.length() - 1, 1 );
+
+  QString ver;
+  int idx = line.findRev( ":" );
+  if ( idx != -1 )
+    ver = line.mid( idx + 1 ).stripWhiteSpace();
+
+  return ver;
+}
+
+class SALOME_ResourceMgr : public SUIT_ResourceMgr
+{
+public:
+  SALOME_ResourceMgr( const QString& app, const QString& resVarTemplate ) : SUIT_ResourceMgr( app, resVarTemplate )
+  {
+    setCurrentFormat( "xml" );
+    setOption( "translators", QString( "%P_msg_%L.qm|%P_icons.qm|%P_images.qm" ) );
+    setDefaultPixmap( QPixmap( pixmap_not_found_xpm ) );
+  }
+  static void initResourceMgr()
+  {
+    if ( myExtAppName.isNull() || myExtAppVersion.isNull() ) {
+      SALOME_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) );
+      resMgr.loadLanguage( "SalomeApp", "en" );
+
+      myExtAppName = QObject::tr( "APP_NAME" ).stripWhiteSpace();
+      if ( myExtAppName == "APP_NAME" || myExtAppName.lower() == "salome" ) 
+        myExtAppName = "SalomeApp";
+      myExtAppVersion = QObject::tr( "APP_VERSION" );
+      if ( myExtAppVersion == "APP_VERSION" ) {
+        if ( myExtAppName != "SalomeApp" )
+          myExtAppVersion = "";
+       else myExtAppVersion = salomeVersion();
+      }
+    }
+  }
+  QString version() const { return myExtAppVersion; }
+
+protected:
+  QString userFileName( const QString& appName ) const
+  { 
+    if ( version().isNull()  ) return ""; 
+    return SUIT_ResourceMgr::userFileName( myExtAppName );
+  }
+
+public:
+  static QString myExtAppName;
+  static QString myExtAppVersion;
+};
+
+QString SALOME_ResourceMgr::myExtAppName    = QString::null;
+QString SALOME_ResourceMgr::myExtAppVersion = QString::null;
+
+class SALOME_Session : public SUIT_Session
+{
+public:
+  SALOME_Session() : SUIT_Session() {}
+  virtual ~SALOME_Session() {}
+
+protected:
+  virtual SUIT_ResourceMgr* createResourceMgr( const QString& appName ) const
+  {
+    SALOME_ResourceMgr::initResourceMgr();
+    SALOME_ResourceMgr* resMgr = new SALOME_ResourceMgr( appName, QString( "%1Config" ) );
+    return resMgr;
+  }
+};
+
+class SALOME_QApplication : public QApplication
+{
+public:
+  SALOME_QApplication( int& argc, char** argv ) : QApplication( argc, argv ), myHandler ( 0 ) {}
+
+  virtual bool notify( QObject* receiver, QEvent* e )
+  {
+    return myHandler ? myHandler->handle( receiver, e ) :
+      QApplication::notify( receiver, e );
+  }
+  SUIT_ExceptionHandler* handler() const { return myHandler; }
+  void setHandler( SUIT_ExceptionHandler* h ) { myHandler = h; }
+
+private:
+  SUIT_ExceptionHandler* myHandler;
+};
+
+// class which calls SALOME::Session::GetInterface() from another thread
+// to avoid mutual lock ( if called from the same thread as main()
+class GetInterfaceThread : public QThread
+{
+public:
+  GetInterfaceThread( SALOME::Session_var s ) : session ( s ) {}
+protected:
+  virtual void run()
+  {
+    if ( !CORBA::is_nil( session ) )
+      session->GetInterface();
+    else
+      printf( "\nFATAL ERROR: SALOME::Session object is nil! Can not display GUI\n\n" );
+  }
+private:
+  SALOME::Session_var session;
+};
+
+// returns true if 'str' is found in argv
+bool isFound( const char* str, int argc, char** argv )
+{
+  for ( int i = 1; i <= ( argc-1 ); i++ )
+    if ( !strcmp( argv[i], str ) )
+      return true;
+  return false;
+}
+
+// ---------------------------- MAIN -----------------------
+int main( int argc, char **argv )
+{
+  qInstallMsgHandler( MessageOutput );
+
+  // QApplication should be create before all other operations
+  // When uses QApplication::libraryPaths() ( example, QFile::encodeName() )
+  // qApp used for detection of the executable dir path.
+  SALOME_QApplication _qappl( argc, argv );
+  ASSERT( QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) ) );
+
+  QString path = QDir::convertSeparators( SUIT_Tools::addSlash( QString( ::getenv( "GUI_ROOT_DIR" ) ) ) + QString( "bin/salome" ) );
+  _qappl.addLibraryPath( path );
+  
+  _qappl.setStyle( "salome" );
+
+  int result = -1;
+
+  CORBA::ORB_var orb;
+  PortableServer::POA_var poa;
+
+  SUIT_Session* aGUISession = 0;
+  SALOME_NamingService* _NS = 0;
+  GetInterfaceThread* guiThread = 0;
+  Session_ServerLauncher* myServerLauncher = 0;
+
+  try {
+    
+    // Python initialisation : only once
+
+    int _argc = 1;
+    char* _argv[] = {""};
+    KERNEL_PYTHON::init_python( _argc,_argv );
+    PyEval_RestoreThread( KERNEL_PYTHON::_gtstate );
+    if ( !KERNEL_PYTHON::salome_shared_modules_module ) // import only once
+      KERNEL_PYTHON::salome_shared_modules_module = PyImport_ImportModule( "salome_shared_modules" );
+    if ( !KERNEL_PYTHON::salome_shared_modules_module )
+    {
+      INFOS( "salome_shared_modules_module == NULL" );
+      PyErr_Print();
+    }
+    PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );
+
+    // Create ORB, get RootPOA object, NamingService, etc.
+    ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance();
+    ASSERT( SINGLETON_<ORB_INIT>::IsAlreadyExisting() );
+    int orbArgc = 1;
+    orb = init( orbArgc, argv );
+
+    // Install SALOME thread event handler
+    SALOME_Event::GetSessionThread();
+
+    CORBA::Object_var obj = orb->resolve_initial_references( "RootPOA" );
+    poa = PortableServer::POA::_narrow( obj );
+
+    PortableServer::POAManager_var pman = poa->the_POAManager();
+    pman->activate() ;
+    INFOS( "pman->activate()" );
+
+    _NS = new SALOME_NamingService( orb );
+
+    result = 0;
+  }
+  catch ( SALOME_Exception& e ) {
+    INFOS( "run(): SALOME::SALOME_Exception is caught: "<<e.what() );
+  }
+  catch ( CORBA::SystemException& e ) {
+    INFOS( "Caught CORBA::SystemException." );
+  }
+  catch ( CORBA::Exception& e ) {
+    INFOS( "Caught CORBA::Exception." );
+    CORBA::Any tmp;
+    tmp<<= e;
+    CORBA::TypeCode_var tc = tmp.type();
+    const char *p = tc->name();
+    INFOS ( "run(): CORBA exception of the kind : "<<p<< " is caught" );
+  }
+  catch ( exception& e ) {
+    INFOS( "run(): An exception has been caught: " <<e.what() );
+  }
+  catch (...) {
+    INFOS( "Caught unknown exception." );
+  }
+
+  // CORBA Servant Launcher
+  QMutex _GUIMutex;
+  QWaitCondition _ServerLaunch, _SessionStarted;
+
+  if ( !result )
+  {
+    _GUIMutex.lock();  // to block Launch server thread until wait( mutex )
+
+    // Activate embedded CORBA servers: Registry, SALOMEDS, etc.
+    myServerLauncher = new Session_ServerLauncher( argc, argv, orb, poa, &_GUIMutex, &_ServerLaunch, &_SessionStarted );
+    myServerLauncher->start();
+
+    _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready:
+    
+    // show splash screen if "SPLASH" parameter was passed ( default )
+    if ( isFound( "SPLASH", argc, argv ) )
+    {
+      // create temporary resource manager just to load splash icon
+      SUIT_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) );
+      resMgr.setCurrentFormat( "xml" );
+      resMgr.loadLanguage( "LightApp", "en" );
+
+      // create splash object: widget ( splash with progress bar ) and "pinging" thread
+      InquireServersGUI splash;
+      splash.setPixmap( resMgr.loadPixmap( "LightApp", QObject::tr( "ABOUT_SPLASH" ) ) );
+      SUIT_Tools::centerWidget( &splash, _qappl.desktop() );
+      
+      _qappl.setMainWidget( &splash );
+      QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) );
+      splash.show(); // display splash with running progress bar
+      _qappl.exec(); // wait untill splash closes ( progress runs till end or Cancel is pressed )
+      
+      result = splash.getExitStatus(); // 1 is error
+    }
+    else
+      _SessionStarted.wait();
+  }
+
+  // call Session::GetInterface() if "GUI" parameter was passed ( default )
+  if ( !result && isFound( "GUI", argc, argv ) )
+  {
+    CORBA::Object_var obj = _NS->Resolve( "/Kernel/Session" );
+    SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
+    ASSERT ( ! CORBA::is_nil( session ) );
+
+    INFOS( "Session activated, Launch IAPP..." );
+    guiThread = new GetInterfaceThread( session );
+    guiThread->start();
+  }
+
+  if ( !result )
+  {
+
+    // GUI activation
+    // Allow multiple activation/deactivation of GUI
+    while ( true )
+    {
+      MESSAGE( "waiting wakeAll()" );
+      _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready:
+      // atomic operation lock - unlock on mutex
+      // unlock mutex: serverThread runs, calls _ServerLaunch->wakeAll()
+      // this thread wakes up, and lock mutex
+
+      _GUIMutex.unlock();
+
+      // SUIT_Session creation
+      aGUISession = new SALOME_Session();
+
+      // Load SalomeApp dynamic library
+      INFOS( "creation SUIT_Application" );
+      SUIT_Application* aGUIApp = aGUISession->startApplication( "SalomeApp", 0, 0 );
+      if ( aGUIApp )
+      {
+       if ( !isFound( "noexcepthandler", argc, argv ) )
+         _qappl.setHandler( aGUISession->handler() ); // after loading SalomeApp application
+                                                      // aGUISession contains SalomeApp_ExceptionHandler
+       // Run GUI loop
+       MESSAGE( "run(): starting the main event loop" );
+       result = _qappl.exec();
+
+       if ( result == SUIT_Session::FROM_GUI ) // desktop is closed by user from GUI
+         break;
+      }
+
+      delete aGUISession;
+      aGUISession = 0;
+
+      // Prepare _GUIMutex for a new GUI activation
+      _GUIMutex.lock();
+    }
+  }
+
+  if ( myServerLauncher )
+    myServerLauncher->KillAll(); // kill embedded servers
+
+  delete aGUISession;
+  delete guiThread;
+  delete myServerLauncher;
+  delete _NS;
+
+  LocalTraceBufferPool *bp1 = LocalTraceBufferPool::instance();
+  LocalTraceBufferPool::deleteInstance(bp1);
+
+  return result;
+}
diff --git a/src/Session/Session_ServerThread.cxx b/src/Session/Session_ServerThread.cxx
new file mode 100755 (executable)
index 0000000..7e37145
--- /dev/null
@@ -0,0 +1,559 @@
+//  SALOME Session : implementation of Session_ServerThread.cxx
+//
+//  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Session_ServerThread.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SALOME
+//  $Header$
+
+// #include <SALOMEconfig.h>
+// #include CORBA_SERVER_HEADER(SALOME_Session)
+// #include CORBA_SERVER_HEADER(SALOMEDS)
+
+#include "Session_ServerThread.hxx"
+
+#include "SALOME_Container_i.hxx"
+#include "SALOME_ContainerManager.hxx"
+#include "SALOMEDS_StudyManager_i.hxx"
+#include "SALOME_ModuleCatalog_impl.hxx"
+#include "RegistryService.hxx"
+#include "Session_Session_i.hxx"
+#include "SalomeApp_Engine_i.hxx"
+
+#include "Utils_ORB_INIT.hxx"
+#include "Utils_SINGLETON.hxx"
+#include "Utils_SALOME_Exception.hxx"
+#include "OpUtil.hxx"
+#include "NamingService_WaitForServerReadiness.hxx"
+#include "utilities.h"
+
+#include <cstdlib>
+#include <ctime>
+
+using namespace std;
+
+const int Session_ServerThread::NB_SRV_TYP = 7;
+const char* Session_ServerThread::_serverTypes[NB_SRV_TYP] = {"Container",
+                                                             "ModuleCatalog",
+                                                             "Registry",
+                                                             "SALOMEDS",
+                                                             "Session",
+                                                             "SalomeAppEngine",
+                                                              "ContainerManager"};
+
+//=============================================================================
+/*! 
+ *  default constructor not for use
+ */
+//=============================================================================
+
+Session_ServerThread::Session_ServerThread()
+{
+  ASSERT(0); // must not be called
+}
+
+//=============================================================================
+/*! 
+ *  constructor
+ */
+//=============================================================================
+
+Session_ServerThread::Session_ServerThread(int argc,
+                                          char ** argv, 
+                                          CORBA::ORB_ptr orb, 
+                                          PortableServer::POA_ptr poa,
+                                          QMutex *GUIMutex)
+{
+  //MESSAGE("Session_ServerThread Constructor " << argv[0]);
+  _argc = argc;
+  _argv = argv;
+  _orb = CORBA::ORB::_duplicate(orb);
+  _root_poa = PortableServer::POA::_duplicate(poa);
+  _GUIMutex = GUIMutex;
+  _servType =-1;
+  _NS = new SALOME_NamingService(_orb); // one instance per server to limit
+                                        // multi thread coherence problems
+}
+
+//=============================================================================
+/*! 
+ *  destructor 
+ */
+//=============================================================================
+
+Session_ServerThread::~Session_ServerThread()
+{
+  //MESSAGE("~Session_ServerThread "<< _argv[0]);
+}
+
+//=============================================================================
+/*! 
+ *  run the thread : activate one servant, the servant type is given by
+ *  argument _argv[0]
+ */
+//=============================================================================
+
+void Session_ServerThread::Init()
+{
+  MESSAGE("Session_ServerThread::Init "<< _argv[0]); 
+
+  for (int i=0; i<_argc; i++) SCRUTE(_argv[i]);
+#ifndef WNT
+  for (int i=0; i<NB_SRV_TYP; i++)
+#else
+  for (i=0; i<NB_SRV_TYP; i++)
+#endif
+    if (strcmp(_argv[0],_serverTypes[i])==0)
+      {
+       _servType = i;
+       MESSAGE("Server Thread type : "<<_serverTypes[i]);
+       switch (_servType)
+         {
+         case 0:  // Container
+           {
+             NamingService_WaitForServerReadiness(_NS,"/Registry");
+             NamingService_WaitForServerReadiness(_NS,"/ContainerManager");
+             ActivateContainer(_argc, _argv);
+             break;
+           }
+         case 1:  // ModuleCatalog
+           {
+             NamingService_WaitForServerReadiness(_NS,"/Registry");
+             ActivateModuleCatalog(_argc, _argv);
+             break;
+           }
+         case 2:  // Registry
+           {
+             NamingService_WaitForServerReadiness(_NS,"");
+             ActivateRegistry(_argc, _argv);
+             break;
+           }
+         case 3:  // SALOMEDS
+           {
+             NamingService_WaitForServerReadiness(_NS,"/Kernel/ModulCatalog");
+             ActivateSALOMEDS(_argc, _argv);
+             break;
+           }
+         case 4:  // Session
+           {
+             NamingService_WaitForServerReadiness(_NS,"/myStudyManager");
+             string containerName = "/Containers/";
+             containerName = containerName + GetHostname();
+             containerName = containerName + "/FactoryServer";
+             NamingService_WaitForServerReadiness(_NS,containerName);
+             ActivateSession(_argc, _argv);
+             break;
+           }
+         case 5: // SalomeApp_Engine
+           {
+             NamingService_WaitForServerReadiness(_NS,"/myStudyManager");
+             ActivateEngine(_argc, _argv);
+             break;
+           }
+         case 6: // Container Manager
+           {
+             NamingService_WaitForServerReadiness(_NS,"");
+             ActivateContainerManager(_argc, _argv);
+             break;
+           }
+         default:
+           {
+             ASSERT(0);
+             break;
+           }
+         }
+      }
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void Session_ServerThread::ActivateModuleCatalog(int argc,
+                                                char ** argv)
+{
+  try
+    {
+      INFOS("ModuleCatalog thread started");
+      // allocation on heap to allow destruction by POA
+
+      SALOME_ModuleCatalogImpl* Catalogue_i
+       = new SALOME_ModuleCatalogImpl(argc, argv);
+
+      // Tell the POA that the objects are ready to accept requests.
+
+      _root_poa->activate_object (Catalogue_i);
+
+      CORBA::Object_ptr myCata = Catalogue_i->_this();
+      _NS->Register(myCata ,"/Kernel/ModulCatalog");
+    }
+  catch(CORBA::SystemException&)
+    {
+      INFOS( "Caught CORBA::SystemException." );
+    }
+  catch(CORBA::Exception&)
+    {
+      INFOS( "Caught CORBA::Exception." );
+    }
+  catch(omniORB::fatalException& fe)
+    {
+      INFOS( "Caught omniORB::fatalException:" );
+      INFOS( "  file: " << fe.file() );
+      INFOS( "  line: " << fe.line() );
+      INFOS( "  mesg: " << fe.errmsg() );
+    }
+  catch(...) 
+    {
+      INFOS( "Caught unknown exception." );
+    }
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void Session_ServerThread::ActivateSALOMEDS(int argc,
+                                           char ** argv)
+{
+  try
+    {
+      INFOS("SALOMEDS thread started");
+      // We allocate the objects on the heap.  Since these are reference
+      // counted objects, they will be deleted by the POA when they are no
+      // longer needed.    
+
+      SALOMEDS_StudyManager_i * myStudyManager_i
+       = new  SALOMEDS_StudyManager_i(_orb,_root_poa);
+      
+      // Activate the objects.  This tells the POA that the objects are
+      // ready to accept requests.
+
+      PortableServer::ObjectId_var myStudyManager_iid
+       = _root_poa->activate_object(myStudyManager_i);
+      myStudyManager_i->register_name("/myStudyManager");
+    }
+  catch(CORBA::SystemException&)
+    {
+      INFOS( "Caught CORBA::SystemException." );
+    }
+  catch(CORBA::Exception&)
+    {
+      INFOS( "Caught CORBA::Exception." );
+    }
+  catch(omniORB::fatalException& fe)
+    {
+      INFOS( "Caught omniORB::fatalException:" );
+      INFOS( "  file: " << fe.file() );
+      INFOS( "  line: " << fe.line() );
+      INFOS( "  mesg: " << fe.errmsg() );
+    }
+  catch(...) 
+    {
+      INFOS( "Caught unknown exception." );
+    }
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void Session_ServerThread::ActivateRegistry(int argc,
+                                           char ** argv)
+{
+  INFOS("Registry thread started");
+  SCRUTE(argc); 
+  if( argc<3 )
+    {
+      INFOS("you must provide the Salome session name when you call SALOME_Registry_Server");
+      throw CommException("you must provide the Salome session name when you call SALOME_Registry_Server");
+    }
+  const char *ptrSessionName=0;
+
+  int k=0 ;
+  for ( k=1 ; k<argc ; k++ )
+    {
+      if( strcmp(argv[k],"--salome_session")==0 )
+       {
+         ptrSessionName=argv[k+1];
+         break;
+       }
+    }
+  ASSERT(ptrSessionName) ;
+  ASSERT(strlen( ptrSessionName )>0);
+  const char *registryName = "Registry";
+  Registry::Components_var varComponents;
+  try
+    {
+      RegistryService *ptrRegistry = SINGLETON_<RegistryService>::Instance();
+      ptrRegistry->SessionName( ptrSessionName );
+      varComponents = ptrRegistry->_this();
+      // The RegistryService must not already exist.
+           
+      try
+       {
+         CORBA::Object_var pipo = _NS->Resolve( registryName );
+         if (CORBA::is_nil(pipo) )  throw ServiceUnreachable();
+         INFOS("RegistryService servant already existing" );
+         ASSERT(0);
+       }
+      catch( const ServiceUnreachable &ex )
+       {
+       }
+      catch( const CORBA::Exception &exx )
+       {
+       }
+      string absoluteName = string("/") + registryName;
+      _NS->Register( varComponents , absoluteName.c_str() );
+      MESSAGE("On attend les requetes des clients");
+    }
+  catch( const SALOME_Exception &ex )
+    {
+      INFOS( "Communication Error : " << ex.what() );
+      ASSERT(0);
+    }
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void Session_ServerThread::ActivateContainerManager(int argc,
+                                            char ** argv)
+{
+  try
+    {
+      PortableServer::POA_var root_poa=PortableServer::POA::_the_root_poa();
+      cout << "ActivateContainerManager ......!!!! " << endl;
+      SALOME_ContainerManager * myContainer 
+       = new SALOME_ContainerManager(_orb);
+    }
+  catch(CORBA::SystemException&)
+    {
+      INFOS("Caught CORBA::SystemException.");
+    }
+  catch(PortableServer::POA::WrongPolicy&)
+    {
+      INFOS("Caught CORBA::WrongPolicyException.");
+    }
+  catch(PortableServer::POA::ServantAlreadyActive&)
+    {
+      INFOS("Caught CORBA::ServantAlreadyActiveException");
+    }
+  catch(CORBA::Exception&)
+    {
+      INFOS("Caught CORBA::Exception.");
+    }
+  catch(...)
+    {
+      INFOS("Caught unknown exception.");
+    }
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void Session_ServerThread::ActivateContainer(int argc,
+                                            char ** argv)
+{
+  try
+    {
+      INFOS("Container thread started");
+
+      // get or create the child POA
+
+      PortableServer::POA_var factory_poa;
+      try
+       {
+         factory_poa = _root_poa->find_POA("factory_poa",0);
+         // 0 = no activation (already done if exists)
+       }
+      catch (PortableServer::POA::AdapterNonExistent&)
+       {
+         INFOS("factory_poa does not exists, create...");
+         // define policy objects     
+         PortableServer::ImplicitActivationPolicy_var implicitActivation =
+           _root_poa->create_implicit_activation_policy(
+                               PortableServer::NO_IMPLICIT_ACTIVATION);
+         // default = NO_IMPLICIT_ACTIVATION
+         PortableServer::ThreadPolicy_var threadPolicy =
+           _root_poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL);
+         // default = ORB_CTRL_MODEL, other choice SINGLE_THREAD_MODEL
+      
+         // create policy list
+         CORBA::PolicyList policyList;
+         policyList.length(2);
+         policyList[0] = PortableServer::ImplicitActivationPolicy::
+           _duplicate(implicitActivation);
+         policyList[1] = PortableServer::ThreadPolicy::
+           _duplicate(threadPolicy);
+      
+         PortableServer::POAManager_var nil_mgr
+           = PortableServer::POAManager::_nil();
+         factory_poa = _root_poa->create_POA("factory_poa",
+                                             nil_mgr,
+                                             policyList);
+         //with nil_mgr instead of pman,
+         //a new POA manager is created with the new POA
+      
+         // destroy policy objects
+         implicitActivation->destroy();
+         threadPolicy->destroy();
+
+         // obtain the factory poa manager
+         PortableServer::POAManager_var pmanfac = factory_poa->the_POAManager();
+         pmanfac->activate();
+         MESSAGE("pmanfac->activate()");
+       }
+      
+      char *containerName = "";
+      if (argc >1) 
+       {
+         containerName = argv[1];
+       }
+      
+      Engines_Container_i * myContainer 
+       = new Engines_Container_i(_orb, _root_poa, containerName , argc , argv , true , false);
+    }
+  catch(CORBA::SystemException&)
+    {
+      INFOS("Caught CORBA::SystemException.");
+    }
+  catch(PortableServer::POA::WrongPolicy&)
+    {
+      INFOS("Caught CORBA::WrongPolicyException.");
+    }
+  catch(PortableServer::POA::ServantAlreadyActive&)
+    {
+      INFOS("Caught CORBA::ServantAlreadyActiveException");
+    }
+  catch(CORBA::Exception&)
+    {
+      INFOS("Caught CORBA::Exception.");
+    }
+  catch(...)
+    {
+      INFOS("Caught unknown exception.");
+    }
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void Session_ServerThread::ActivateEngine(int /*argc*/, char ** /*argv*/)
+{
+    try
+      {
+       INFOS("SalomeApp_Engine thread started");
+       SalomeApp_Engine_i* anEngine = new SalomeApp_Engine_i();
+       /*PortableServer::ObjectId_var id = */_root_poa->activate_object( anEngine );
+       INFOS("poa->activate_object( SalomeApp_Engine )");
+      
+       CORBA::Object_ptr obj = anEngine->_this();
+       _NS->Register( obj ,"/SalomeAppEngine");
+
+      }
+    catch (CORBA::SystemException&)
+      {
+       INFOS("Caught CORBA::SystemException.");
+      }
+    catch (CORBA::Exception&)
+      {
+       INFOS("Caught CORBA::Exception.");
+      }
+    catch (...)
+      {
+       INFOS("Caught unknown exception.");
+      }  
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void Session_ServerThread::ActivateSession(int argc,
+                                          char ** argv)
+{
+  MESSAGE("Session_ServerThread::ActivateSession() not implemented!");
+}
+
+Session_SessionThread::Session_SessionThread(int argc,
+                                            char** argv, 
+                                            CORBA::ORB_ptr orb, 
+                                            PortableServer::POA_ptr poa,
+                                            QMutex* GUIMutex,
+                                            QWaitCondition* GUILauncher)
+: Session_ServerThread(argc, argv, orb, poa, GUIMutex),
+  _GUILauncher( GUILauncher )
+{
+}
+
+Session_SessionThread::~Session_SessionThread()
+{
+}
+
+void Session_SessionThread::ActivateSession(int argc,
+                                           char ** argv)
+{
+    try
+      {
+       INFOS("Session thread started");
+       SALOME_Session_i * mySALOME_Session
+         = new SALOME_Session_i(argc, argv, _orb, _root_poa, _GUIMutex, _GUILauncher) ;
+       PortableServer::ObjectId_var mySALOME_Sessionid
+         = _root_poa->activate_object(mySALOME_Session);
+       INFOS("poa->activate_object(mySALOME_Session)");
+      
+       CORBA::Object_var obj = mySALOME_Session->_this();
+       CORBA::String_var sior(_orb->object_to_string(obj));
+      
+       mySALOME_Session->NSregister();
+         }
+    catch (CORBA::SystemException&)
+      {
+       INFOS("Caught CORBA::SystemException.");
+      }
+    catch (CORBA::Exception&)
+      {
+       INFOS("Caught CORBA::Exception.");
+      }
+    catch (...)
+      {
+       INFOS("Caught unknown exception.");
+      }  
+}