--- /dev/null
+/*! \mainpage
+
+\image html guiscreen.png
+
+To browse the \b SALOME GUI module Developer Documentation, follow the links below or use navigation menu at the top of the page:
+<ul>
+<li> <a href="namespaces.html">Packages</a> - list of GUI module packages and scripts.</li>
+<li> <a href="annotated.html">Data Structures</a> - list of all data structures and classes with brief descriptions.</li>
+<li> <a href="files.html">Files</a> - list of all files with brief descriptions.</li>
+</ul>
+
+*/
\ No newline at end of file
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+mypkgpythondir = $(salomepythondir)/salome/gui
+
+# Python modules to be installed
+mypkgpython_PYTHON = \
+ __init__.py \
+ selectvars.py \
+ genericdialog.py \
+ mytestdialog.py \
+ helper.py
+
+PYUIC_FILES = \
+ SelectVarsDialog_ui.py \
+ genericdialog_ui.py \
+ mytestdialog_ui.py
+
+nodist_mypkgpython_PYTHON = $(PYUIC_FILES)
+CLEANFILES = $(PYUIC_FILES)
+
+EXTRA_DIST += \
+ SelectVarsDialog.ui \
+ genericdialog.ui \
+ mytestdialog.ui
+
+# This rule indicates that some python files are generated from ui
+# files using the PYUIC utility. The convention is to create a file
+# name <basename>_ui.py when the ui file name is <basename>.ui. When
+# implementing the dialog, you generally create a third file named
+# <basename>.py that uses the UI_<basename> classe defined in the
+# generated file <basename>_ui.py.
+%_ui.py:%.ui
+ $(PYUIC) -x $< -o $@
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SelectVarsDialog</class>
+ <widget class="QDialog" name="SelectVarsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>611</width>
+ <height>743</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Select Variables of Interest</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Potential Variables List</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Selected Variables List</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="loadVarsButton">
+ <property name="text">
+ <string>Import...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="saveVarsButton">
+ <property name="text">
+ <string>Export...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>All Input Variables</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Selected Input Variables</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QListWidget" name="allInputVarListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::MultiSelection</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addInputVarButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeInputVarButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newInputVarButton">
+ <property name="text">
+ <string>New...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="2">
+ <widget class="QListWidget" name="selectedInputVarListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::MultiSelection</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>All Output Variables</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Selected Output Variables</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QListWidget" name="allOutputVarListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::MultiSelection</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addOutputVarButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeOutputVarButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newOutputVarButton">
+ <property name="text">
+ <string>New...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="2">
+ <widget class="QListWidget" name="selectedOutputVarListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::MultiSelection</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="varListObjLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="selectButton">
+ <property name="text">
+ <string>Select</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="OKButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+__author__="gboulant"
+__date__ ="$31 mars 2010 17:09:53$"
+
+from PyQt4.QtGui import QDialog, QMessageBox
+
+from genericdialog_ui import Ui_GenericDialog
+
+class GenericDialog(QDialog):
+ """
+ This is an abstract generic dialog box for implementing default and
+ generic behaviour of dialog windows.
+ Note that this class can be instantiated but can't be used because the
+ OK behaviour is a default one indicating that the checkData function should
+ be implemented in a derived class. The general interface that should be
+ implemented in derived class is the MVC pattern:
+
+ - setData(<a_data_model_object>):
+ to initiate the values of the dialog windows from a given data model.
+
+ - boolean checkData():
+ to verify that the data are valid and notify user if not.
+
+ - <a_data_model_object> getData():
+ to get the valid data model from values read in the dialog window.
+ """
+
+ __wasOk = False
+ checkDataMessage = ""
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ QDialog.__init__(self,parent)
+ # Set up the user interface from Designer.
+ self.__ui = Ui_GenericDialog()
+ self.__ui.setupUi(self)
+
+ def getPanel(self):
+ '''
+ This returns the central panel where to draw the custom dialog
+ widgets.
+ '''
+ return self.__ui.myCenterPanel
+
+ def getButtonBox(self):
+ return self.__ui.buttonBox
+
+ def accept(self):
+ """
+ Slot function connected to the button OK
+ """
+ if not self.checkData():
+ QMessageBox.warning( self, "Alerte", self.checkDataMessage)
+ return
+ self.__wasOk = True
+ self.hide()
+
+ def displayAndWait(self):
+ """
+ This function can be used to display the dialog in the case
+ where the dialog is modal and does not need interactivity with
+ parent windows and other part of the application. When called,
+ the dialog is raised visible and keep waiting until the button
+ OK or the button CANCEL is pressed. Then the flow can go on
+ (see an example of implementation in the tests functions at
+ the end of this file).
+ In the general case, in particular if you need interaction
+ with the graphical framework (clic on widgets embedded in
+ other dialogs), you should used instead the show() command
+ (for a non modal dialog) or the open() command (for a window
+ modal dialog, i.e. a dialog that can not interact with its
+ direct parent but can interact with the other parts).
+ """
+ self.__wasOk = False
+ self.exec_()
+
+ def wasOk(self):
+ """
+ Return True if the button OK was pressed to close the dialog windows.
+ """
+ return self.__wasOk
+
+ def checkData(self):
+ """
+ This function should be implemented in a derived class. It should return
+ True in the case where the data are estimated to be valid data.
+ """
+ self.checkDataMessage = "The checkData() function is not implemented yet"
+ return True
+
+#
+# ==============================================================================
+# Basic use cases and unit test functions
+# ==============================================================================
+#
+def TEST_GenericDialog():
+ import sys
+ from PyQt4.QtGui import QApplication
+ from PyQt4.QtCore import QObject, SIGNAL, SLOT
+ app = QApplication(sys.argv)
+ QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+ dlg=GenericDialog()
+ dlg.displayAndWait()
+ if dlg.wasOk():
+ print "OK has been pressed"
+ else:
+ print "Cancel has been pressed"
+
+if __name__ == "__main__":
+ TEST_GenericDialog()
--- /dev/null
+<ui version="4.0" >
+ <class>GenericDialog</class>
+ <widget class="QDialog" name="GenericDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>498</width>
+ <height>352</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="myCenterPanel" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>GenericDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>GenericDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Author: Guillaume Boulant (EDF/R&D)
+
+# ==================================================================
+# This file provides helper functions to drive some gui features of a
+# SALOME Application (the selection in the object browser for now,
+# further development coming soon). Note that some of these helper
+# functions are specialized for a GEOM or SMESH context (see the
+# guihelper.py modules comming with the packages salome.geom and
+# salome.smesh.
+# ==================================================================
+
+#
+# ==================================================================
+# Definition of usefull objects and functions to deal with the SALOME
+# technical context.
+# ==================================================================
+#
+
+from salome.kernel import services
+
+#
+# Get SALOME PyQt interface to manipulate the GUI context
+# (Get the active study for example. Note that the active study is a
+# GUI concept only: it is the study that is currently active in the
+# desktop)
+#
+import SalomePyQt
+sgPyQt=SalomePyQt.SalomePyQt()
+
+#
+# Get SALOME Swig interface to manipulate the GUI widget
+#
+import libSALOME_Swig
+SalomeGUI = libSALOME_Swig.SALOMEGUI_Swig()
+
+#
+# ==================================================================
+# General helper function for GUI programming actions
+# ==================================================================
+#
+# Get the active study
+#
+def getActiveStudy():
+ """
+ This returns a study object that corresponds to the active
+ study. The active study is a GUI concept: it's the study currently
+ active on the desktop.
+ """
+ studyId = sgPyQt.getStudyId()
+ study = services.getStudyManager().GetStudyByID( studyId )
+ return study
+
+#
+# ==================================================================
+# Functions to manipulate the objects in the browser (generic)
+# ==================================================================
+#
+def getSObjectSelected():
+ '''
+ Returns the sobject and the entry of the item currently selected
+ in the objects browser. Returns "None, None" if no item is
+ selected. If several objects are selected, it returns the first
+ one of the list.
+ '''
+ sobj = None
+ entry = None
+ study = getActiveStudy()
+ if SalomeGUI.SelectedCount() == 1:
+ # We only considere the first element of the list. If you need
+ # something else, create another function in your own context.
+ entry = SalomeGUI.getSelected( 0 )
+ if entry != '':
+ sobj = study.FindObjectID( entry )
+ return sobj, entry
+
+def showSObjectSelected():
+ '''
+ This function print the attributes of the selected object.
+ (this function is only for test purpose)
+ '''
+ sobj, entry = getSObjectSelected()
+ if ( sobj ):
+ test, attr = sobj.FindAttribute( "AttributeName" )
+ if test:
+ message = "My name is '%s'" % attr.Value()
+ print message
+ pass
+
+def deleteSObjectSelected():
+ '''
+ This function deletes the selected object.
+ '''
+ sobj, entry = getSObjectSelected()
+ if ( sobj ):
+ study = getActiveStudy()
+ builder = study.NewBuilder()
+ builder.RemoveObject( sobj )
+ SalomeGUI.updateObjBrowser(True)
+ pass
+
+#
+# ==================================================================
+# Use cases and demo functions
+# ==================================================================
+#
+
+# CAUTION: Before running this test functions, you first have to
+# create (or import) an object and select this object in the objects
+# browser.
+
+#
+# Definitions:
+# - the SObject is an item in the active study (Study Object).
+# - the entry is the identifier of an item.
+# - the object (geom object or smesh object) is a CORBA servant
+# embedded in the SALOME component container and with a reference in
+# the SALOME study, so that it can be retrieved.
+#
+
+def TEST_getSObjectSelected():
+ mySObject, myEntry = getSObjectSelected()
+ myName = mySObject.GetName()
+ print "The name of the selected object is %s"%myName
+
+def TEST_showSObjectSelected():
+ showSObjectSelected()
+
+if __name__ == "__main__":
+ TEST_getSObjectSelected()
+ TEST_showSObjectSelected()
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+__author__="gboulant"
+__date__ ="$31 mars 2010 17:09:53$"
+
+from mytestdialog_ui import Ui_MyTestDialog
+from genericdialog import GenericDialog
+
+class MyTestDialog(GenericDialog):
+ """
+ This class is to illustrate the usage of the GenericDialog to implement
+ the dialog windows of the application with a common design template provided
+ by the generic class GenericDialog.
+ """
+ def __init__(self, parent=None, name="MyTestDialog"):
+ GenericDialog.__init__(self, parent, name)
+ # Set up the user interface from Designer.
+ self.ui = Ui_MyTestDialog()
+ # BE CAREFULL HERE, the ui form is NOT put in the global dialog (already
+ # containing some generic widgets) but in the center panel created in the
+ # GenericDialog as a void container for the form. The MyTestDialog form
+ # is supposed here to create only the widgets to be placed in the center
+ # panel
+ self.ui.setupUi(self.getPanel())
+
+ #
+ # We implement here the interface of the MVC pattern
+ #
+ def setData(self, name):
+ """
+ This function implements the mapping from the data model to the widgets
+ """
+ self.ui.txtName.setText(name)
+
+ def checkData(self):
+ """
+ This function implements the control to be done on the values contained
+ in the widgets when trying to validate the dialog window (click OK first
+ trigs this function).
+ """
+ if ( self.ui.txtName.text().trimmed() == "" ):
+ self.checkDataMessage = "The name can't be void"
+ return False
+ return True
+
+ def getData(self):
+ """
+ This function implements the mapping from the widgets to the data model
+ """
+ name = str(self.ui.txtName.text().trimmed().toUtf8())
+ # _MEM_: note here that (i) the utf8 format is used and (ii) we must not
+ # forget to convert to a standard python string (instead of a QString).
+ return name
+
+
+from PyQt4.QtCore import SIGNAL
+class MyTestDialogWithSignals(MyTestDialog):
+ """
+ This class is to illustrate the usage of the GenericDialog in the
+ case where the dialog windows is not modal. In such a case, the
+ controller must be warn of close events using Qt signals.
+ """
+ def __init__(self, parent=None, name="MyTestDialogWithSignals"):
+ MyTestDialog.__init__(self, parent, name)
+
+ def accept(self):
+ """
+ This function is the slot connected to the the OK button
+ (click event of the OK button).
+ """
+ # The dialog is raised in a non modal mode (for example, to
+ # get interactivity with the parents windows. Then we have to
+ # emit a signal to warn the parent observer that the dialog
+ # has been validated so that it can process the event
+ MyTestDialog.accept(self)
+ if self.wasOk():
+ self.emit(SIGNAL('inputValidated()'))
+
+
+
+#
+# ==============================================================================
+# Basic use case
+# ==============================================================================
+#
+
+def TEST_MyTestDialog_modal():
+ import sys
+ from PyQt4.QtCore import QObject, SIGNAL, SLOT
+ from PyQt4.QtGui import QApplication
+ app = QApplication(sys.argv)
+ QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+ dlg=MyTestDialog()
+ dlg.setData("A default name")
+ dlg.displayAndWait()
+ if dlg.wasOk():
+ name = dlg.getData()
+ print "The name has been modified to",name
+
+
+class DialogListener:
+ def onProcessEvent(self):
+ print "onProcessEvent(): OK has been pressed"
+ import sys
+ sys.exit(0)
+
+
+def TEST_MyTestDialog_non_modal():
+ import sys
+ from PyQt4.QtCore import QObject, SIGNAL, SLOT
+ from PyQt4.QtGui import QApplication
+ app = QApplication(sys.argv)
+ QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+ dlg=MyTestDialogWithSignals()
+ # This dialog window will emit a inputValidated() signal when the
+ # OK button is pressed and the data are validated. Then, we
+ # connect this signal to a local slot so that the event can be
+ # processed.
+ dlgListener = DialogListener()
+ app.connect(dlg, SIGNAL('inputValidated()'), dlgListener.onProcessEvent)
+ # This connect instruction means that the signal inputValidated()
+ # emited by the dlg Qt object will raise a call to the slot
+ # dlgListener.onProcessEvent
+
+ dlg.setData("A default name")
+ dlg.show()
+
+ app.exec_()
+
+if __name__ == "__main__":
+ #TEST_MyTestDialog_modal()
+ TEST_MyTestDialog_non_modal()
--- /dev/null
+<ui version="4.0" >
+ <class>MyTestDialog</class>
+ <widget class="QDialog" name="MyTestDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="lblName" >
+ <property name="text" >
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtName" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import os
+from PyQt4 import QtGui, QtCore
+from PyQt4.QtCore import Qt
+
+import salome
+from salome.kernel.studyedit import getStudyEditor
+from salome.kernel.parametric import study_exchange_vars
+
+# ---------------------------------- #
+# Dialog box for variables selection #
+# ---------------------------------- #
+
+from SelectVarsDialog_ui import Ui_SelectVarsDialog
+
+class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog):
+
+ def __init__(self, parent = None, modal = 0):
+ QtGui.QDialog.__init__(self, parent)
+ Ui_SelectVarsDialog.__init__(self)
+ self.setupUi(self)
+ self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self.close)
+ self.connect(self.OKButton, QtCore.SIGNAL("clicked()"), self.accept)
+ self.connect(self.selectButton, QtCore.SIGNAL("clicked()"), self.initPotentialVariablesFromSelection)
+ self.connect(self.addInputVarButton, QtCore.SIGNAL("clicked()"), self.addSelectedInputVar)
+ self.connect(self.removeInputVarButton, QtCore.SIGNAL("clicked()"), self.removeSelectedInputVar)
+ self.connect(self.newInputVarButton, QtCore.SIGNAL("clicked()"), self.newInputVar)
+ self.connect(self.addOutputVarButton, QtCore.SIGNAL("clicked()"), self.addSelectedOutputVar)
+ self.connect(self.removeOutputVarButton, QtCore.SIGNAL("clicked()"), self.removeSelectedOutputVar)
+ self.connect(self.newOutputVarButton, QtCore.SIGNAL("clicked()"), self.newOutputVar)
+ self.connect(self.loadVarsButton, QtCore.SIGNAL("clicked()"), self.loadVars)
+ self.connect(self.saveVarsButton, QtCore.SIGNAL("clicked()"), self.saveVars)
+ self.refEntry = None
+
+ def setExchangeVariables(self, exchangeVariables):
+ if exchangeVariables.refEntry is not None:
+ self._initPotentialVariables(exchangeVariables.refEntry)
+ self.selectedInputVarListWidget.addItems([x.name for x in exchangeVariables.inputVarList])
+ self.selectedOutputVarListWidget.addItems([x.name for x in exchangeVariables.outputVarList])
+
+ def initPotentialVariablesFromSelection(self):
+ entries = salome.sg.getAllSelected()
+ if len(entries) != 1 :
+ QtGui.QMessageBox.warning(self, self.tr("Error"),
+ self.tr("One item must be selected in the object browser"))
+ return
+ selectedEntry = entries[0]
+ self._initPotentialVariables(selectedEntry)
+
+ def _initPotentialVariables(self, entry):
+ sobj = getStudyEditor().study.FindObjectID(entry)
+ if sobj is None:
+ QtGui.QMessageBox.warning(self, self.tr("Error"),
+ self.tr('No item at entry %s' % entry))
+ return
+ exchangeVariables = study_exchange_vars.getExchangeVariablesFromSObject(sobj)
+ if exchangeVariables is None:
+ QtGui.QMessageBox.warning(self, self.tr("Error"),
+ self.tr('Item at entry %s is not a valid '
+ '"Variable List" object' % entry))
+ return
+ self.refEntry = entry
+ self.varListObjLineEdit.setText(sobj.GetName())
+ self.allInputVarListWidget.clear()
+ self.allOutputVarListWidget.clear()
+ self.allInputVarListWidget.addItems([x.name for x in exchangeVariables.inputVarList])
+ self.allOutputVarListWidget.addItems([x.name for x in exchangeVariables.outputVarList])
+
+ def addSelectedInputVar(self):
+ for item in self.allInputVarListWidget.selectedItems():
+ self.selectedInputVarListWidget.addItem(QtGui.QListWidgetItem(item))
+
+ def removeSelectedInputVar(self):
+ for item in self.selectedInputVarListWidget.selectedItems():
+ self.selectedInputVarListWidget.takeItem(self.selectedInputVarListWidget.row(item))
+
+ def newInputVar(self):
+ newItem = QtGui.QListWidgetItem("TO EDIT!")
+ newItem.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsUserCheckable|Qt.ItemIsEnabled)
+ self.selectedInputVarListWidget.addItem(newItem);
+
+ def addSelectedOutputVar(self):
+ for item in self.allOutputVarListWidget.selectedItems():
+ self.selectedOutputVarListWidget.addItem(QtGui.QListWidgetItem(item))
+
+ def removeSelectedOutputVar(self):
+ for item in self.selectedOutputVarListWidget.selectedItems():
+ self.selectedOutputVarListWidget.takeItem(self.selectedOutputVarListWidget.row(item))
+
+ def newOutputVar(self):
+ newItem = QtGui.QListWidgetItem("TO EDIT!")
+ newItem.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsUserCheckable|Qt.ItemIsEnabled)
+ self.selectedOutputVarListWidget.addItem(newItem);
+
+ def getSelectedExchangeVariables(self):
+ inputVarList = []
+ outputVarList = []
+ for row in range(self.selectedInputVarListWidget.count()):
+ name = str(self.selectedInputVarListWidget.item(row).text())
+ inputVarList.append(study_exchange_vars.Variable(name))
+ for row in range(self.selectedOutputVarListWidget.count()):
+ name = str(self.selectedOutputVarListWidget.item(row).text())
+ outputVarList.append(study_exchange_vars.Variable(name))
+ return study_exchange_vars.ExchangeVariables(inputVarList, outputVarList, self.refEntry)
+
+ def loadVars(self):
+ filename = QtGui.QFileDialog.getOpenFileName(self, self.tr("Import variables from file"),
+ os.getenv("HOME"),
+ self.tr("XML Files (*.xml)"))
+ if not filename:
+ return
+ try:
+ filename = str(filename)
+ exchange_variables = study_exchange_vars.loadExchangeVariablesFromXmlFile(filename)
+ self.setExchangeVariables(exchange_variables)
+ except Exception, e:
+ QtGui.QMessageBox.critical(self, self.tr("Error"),
+ self.tr("Cannot load file %s:\n%s" % (filename, e)))
+
+ def saveVars(self):
+ default = os.path.join(os.getenv("HOME"), "vars.xml")
+ filename = QtGui.QFileDialog.getSaveFileName(self, self.tr("Export variables to file"),
+ default, self.tr("XML Files (*.xml)"))
+ if not filename:
+ return
+ try:
+ filename = str(filename)
+ exchange_variables = self.getSelectedExchangeVariables()
+ exchange_variables.saveToXmlFile(filename)
+ except Exception, e:
+ QtGui.QMessageBox.critical(self, self.tr("Error"),
+ self.tr("Cannot save file %s:\n%s" % (filename, e)))
--- /dev/null
+# Copyright (C) 2011-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF/R&D)
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# header files
+salomeinclude_HEADERS = \
+ QtHelper.hxx \
+ SALOME_GuiServices.hxx \
+ SALOME_AppStudyEditor.hxx \
+ StandardApp_Module.hxx
+
+# Libraries targets
+lib_LTLIBRARIES = libSalomeGuiHelpers.la
+
+dist_libSalomeGuiHelpers_la_SOURCES = \
+ SALOME_GuiServices.cxx \
+ SALOME_AppStudyEditor.cxx \
+ StandardApp_Module.cxx
+
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+CAS_CXXFLAGS=@CAS_CPPFLAGS@ @CAS_CXXFLAGS@
+BOOST_CPPFLAGS=@BOOST_CPPFLAGS@
+BOOST_LIBS=@BOOST_LIBS@
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+
+libSalomeGuiHelpers_la_CPPFLAGS = \
+ $(QT_CXXFLAGS) \
+ $(CAS_CXXFLAGS) \
+ $(BOOST_CPPFLAGS) \
+ $(CORBA_CXXFLAGS) \
+ $(KERNEL_CXXFLAGS) \
+ -I$(srcdir)/../SalomeApp \
+ -I$(srcdir)/../LightApp \
+ -I$(srcdir)/../SUIT \
+ -I$(srcdir)/../Qtx \
+ -I$(srcdir)/../CAM \
+ -I$(srcdir)/../STD \
+ -I$(srcdir)/../OBJECT
+
+
+libSalomeGuiHelpers_la_LDFLAGS = \
+ ../SalomeApp/libSalomeApp.la \
+ $(KERNEL_LDFLAGS) -lSalomeKernelHelpers \
+ $(CORBA_LIBS)
+
+#
+# =======================================================
+# Specific definitions for Qt MOC files
+#
+
+# moc-files generation
+%_moc.cxx: %.hxx
+ $(MOC) $< -o $@
+
+# MOC pre-processing
+MOC_FILES_HXX = \
+ StandardApp_Module_moc.cxx
+
+nodist_libSalomeGuiHelpers_la_SOURCES = $(MOC_FILES_HXX)
+
+EXTRA_DIST+=$(MOC_FILES_HXX:%_moc.cxx=%.hxx)
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _QT_HELPER_HXX_
+#define _QT_HELPER_HXX_
+
+//
+// =============================================================
+// Macro and template functions for type conversions.
+// =============================================================
+//
+#include "Basics_Utils.hxx" // To get ToString macro
+#include <QString>
+
+// This can be used to convert QString into char *.
+#define QCHARSTAR(qstring) qstring.toLatin1().data()
+// This converts a string into a QString
+#define S2QS(string) QString(string.c_str())
+// This converts a QString into a string
+#define QS2S(qstring) ToString(QCHARSTAR(qstring))
+#define QSTRING(any) S2QS(ToString(any))
+
+//
+// =============================================================
+// General helper macros for manipulating widgets values
+// =============================================================
+//
+#define GETTEXT(widget) ToString(QCHARSTAR(widget->text().trimmed()))
+#define SETTEXT(widget,str) widget->setText(str.c_str())
+
+//
+// =============================================================
+// Qt Logger macros
+// =============================================================
+//
+
+// We can use the macros defined by SALOMELocalTrace/utilities.h
+// as proposed in the file KERNEL_helper.hxx. But we can use instead
+// the Qt debug function:
+#include <QDebug>
+#define QDEBUG qWarning()
+//#define QDEBUG qDebug()
+#define QLOG(data) QDEBUG << "[XSALOME] " << data
+#ifdef LOG
+#undef LOG
+#endif
+#define LOG QLOG
+
+#endif // __QT_HELPER_H_
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "SALOME_AppStudyEditor.hxx"
+
+#include <SalomeApp_Study.h>
+#include <SALOME_ListIO.hxx>
+#include <LightApp_SelectionMgr.h>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+SALOME_AppStudyEditor::SALOME_AppStudyEditor(SalomeApp_Application * salomeApp)
+ : SALOME_StudyEditor()
+{
+ _salomeApp = salomeApp;
+ updateActiveStudy();
+}
+
+/**
+ * This updates the editor with the current active study. If the
+ * active study id is identical to the study id currently associated
+ * to this object, then no update is performed.
+ */
+int SALOME_AppStudyEditor::updateActiveStudy() {
+ int activeStudyId = SALOME_AppStudyEditor::getActiveStudyId(_salomeApp);
+ if ( activeStudyId != this->getStudyId() ) {
+ this->setStudyById(activeStudyId);
+ }
+ return activeStudyId;
+}
+
+// GUI context only
+int SALOME_AppStudyEditor::getActiveStudyId(SalomeApp_Application * salomeApp) {
+ SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*> (salomeApp->activeStudy());
+ _PTR(Study) aCStudy = appStudy->studyDS();
+ int studyId = aCStudy->StudyId();
+ return studyId;
+}
+
+SALOMEDS::SObject_ptr SALOME_AppStudyEditor::IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject) {
+ if (!iobject.IsNull()) {
+ if (iobject->hasEntry()) {
+ SALOMEDS::SObject_var sobject = _study->FindObjectID(iobject->getEntry());
+ return sobject._retn();
+ }
+ }
+ return SALOMEDS::SObject::_nil();
+}
+
+/**
+ * This function creates a list of all the "study objects" (SObject)
+ * that map with the selection in the object browser (the "interactive
+ * objects", IObjects). Please note that the objects belongs to the
+ * active study.
+ */
+SALOME_StudyEditor::SObjectList * SALOME_AppStudyEditor::getSelectedObjects() {
+
+ // _GBO_: please note that the use of this function can be
+ // underoptimal in the case where the number of selected objects is
+ // high, because we create a vector list of SObjects while the list
+ // of IObject can be processed directly. In the case where a high
+ // number of objects is selected (~1000), it's certainly better to
+ // use directly the SALOME_ListIO and iterators on it.
+
+ LightApp_SelectionMgr* aSelectionMgr = _salomeApp->selectionMgr();
+ SALOME_ListIO selectedIObjects;
+ aSelectionMgr->selectedObjects(selectedIObjects);
+ /*
+ * This returns a list containing the selected objects of the objects
+ * browser. Please note that the objects of the browser ARE NOT the
+ * objects of the study. What is returned by this function is a list
+ * of "interactive objects" (IObject) which are objects of the
+ * graphical context. Each of this IObject is characterized by an
+ * entry string that corresponds to the entry string of an associated
+ * "study object" (SObject) in the active study. The mapping can be
+ * done using the function IObjectToSObject.
+ */
+
+ SObjectList * listOfSObject = new SObjectList();
+ SALOME_ListIteratorOfListIO It (selectedIObjects);
+ for (; It.More(); It.Next()) {
+ SALOMEDS::SObject_ptr sobject = this->IObjectToSObject(It.Value());
+ if (!sobject->_is_nil()) {
+ listOfSObject->push_back(sobject);
+ }
+ }
+
+ return listOfSObject;
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef __APP_STUDY_EDITOR_HXX__
+#define __APP_STUDY_EDITOR_HXX__
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include <SalomeApp_Application.h>
+#include <SALOME_InteractiveObject.hxx>
+
+#include "SALOME_StudyEditor.hxx"
+
+class SALOME_AppStudyEditor: public SALOME_StudyEditor {
+public:
+ SALOME_AppStudyEditor(SalomeApp_Application * salomeApp);
+ int updateActiveStudy();
+
+ SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject);
+ SALOME_StudyEditor::SObjectList * getSelectedObjects();
+
+ static int getActiveStudyId(SalomeApp_Application * salomeApp);
+
+private:
+ SalomeApp_Application * _salomeApp;
+
+};
+
+#endif // __APP_STUDY_EDITOR_HXX__
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "SALOME_GuiServices.hxx"
+#include <SUIT_Session.h>
+
+namespace GUI {
+ /*!
+ * Get the SALOME application, i.e. the main GUI framework of
+ * SALOME. This function returns a pointer to the singleton instance
+ * of the SalomeApp_Application.
+ *
+ * The SALOME application can be used to get reference to
+ * the SALOME KERNEL services such that the naming service, the
+ * lifeCycleCORBA, ... Theses services can be retrieved using static
+ * functions (not required to get the singleton instance):
+ *
+ * SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
+ *
+ * Please note that this usage can be done only from within the
+ * SALOME session server process, i.e. the process that embed the
+ * SALOME application.
+ */
+ SalomeApp_Application * getSalomeApplication() {
+ static SalomeApp_Application * app;
+ if ( app == NULL ) {
+ app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ }
+ return app;
+ }
+
+ /*!
+ * Get the selection manager of the SALOME application. The
+ * selection manager can be used to get the selected items in the
+ * objects browser that is a GUI display of the active study.
+ * The function returns a pointer to the selectionMgr attribute of
+ * the SalomeApp_Application singleton instance.
+ */
+ LightApp_SelectionMgr * getSelectionManager() {
+ SalomeApp_Application* anApp = GUI::getSalomeApplication();
+ if ( anApp == NULL ) return NULL;
+ return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
+ }
+
+
+ SUIT_ResourceMgr * getResourcesManager() {
+ return SUIT_Session::session()->resourceMgr();
+ }
+ // Note that the resource manager can be also retrieved from the
+ // SALOME application using the resourceMgr() method:
+ //
+
+ /**
+ * This returns the current active study id if an active study is
+ * defined in the SALOME session, returns -1 otherwise. Note that
+ * the active study doesn't make sense outside of the GUI SALOME
+ * process, i.e. the SALOME_SessionServer embedding the
+ * SalomeApp_Application.
+ */
+ int getActiveStudyId() {
+ SALOME::Session_var aSession = KERNEL::getSalomeSession();
+ if ( CORBA::is_nil(aSession) ) {
+ INFOS("ERR: can't request for active study because the session is NULL");
+ return -1;
+ }
+ return aSession->GetActiveStudyId();
+ }
+
+ /**
+ * This returns the current active study if an active study is
+ * defined in the SALOME session, returns null otherwise.
+ */
+ SALOMEDS::Study_ptr getActiveStudy() {
+ return KERNEL::getStudyById(getActiveStudyId());
+ }
+
+
+ // __GBO__ Question: what is the difference between a
+ // SALOMEDS::Study and a SalomeApp_Study?
+ SalomeApp_Study* getSalomeAppActiveStudy() {
+ SUIT_Application* app = getSalomeApplication();
+ if( app )
+ return dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+ else
+ return NULL;
+ }
+
+
+ SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject) {
+ if (!iobject.IsNull()) {
+ if (iobject->hasEntry()) {
+ SalomeApp_Study* appStudy = getSalomeAppActiveStudy();
+ if ( appStudy != NULL ) {
+ //
+ // IMPORTANT NOTE:
+ //
+ // Note that the SalomeApp_Study give acces to shared
+ // pointer (i.e. _PTR(<BaseClassName>)) that points to proxy
+ // objects (i.e. SALOMEDSClien_<BaseClassName>) that embeds
+ // the CORBA servants (i.e. SALOMEDS::<BaseClassName>_ptr).
+ // Then to retrieve the corba servant, a method is to
+ // retrieve the SALOMEDS::Study servant first and the to
+ // request this servant to get the SObject given its entry.
+ //
+ _PTR(Study) studyClient = appStudy->studyDS();
+ SALOMEDS::Study_var study = KERNEL::getStudyManager()->GetStudyByID(studyClient->StudyId());
+ SALOMEDS::SObject_ptr sobject = study->FindObjectID(iobject->getEntry());
+ return sobject;
+ }
+ }
+ }
+ return SALOMEDS::SObject::_nil();
+ }
+
+}
+
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef __GUI_SERVICES_H__
+#define __GUI_SERVICES_H__
+
+#include <SalomeApp_Application.h>
+#include <SalomeApp_Study.h>
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_ResourceMgr.h>
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOMEDS)
+#include <SALOME_InteractiveObject.hxx>
+#include <SALOME_KernelServices.hxx>
+
+namespace GUI {
+
+ // SALOME GUI main services
+ SalomeApp_Application * getSalomeApplication();
+ LightApp_SelectionMgr * getSelectionManager();
+ SUIT_ResourceMgr * getResourcesManager();
+
+ // Helper functions to deal with the study in a GUI context.
+ //
+ // First of all, in a GUI context, there is one of the opened
+ // studies that is considered as active. Please note that the active
+ // study is a GUI concept and it can be obtained only in the
+ // SALOME_SessionServer process, i.e. the process that embeds the
+ // SalomeApp_Application. The concept of active study doesn't make
+ // sense outside of the GUI context.
+ //
+ // The active study is associated with an GUI Objects Browser that
+ // displays a graphical representation of the study. The items that
+ // can be selected in the Objects Browser are name Interactive
+ // Objects (instance of class SALOME_InteractiveObject). To work
+ // with data, we have to retrieve from this Interactive Object (IO)
+ // the underlying Study Object (instance of class SALOMEDS::SObject)
+ // and from this last the data object that can be anything (that
+ // depends of the SALOME module technical choices). In general, on
+ // of the attribute of a SObject is a CORBA servant that handles the
+ // data to work with
+ SALOMEDS::Study_ptr getActiveStudy();
+ int getActiveStudyId();
+
+ // Another way to get the active study (to be converted in
+ // SALOMEDS::Study):
+ SalomeApp_Study * getSalomeAppActiveStudy();
+
+ SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject);
+
+ template<class TInterface> typename TInterface::_var_type
+ IObjectToInterface(const Handle(SALOME_InteractiveObject)& iobject) {
+ SALOMEDS::SObject_ptr sobject = IObjectToSObject(iobject);
+ return KERNEL::SObjectToInterface<TInterface>(sobject);
+ }
+ // _MEM_: note that template functions have to be declared AND
+ // implemented in the header because they are not compiled in this
+ // library but in every client library that includes this header
+ // file. The effective compilation depends on the particular class
+ // used for TInterface.
+
+
+}
+
+#endif // GUI_SERVICES
--- /dev/null
+// Copyright (C) 2011-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Guillaume Boulant (EDF)
+
+#include "StandardApp_Module.hxx"
+
+#include <SUIT_Desktop.h>
+#include <SUIT_Study.h>
+#include <SalomeApp_Application.h>
+#include <SALOME_LifeCycleCORBA.hxx>
+#include "QtxPopupMgr.h"
+
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
+
+// QT Includes
+#include <QIcon>
+#include <QAction>
+
+#include <Basics_Utils.hxx>
+#include "QtHelper.hxx"
+
+// Constructor
+StandardApp_Module::StandardApp_Module() :
+ SalomeApp_Module( "" ),
+ LightApp_Module( "" )
+{
+ // Note that it's no use to specify here the moduleName because it's
+ // automatically determined by the name of the GUI library
+ // (lib<moduleName>.so) just before initialize step. If you want
+ // nevertheless to setup the module name you should specified this
+ // name in the initialize function below using the CAM_module
+ // function setModuleName(QString&). You are warn then that the
+ // loading of resource files may be incorect and should be manually
+ // managed. In conclusion, if you don't need a special
+ // configuration, please conform to the standard convention: if
+ // <moduleName> is the name of the module as declared in the GUI
+ // configuration file (SalomeApp.xml), then you just have to provide
+ // a library whose name is lib<moduleName>.so and which contains a
+ // factory "extern C" function 'CAM_Module* createModule()'
+}
+
+int StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE = 910;
+int StandardApp_Module::ACTIONID_UNDEFINED = -1;
+
+// Module's initialization
+void StandardApp_Module::initialize( CAM_Application* app )
+{
+ //
+ // ----------------------------------------------------------------
+ // Standard initialization
+ // ----------------------------------------------------------------
+ //
+ SalomeApp_Module::initialize( app );
+ _resourceMgr = app->resourceMgr();
+ // Please note that the moduleName() function is inherited from
+ // CAM_module classe, and that its value is determined automatically
+ // from the name specified in the SalomeApp.xml associated to this
+ // module and which corresponds to the name of the GUI library
+ // (lib<moduleName>.so). For XSALOME, see
+ // share/salome/resources/xsalome/SalomeApp.xml in the install
+ // directory.
+ _defaultMenuId = this->createMenu( QCHARSTAR(moduleName()), -1, -1, 30 );
+ _defaultToolbarId = this->createTool ( QCHARSTAR(moduleName()) );
+ _actionId_internalCount = StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE;
+
+ //
+ // ----------------------------------------------------------------
+ // The following initializes the GUI widget and associated actions
+ // ----------------------------------------------------------------
+ // These functions may be redefined in specialized version of this class
+ this->createModuleWidgets();
+ this->createModuleActions();
+}
+
+QIcon StandardApp_Module::createIcon(const QString& iconName) {
+ // The icon file is supposed to be available througth the resource
+ // manager, i.e. in the folder containing the XSALOME resources (see
+ // specification in the module file SalomeApp.xml).
+ QPixmap aPixmap = _resourceMgr->loadPixmap( QCHARSTAR(moduleName()), iconName );
+ return QIcon( aPixmap );
+}
+
+int StandardApp_Module::newActionId() {
+ _actionId_internalCount++;
+ return _actionId_internalCount;
+}
+
+/*!
+ * This function creates an action and connects it to a button in the
+ * toolbar and to an item in the menu associated to this module. This
+ * function applies a common and standard procedure with a maximum of
+ * default values. If no identifier is specified, then a static
+ * internal counter is used to associate an identifier to the created
+ * action. In any case, the action identifier is returned.
+ *
+ * Note that the action (object of type QAction) can be retrieved
+ * using the method "QAction * action(int identifier)" of the super
+ * class.
+ */
+int StandardApp_Module::createStandardAction(const QString& label,
+ QObject * slotobject,
+ const char* slotmember,
+ const QString& iconName,
+ const QString& tooltip,
+ const int identifier)
+{
+
+ // If the tooltip is not defined, we choose instead the label text.
+ QString effToolTip(tooltip);
+ if ( effToolTip.isEmpty() )
+ effToolTip = label;
+
+ QIcon actionIcon = this->createIcon(iconName);
+
+ // If the identifier is not specified, then we use an internal
+ // counter.
+ int effIdentifier = identifier;
+ if ( effIdentifier == StandardApp_Module::ACTIONID_UNDEFINED ) {
+ effIdentifier=newActionId();
+ }
+
+ // Creating the action
+ QAction * action= this->createAction( effIdentifier, label, actionIcon,
+ label, effToolTip, 0, getApp()->desktop(),
+ false, slotobject, slotmember);
+
+ return effIdentifier;
+}
+
+/**
+ * Integrate the action in the default toolbar
+ */
+void StandardApp_Module::addActionInToolbar(int actionId) {
+ this->createTool( actionId, _defaultToolbarId );
+}
+
+/**
+ * Integrate the action in the default menu
+ */
+void StandardApp_Module::addActionInMenubar(int actionId) {
+ this->createMenu( actionId, _defaultMenuId, 10 );
+}
+
+/**
+ * Add the specified action as an item in the popup menu, with the
+ * specified visible rule. The default is "visible for object browser".
+ */
+void StandardApp_Module::addActionInPopupMenu(int actionId,const QString& rule) {
+ // _GBO_ for a fine customization of the rule (for example with a
+ // test on the type of the selected object), see the LIGTH module:
+ // implement "LightApp_Selection* createSelection() const;"
+ int parentId = -1;
+ QtxPopupMgr* mgr = this->popupMgr();
+ mgr->insert ( this->action( actionId ), parentId, 0 );
+ mgr->setRule( this->action( actionId ), rule, QtxPopupMgr::VisibleRule );
+}
+
+/*!
+ * This function can be used to create additionnal widget for this
+ * module GUI (e.g. docked widget). It can be redefined in a
+ * specialized version of this class.
+ */
+void StandardApp_Module::createModuleWidgets() {
+ // Nothing to do in this default gui
+}
+
+/*!
+ * This function can be used to defined the list of actions for this
+ * module GUI. It can be redefined in a specialized version of this
+ * class.
+ * Depending on wether you use the method "createStandardAction" or
+ * not, the actions will be automatically plugged in the toolbar and
+ * the menu associated to the module.
+ */
+void StandardApp_Module::createModuleActions() {
+ int actionId = this->createStandardAction("Test", this, SLOT(OnTest()),
+ "f1.png", "Run the default test function");
+ this->addActionInToolbar(actionId);
+}
+
+// Get compatible dockable windows.
+void StandardApp_Module::windows( QMap<int, int>& theMap ) const
+{
+ theMap.clear();
+ theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+ theMap.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
+}
+
+// Module's engine IOR
+QString StandardApp_Module::engineIOR() const
+{
+ CORBA::String_var anIOR = getApp()->orb()->object_to_string(getEngine());
+ return QString( anIOR.in() );
+}
+
+/*!
+ * This specifies the filename for the icon to be used for the study
+ * component associated to the module. Note that this icon could be
+ * different than the module icon which is defined by the
+ * SalomeApp.xml file dedicated to this module (see the shared
+ * resources folder dedicated to the module) and which is used for the
+ * toolbar of the SALOME application.
+ */
+QString StandardApp_Module::studyIconName()
+{
+ // By default, we return the module icone name
+ return iconName(); // inherited from CAM_Module
+}
+
+/*!
+ * This can be used to switch the layout of main application
+ * dockwidgets to one of the predefined configuration (see enum
+ * DockLayoutType). When a layout is set, the previous layout is
+ * memorized and can be restored using the unsetDockLayout function (1
+ * step undo). It is typically to be used in the functions
+ * activateModule to setup the layout and deactivateModule to unset
+ * the layout, i.e. restore to the previous state.
+ */
+void StandardApp_Module::setDockLayout(DockLayoutType layoutType) {
+ SUIT_Desktop* desk = getApp()->desktop();
+ _areaAtBottomLeftCorner = desk->corner(Qt::BottomLeftCorner);
+ _areaAtBottomRightCorner = desk->corner(Qt::BottomRightCorner);
+
+ if ( layoutType == DOCKLAYOUT_LEFT_VLARGE ) {
+ desk->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+ desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+ } else {
+ desk->setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
+ desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+ }
+}
+
+/*!
+ * This function restores the layout state that was previously in
+ * place before the last setDockLayout call.
+ */
+void StandardApp_Module::unsetDockLayout() {
+ SUIT_Desktop* desk = getApp()->desktop();
+ desk->setCorner(Qt::BottomLeftCorner, _areaAtBottomLeftCorner);
+ desk->setCorner(Qt::BottomRightCorner, _areaAtBottomRightCorner);
+}
+
+// Module's activation
+bool StandardApp_Module::activateModule( SUIT_Study* theStudy )
+{
+ bool bOk = SalomeApp_Module::activateModule( theStudy );
+
+ setMenuShown( true );
+ setToolShown( true );
+
+ if ( this->createStudyComponentAtActivation() ) {
+ this->createStudyComponent(theStudy);
+ }
+
+ return bOk;
+}
+
+/*!
+ * This function should be implemented in a specialized class and must
+ * return true if you want to automatically create a study component
+ * for this module at activation step (when you first load the module
+ * for a given study). The default function return true.
+ */
+bool StandardApp_Module::createStudyComponentAtActivation() {
+ return true;
+}
+
+/*!
+ * This creates a root entry in the active study for this module, i.e
+ * a SComponent with the name of the module and the icon specified for
+ * the module. This component is associated to the engine (return by
+ * getEngine()) if the engine is a SALOMEDS::Driver.
+ */
+void StandardApp_Module::createStudyComponent(SUIT_Study* theStudy) {
+
+ SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
+ CORBA::Object_var aSMObject = aNamingService->Resolve("/myStudyManager");
+ SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(aSMObject);
+ SALOMEDS::Study_var aDSStudy = aStudyManager->GetStudyByID(theStudy->id());
+
+ SALOMEDS::SComponent_var aFather = aDSStudy->FindComponent(QCHARSTAR(moduleName()));
+ if (aFather->_is_nil())
+ {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = aDSStudy->NewBuilder();
+ aFather = aStudyBuilder->NewComponent(QCHARSTAR(moduleName()));
+ SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
+ SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ aName->SetValue(QCHARSTAR(moduleName()));
+ aName->Destroy();
+ anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
+ SALOMEDS::AttributePixMap_var aPixMap = SALOMEDS::AttributePixMap::_narrow(anAttr);
+ aPixMap->SetPixMap(QCHARSTAR(studyIconName()));
+
+ // WARN: The engine should be associated to the SComponent IF
+ // AND ONLY IF it is a SALOMEDS::Driver. Otherwise, there is no
+ // need to do that, and it could even lead to exception
+ // raising (eh, you work on SALOME isn't it?)
+ SALOMEDS::Driver_var driver = SALOMEDS::Driver::_narrow(this->getEngine());
+ if ( ! driver->_is_nil() ) {
+ STDLOG("Associate the SComponent to the engine");
+ aStudyBuilder->DefineComponentInstance(aFather, this->getEngine());
+ }
+ }
+
+}
+
+// Module's deactivation
+bool StandardApp_Module::deactivateModule( SUIT_Study* theStudy )
+{
+ setMenuShown( false );
+ setToolShown( false );
+
+ return SalomeApp_Module::deactivateModule( theStudy );
+}
+
+void StandardApp_Module::OnTest()
+{
+ // Just for test
+ STDLOG("OnTest: engine IOR = "<<QCHARSTAR(engineIOR()));
+}
+
--- /dev/null
+// Copyright (C) 2011-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Guillaume Boulant (EDF)
+
+#ifndef _STANDARDAPP_MODULE_HXX_
+#define _STANDARDAPP_MODULE_HXX_
+
+#include <SUIT_ResourceMgr.h>
+#include <SalomeApp_Module.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Component)
+
+#include <QString>
+
+/*!
+ * This class is provided as the base class for the standard gui part
+ * of a SALOME module. To define a gui part, you just have to
+ * implement the virtual functions:
+ * - getEngine() to specify the engine component associated to this module
+ * - createModuleActions(...) to specify the action functions
+ * - createModuleWidgets(...) to specify special additionnal widgets
+ *
+ * The gui part of a SALOME module is an extension of the SALOME
+ * client Application for this module. Technically speaking, it
+ * consists in a plugin that provides a derived class of CAM_Module
+ * (provided by the GUI module).
+ *
+ * A standard gui is the standard design for most of SALOME module
+ * (object browser on the left, viewer on the rigth, python console on
+ * the bottom, and toolbox in the toolbar with standard definition of
+ * the tool function). This standard design suggests also to specify
+ * the engine associated to the module by implementing the virtual
+ * pure function getEngine(). The engine of a module is the SALOME
+ * component that is associated to the study component for this
+ * module, and generally which is responsible for the persistency
+ * functions or data management for the module.
+ *
+ * See a use case example in the test module Xsalome provided by the
+ * test package (tst/module/gui/Xsalome.hxx and
+ * tst/module/gui/factory.cxx in the XSALOME library).
+ */
+class StandardApp_Module: public SalomeApp_Module
+{
+ Q_OBJECT
+
+public:
+
+ // ================================================================
+ // This part defines the standard interface of the SalomeApp_Module
+ // ================================================================
+
+ StandardApp_Module();
+ void initialize( CAM_Application* );
+ QString engineIOR() const;
+ virtual void windows( QMap<int, int>& theMap ) const;
+
+public slots:
+ bool deactivateModule( SUIT_Study* );
+ bool activateModule( SUIT_Study* );
+
+ // ================================================================
+ // This part defines the specific interface of this class
+ // ================================================================
+
+public:
+ /* Creates an action with standard default values */
+ int createStandardAction(const QString& label,
+ QObject * slotobject,
+ const char* slotmember,
+ const QString& iconName=QString(),
+ const QString& tooltip=QString(),
+ const int identifier=ACTIONID_UNDEFINED);
+
+ void addActionInToolbar(int actionId);
+ void addActionInMenubar(int actionId);
+ void addActionInPopupMenu(int actionId,const QString& rule="client='ObjectBrowser'");
+
+protected:
+ /* Implement this to create additionnal widget (e.g. docked widget) */
+ virtual void createModuleWidgets();
+ /* Implement this to define the actions for this gui */
+ virtual void createModuleActions();
+
+ /* Use this to create a root entry in the study for this module */
+ void createStudyComponent(SUIT_Study*);
+ /* Implement this to say if study component entry should be created
+ at activation step */
+ virtual bool createStudyComponentAtActivation();
+
+ /* The engine is the SALOME component associated to the study */
+ virtual Engines::EngineComponent_ptr getEngine() const = 0;
+ // Note that the function getEngine() is virtual pure and must be
+ // implemented in the specific inherited classes. Note also that the
+ // const flag is required because getEngine is used by functions
+ // with const flags (see for ex: engineIOR()).
+ virtual QString studyIconName();
+
+ QIcon createIcon(const QString& iconName);
+ int newActionId();
+
+ enum DockLayoutType {
+ DOCKLAYOUT_BOTTOM_HLARGE, // Bottom is Horizontal Large
+ DOCKLAYOUT_LEFT_VLARGE, // Left is Vertical Large
+ };
+ virtual void setDockLayout(DockLayoutType layoutType);
+ virtual void unsetDockLayout();
+
+ SUIT_ResourceMgr* _resourceMgr;
+ int _defaultMenuId;
+ int _defaultToolbarId;
+
+ static int ACTIONID_DEFAULT_INIT_VALUE;
+ static int ACTIONID_UNDEFINED;
+
+private:
+ int _actionId_internalCount;
+ Qt::DockWidgetArea _areaAtBottomLeftCorner;
+ Qt::DockWidgetArea _areaAtBottomRightCorner;
+
+ // =========================================================
+ // This part defines slots for test purposes
+ // =========================================================
+
+protected slots:
+ void OnTest();
+};
+
+#endif
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# File : Makefile.am
+# Author : Oleg UVAROV
+# Module : SALOME
+# $Header$
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+lib_LTLIBRARIES = libOpenGLUtils.la
+
+salomeinclude_HEADERS = \
+ OpenGLUtils.h \
+ OpenGLUtils_FrameBuffer.h
+
+dist_libOpenGLUtils_la_SOURCES = \
+ OpenGLUtils_FrameBuffer.cxx
+
+libOpenGLUtils_la_CPPFLAGS = $(OGL_INCLUDES)
+libOpenGLUtils_la_LDFLAGS = $(KERNEL_LDFLAGS)
+
+libOpenGLUtils_la_LIBADD = $(OGL_LIBS) -lSALOMELocalTrace
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#if !defined ( OPENGLUTILS_H )
+#define OPENGLUTILS_H
+
+#ifdef WIN32
+# if defined OPENGLUTILS_EXPORTS || defined OpenGLUtils_EXPORTS
+# define OPENGLUTILS_EXPORT __declspec(dllexport)
+# else
+# define OPENGLUTILS_EXPORT __declspec(dllimport)
+# endif
+#else
+# define OPENGLUTILS_EXPORT
+#endif
+
+#if defined WIN32
+#pragma warning ( disable: 4251 )
+#endif
+
+#endif // OPENGLUTILS_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File : OpenGLUtils_FrameBuffer.cxx
+// Module : SALOME
+//
+#include "OpenGLUtils_FrameBuffer.h"
+
+#include <utilities.h>
+
+#include <cstring>
+
+#ifndef WNT
+# ifndef GLX_GLXEXT_LEGACY
+# define GLX_GLXEXT_LEGACY
+# endif
+# include <GL/glx.h>
+# include <dlfcn.h>
+#else
+# include <wingdi.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+
+#ifndef GL_FRAMEBUFFER_EXT
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#endif
+
+#ifndef GL_RENDERBUFFER_EXT
+#define GL_RENDERBUFFER_EXT 0x8D41
+#endif
+
+#ifndef GL_COLOR_ATTACHMENT0_EXT
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#endif
+
+#ifndef GL_DEPTH_ATTACHMENT_EXT
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#endif
+
+#ifndef GL_FRAMEBUFFER_COMPLETE_EXT
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#endif
+
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+
+static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL;
+static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL;
+static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL;
+static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL;
+static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL;
+static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL;
+static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL;
+static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL;
+static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL;
+static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL;
+
+#ifndef WNT
+#define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
+#else
+#define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
+#endif
+
+bool InitializeEXT()
+{
+ vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" );
+ vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" );
+ vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" );
+ vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" );
+ vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" );
+ vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" );
+ vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" );
+ vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" );
+ vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" );
+ vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" );
+
+ bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT &&
+ vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT &&
+ vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT &&
+ vglDeleteRenderbuffersEXT;
+
+ return ok;
+}
+
+static bool IsEXTInitialized = InitializeEXT();
+
+OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer()
+ : textureId( 0 ),
+ fboId( 0 ),
+ rboId( 0 )
+{
+}
+
+OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer()
+{
+ release();
+}
+
+bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize )
+{
+ char* ext = (char*)glGetString( GL_EXTENSIONS );
+ if( !IsEXTInitialized ||
+ strstr( ext, "GL_EXT_framebuffer_object" ) == NULL )
+ {
+ MESSAGE( "Initializing OpenGL FrameBuffer extension failed" );
+ return false;
+ }
+
+ // create a texture object
+ glEnable( GL_TEXTURE_2D );
+ glGenTextures( 1, &textureId );
+ glBindTexture( GL_TEXTURE_2D, textureId );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+
+ // create a renderbuffer object to store depth info
+ vglGenRenderbuffersEXT( 1, &rboId );
+ vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId );
+ vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize );
+ vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
+
+ // create a framebuffer object
+ vglGenFramebuffersEXT( 1, &fboId );
+ vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
+
+ // attach the texture to FBO color attachment point
+ vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 );
+
+ // attach the renderbuffer to depth attachment point
+ vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId );
+
+ // check FBO status
+ GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
+
+ // Unbind FBO
+ vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+
+ return status == GL_FRAMEBUFFER_COMPLETE_EXT;
+}
+
+void OpenGLUtils_FrameBuffer::release()
+{
+ if( !IsEXTInitialized )
+ return;
+
+ glDeleteTextures( 1, &textureId );
+ textureId = 0;
+
+ vglDeleteFramebuffersEXT( 1, &fboId );
+ fboId = 0;
+
+ vglDeleteRenderbuffersEXT( 1, &rboId );
+ rboId = 0;
+}
+
+void OpenGLUtils_FrameBuffer::bind()
+{
+ if( !IsEXTInitialized )
+ return;
+
+ vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
+}
+
+void OpenGLUtils_FrameBuffer::unbind()
+{
+ if( !IsEXTInitialized )
+ return;
+
+ vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File : OpenGLUtils_FrameBuffer.h
+// Module : SALOME
+//
+#ifndef OPENGLUTILS_FRAMEBUFFER_H
+#define OPENGLUTILS_FRAMEBUFFER_H
+
+#include "OpenGLUtils.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <GL/gl.h>
+
+class OPENGLUTILS_EXPORT OpenGLUtils_FrameBuffer
+{
+public:
+ OpenGLUtils_FrameBuffer();
+ ~OpenGLUtils_FrameBuffer();
+
+ bool init( const GLsizei&, const GLsizei& );
+ void release();
+
+ void bind();
+ void unbind();
+
+private:
+ GLuint textureId;
+ GLuint fboId;
+ GLuint rboId;
+};
+
+#endif
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+ <name>QtxTreeView</name>
+ <message>
+ <source>Enable sorting</source>
+ <translation>Autoriser le tri</translation>
+ </message>
+</context>
+<context>
+ <name>QtxWorkspaceAction</name>
+ <message>
+ <source>Arranges the windows as overlapping tiles</source>
+ <translation>Ranger les fenêtres en les superposant</translation>
+ </message>
+ <message>
+ <source>Cascade</source>
+ <translation>Cascade</translation>
+ </message>
+ <message>
+ <source>Arranges the windows as nonoverlapping tiles</source>
+ <translation>Ranger les fenêtres sans les superposer</translation>
+ </message>
+ <message>
+ <source>Tile</source>
+ <translation>Mosaïque</translation>
+ </message>
+ <message>
+ <source>Arranges the windows as nonoverlapping horizontal tiles</source>
+ <translation>Ranger les fenêtres en mosaïque horizontale</translation>
+ </message>
+ <message>
+ <source>Tile horizontally</source>
+ <translation>Mosaïque horizontale</translation>
+ </message>
+ <message>
+ <source>Arranges the windows as nonoverlapping vertical tiles</source>
+ <translation>Ranger les fenêtres en mosaïque verticale</translation>
+ </message>
+ <message>
+ <source>Tile vertically</source>
+ <translation>Mosaïque verticale</translation>
+ </message>
+</context>
+<context>
+ <name>QtxMainWindow</name>
+ <message>
+ <source>Menu bar</source>
+ <translation>Barre de menu</translation>
+ </message>
+ <message>
+ <source>Status bar</source>
+ <translation>Barre de statut</translation>
+ </message>
+</context>
+<context>
+ <name>QtxPathDialog</name>
+ <message>
+ <source>Open file</source>
+ <translation>Ouvrir le fichier</translation>
+ </message>
+ <message>
+ <source>Save file</source>
+ <translation>Sauvegarder le fichier</translation>
+ </message>
+ <message>
+ <source>File name</source>
+ <translation>Nom du fichier</translation>
+ </message>
+ <message>
+ <source>File name not specified</source>
+ <translation>Le nom du fichier n'est pas indiqué</translation>
+ </message>
+ <message>
+ <source>File \"%1\" does not exist</source>
+ <translation>Le fichier \"%1\" n'existe pas</translation>
+ </message>
+ <message>
+ <source>File \"%1\" already exist. Do you want to overwrite it?</source>
+ <translation>Le fichier \"%1\" existe déjà. Voulez-vous l'écraser ?</translation>
+ </message>
+ <message>
+ <source>Directory \"%1\" does not exist</source>
+ <translation>Le répertoire \"%1\" n'existe pas</translation>
+ </message>
+ <message>
+ <source>Directory \"%1\" can't be created because file with the same name exist</source>
+ <translation>Il est impossible de créer le répertoire \"%1\" parce qu'un fichier avec ce nom existe déjà</translation>
+ </message>
+ <message>
+ <source>Directory \"%1\" not empty. Do you want to remove all files in this directory?</source>
+ <translation>Le répertoire \"%1\" n'est pas vide. Voulez-vous supprimer tous les fichiers dans ce répertoire?</translation>
+ </message>
+ <message>
+ <source>File dialog</source>
+ <translation>Fenêtre de dialogue de fichiers</translation>
+ </message>
+ <message>
+ <source>All files (*.*)</source>
+ <translation>Tous les fichiers (*.*)</translation>
+ </message>
+</context>
+<context>
+ <name>QtxFontEdit</name>
+ <message>
+ <source>B</source>
+ <translatorcomment>Bold</translatorcomment>
+ <translation>G</translation>
+ </message>
+ <message>
+ <source>I</source>
+ <translatorcomment>Italic</translatorcomment>
+ <translation>I</translation>
+ </message>
+ <message>
+ <source>U</source>
+ <translatorcomment>Underline</translatorcomment>
+ <translation>S</translation>
+ </message>
+ <message>
+ <source>S</source>
+ <translatorcomment>Strikethrough</translatorcomment>
+ <translation>R</translation>
+ </message>
+</context>
+<context>
+ <name>QtxPathListEdit</name>
+ <message>
+ <source>Warning</source>
+ <translation>Avertissement</translation>
+ </message>
+ <message>
+ <source>Path \"%1\" doesn't exist. Add it to list anyway?</source>
+ <translation>Le chemin \"%1\" n'existe pas. Faut-il l'ajouter dans la liste?</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+ <message>
+ <source>Location \"%1\" doesn't point to file</source>
+ <translation>L'emplacement \"%1\" ne pointe sur aucun fichier</translation>
+ </message>
+ <message>
+ <source>Location \"%1\" doesn't point to directory</source>
+ <translation>L'emplacement \"%1\" ne pointe sur aucun répertoire</translation>
+ </message>
+ <message>
+ <source>Path \"%1\" already exist in the list</source>
+ <translation>Le chemin \"%1\" existe déjà dans la liste</translation>
+ </message>
+</context>
+<context>
+ <name>QtxMRUAction</name>
+ <message>
+ <source>Most Recently Used</source>
+ <translation>Récemment utilisés</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Effacer</translation>
+ </message>
+ <message>
+ <source><Empty></source>
+ <translation><Vide></translation>
+ </message>
+</context>
+<context>
+ <name>QtxDialog</name>
+ <message>
+ <source>&OK</source>
+ <translation>&OK</translation>
+ </message>
+ <message>
+ <source>&Cancel</source>
+ <translation>&Annuler</translation>
+ </message>
+ <message>
+ <source>C&lose</source>
+ <translation>&Fermer</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Aide</translation>
+ </message>
+ <message>
+ <source>&Apply</source>
+ <translation>A&ppliquer</translation>
+ </message>
+ <message>
+ <source>&Yes</source>
+ <translation>&Oui</translation>
+ </message>
+ <message>
+ <source>&No</source>
+ <translation>&Non</translation>
+ </message>
+</context>
+<context>
+ <name>QtxSearchTool</name>
+ <message>
+ <source>Case sensitive</source>
+ <translation>Sensible à la casse</translation>
+ </message>
+ <message>
+ <source>Regular expression</source>
+ <translation>Expression régulière</translation>
+ </message>
+ <message>
+ <source>Wrap search</source>
+ <translation>Continuer la recherche</translation>
+ </message>
+</context>
+<context>
+ <name>QtxSplash</name>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+ <message>
+ <source>&OK</source>
+ <translation>&OK</translation>
+ </message>
+</context>
+<context>
+ <name>QtxWorkstack</name>
+ <message>
+ <source>Split vertically</source>
+ <translation>Diviser verticalement</translation>
+ </message>
+ <message>
+ <source>Split horizontally</source>
+ <translation>Diviser horisontalement</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>Fermer</translation>
+ </message>
+ <message>
+ <source>Rename</source>
+ <translation>Renommer</translation>
+ </message>
+ <message>
+ <source>Enter new name:</source>
+ <translation>Indiquer un nouveau nom:</translation>
+ </message>
+</context>
+<context>
+ <name>QtxWorkstackAction</name>
+ <message>
+ <source>Split the active window on two vertical parts</source>
+ <translation>Diviser la fenêtre actuelle en deux parties verticales</translation>
+ </message>
+ <message>
+ <source>Split vertically</source>
+ <translation>Diviser verticalement</translation>
+ </message>
+ <message>
+ <source>Split the active window on two horizontal parts</source>
+ <translation>Diviser la fenêtre actuelle en deux parties horizontales</translation>
+ </message>
+ <message>
+ <source>Split horizontally</source>
+ <translation>Diviser horizontalement</translation>
+ </message>
+</context>
+<context>
+ <name>QtxColorButton</name>
+ <message>
+ <source>Auto</source>
+ <translation>Auto</translation>
+ </message>
+ <message>
+ <source>Other colors...</source>
+ <translation>Autres couleurs...</translation>
+ </message>
+</context>
+<context>
+ <name>QtxColorScale</name>
+ <message>
+ <source>Color scale</source>
+ <translation>Echelle de couleurs</translation>
+ </message>
+</context>
+<context>
+ <name>QtxBackgroundTool</name>
+ <message>
+ <source>Browse...</source>
+ <translation>Parcourir...</translation>
+ </message>
+ <message>
+ <source>Not implemented yet</source>
+ <translation>Pas encore disponible</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation>Centre</translation>
+ </message>
+ <message>
+ <source>Tile</source>
+ <translation>Mosaïque</translation>
+ </message>
+ <message>
+ <source>Stretch</source>
+ <translation>Etiré</translation>
+ </message>
+ <message>
+ <source>Images Files (*.bmp *.png *.jpg *.jpeg *.gif *.tiff)</source>
+ <translation>Fichiers images (*.bmp *.png *.jpg *.jpeg *.gif *.tiff)</translation>
+ </message>
+ <message>
+ <source>Image</source>
+ <translation>Image</translation>
+ </message>
+ <message>
+ <source>Single Color</source>
+ <translation>Couleur unique</translation>
+ </message>
+ <message>
+ <source>Custom</source>
+ <translation>Personnalisé</translation>
+ </message>
+ <message>
+ <source>Select Picture</source>
+ <translation>Choisir l'image</translation>
+ </message>
+</context>
+<context>
+ <name>QtxBackgroundDialog</name>
+ <message>
+ <source>Change background</source>
+ <translation>Modifier l'arrière plan</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# File : Makefile.am
+# Author : Roman NIKOLAEV Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# Library target
+lib_LTLIBRARIES = libSalomePyQtGUILight.la
+
+
+# extra source files (generated by sip)
+SIP_SRC = sipAPISalomePyQtGUILight.h \
+ sipSalomePyQtGUILightcmodule.cc
+
+# Sip definition file
+SIP_FILES = SALOME_PYQT_GUILight.sip
+
+# extra dist files
+EXTRA_DIST += $(SIP_FILES)
+
+
+# extra clean files
+CLEANFILES = $(SIP_SRC)
+
+# moc files (generated my moc)
+MOC_FILES = \
+ SALOME_PYQT_ModuleLight_moc.cxx \
+ SALOME_PYQT_DataModelLight_moc.cxx
+
+
+# exported header files
+salomeinclude_HEADERS = \
+ SALOME_PYQT_GUILight.h \
+ SALOME_PYQT_ModuleLight.h \
+ SALOME_PYQT_DataObjectLight.h \
+ SALOME_PYQT_DataModelLight.h \
+ SALOME_PYQT_PyInterp.h
+
+# library sources
+dist_libSalomePyQtGUILight_la_SOURCES = \
+ SALOME_PYQT_ModuleLight.cxx \
+ SALOME_PYQT_DataObjectLight.cxx \
+ SALOME_PYQT_DataModelLight.cxx \
+ SALOME_PYQT_PyInterp.cxx
+
+nodist_libSalomePyQtGUILight_la_SOURCES = $(MOC_FILES) $(SIP_SRC)
+
+
+libSalomePyQtGUILight_la_CPPFLAGS = $(QT_INCLUDES) $(SIP_INCLUDES) $(PYTHON_INCLUDES) \
+ $(CAS_CPPFLAGS) $(VTK_INCLUDES) $(OGL_INCLUDES) $(BOOST_CPPFLAGS) \
+ -DHAVE_CONFIG_H @KERNEL_CXXFLAGS@ -DCALL_OLD_METHODS \
+ -I. -I$(srcdir)/../../PyInterp -I$(srcdir)/../../PyConsole \
+ -I$(srcdir)/../../SUIT -I$(srcdir)/../../Qtx -I$(srcdir)/../../LightApp \
+ -I$(srcdir)/../../Plot2d -I$(srcdir)/../../OCCViewer \
+ -I$(srcdir)/../../CAM -I$(srcdir)/../../STD \
+ -I$(srcdir)/../../SUITApp \
+ -I$(srcdir)/../../CAM -I$(srcdir)/../../STD
+
+if GUI_ENABLE_CORBA
+libSalomePyQtGUILight_la_CPPFLAGS += -I$(srcdir)/../../SalomeApp \
+ @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
+endif
+
+
+if !GUI_ENABLE_CORBA
+ libSalomePyQtGUILight_la_CPPFLAGS += -DGUI_DISABLE_CORBA
+endif
+
+# linkage flags
+libSalomePyQtGUILight_la_LIBADD = $(PYTHON_LIBS) $(SIP_LIBS) $(PYQT_LIBS) $(VTK_LIBS) \
+ $(OGL_LIBS) ../../PyInterp/libPyInterp.la ../../LightApp/libLightApp.la
+
+if GUI_ENABLE_CORBA
+ libSalomePyQtGUILight_la_LIBADD +=../../SalomeApp/libSalomeApp.la $(KERNEL_LDFLAGS) -lSalomeContainer
+endif
+
+
+
+# Custom build step: generate C++ wrapping according to $(SIP_FILES)
+$(SIP_SRC): $(SIP_FILES)
+ $(SIP) $(PYQT_SIPFLAGS) $<
+
+# extra dependency (SALOME_PYQT_Module.cxx depends on header files generated by sip)
+$(dist_libSalomePyQtGUILight_la_SOURCES): $(SIP_SRC)
+
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+//
+#include "PyInterp_Interp.h" // // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+
+#include "SALOME_PYQT_DataModelLight.h"
+#include "SALOME_PYQT_DataObjectLight.h"
+#include "SALOME_PYQT_ModuleLight.h"
+#include <utilities.h>
+
+#include <LightApp_Study.h>
+#include <CAM_Module.h>
+#include <CAM_Application.h>
+#include <CAM_Study.h>
+
+
+//=================================================================================
+// function : SALOME_PYQT_DataModelLight()
+// purpose : constructor
+//=================================================================================
+SALOME_PYQT_DataModelLight::SALOME_PYQT_DataModelLight(CAM_Module * theModule)
+ : LightApp_DataModel( theModule ),
+ myFileName( "" ),
+ myStudyURL( "" ),
+ myModified( false )
+{
+
+}
+
+//=================================================================================
+// function : ~SALOME_PYQT_DataModelLight()
+// purpose : destructor
+//=================================================================================
+SALOME_PYQT_DataModelLight::~SALOME_PYQT_DataModelLight()
+{
+}
+
+//=================================================================================
+// function : open()
+// purpose : Open data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::open( const QString& theURL, CAM_Study* study, QStringList theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_DataModelLight::open()");
+ LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( study );
+ SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+ if ( !aDoc || !aModule)
+ return false;
+
+ LightApp_DataModel::open( theURL, aDoc, theListOfFiles );
+
+ setModified( false );
+
+ return aModule->open(theListOfFiles);
+
+}
+
+//=================================================================================
+// function : save()
+// purpose : Save data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::save( QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_DataModelLight::save()");
+ bool isMultiFile = false; // temporary solution
+
+ LightApp_DataModel::save(theListOfFiles);
+ LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
+ SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+
+ if(!aModule || !study)
+ return false;
+
+
+ std::string aTmpDir = study->GetTmpDir(myStudyURL.toLatin1().constData(), isMultiFile );
+
+ theListOfFiles.append(QString(aTmpDir.c_str()));
+ int listSize = theListOfFiles.size();
+ aModule->save(theListOfFiles);
+
+ setModified( false );
+
+ //Return true if in the List of files was added item(s)
+ //else return false
+ return theListOfFiles.size() > listSize;
+}
+
+//=================================================================================
+// function : saveAs()
+// purpose : SaveAs data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::saveAs ( const QString& theURL, CAM_Study* theStudy, QStringList& theListOfFiles)
+{
+ myStudyURL = theURL;
+ return save(theListOfFiles);
+}
+
+
+
+bool SALOME_PYQT_DataModelLight::create( CAM_Study* study )
+{
+ return true;
+}
+
+//=================================================================================
+// function : dumpPython()
+// purpose : Re-defined from LigthApp_DataModel in order to participate
+// in dump study process
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::dumpPython( const QString& theURL,
+ CAM_Study* theStudy,
+ bool isMultiFile,
+ QStringList& theListOfFiles )
+{
+ MESSAGE("SALOME_PYQT_DataModelLight::dumpPython()");
+
+ LightApp_DataModel::dumpPython( theURL, theStudy, isMultiFile, theListOfFiles );
+
+ LightApp_Study* study = dynamic_cast<LightApp_Study*>( theStudy );
+ SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+
+ if(!aModule || !study)
+ return false;
+
+ std::string aTmpDir = study->GetTmpDir( theURL.toLatin1().constData(), isMultiFile );
+
+ theListOfFiles.append( QString( aTmpDir.c_str() ) );
+ int oldSize = theListOfFiles.size();
+
+ aModule->dumpPython( theListOfFiles );
+
+ //Return true if some items have been added, else return false
+ return theListOfFiles.size() > oldSize;
+}
+
+//=================================================================================
+// function : isModified()
+// purpose : returns this model's modification status that can be controlled
+// with help of setModified() calls by the underlying Python module
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::isModified() const
+{
+ return myModified;
+}
+
+//=================================================================================
+// function : setModified()
+// purpose : sets the model's modification status, should be used by
+// the underlying Python module when its data changes.
+//=================================================================================
+void SALOME_PYQT_DataModelLight::setModified( bool flag )
+{
+ myModified = flag;
+}
+
+//=================================================================================
+// function : close()
+// purpose : Close data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::close()
+{
+ LightApp_DataModel::close();
+ return true;
+}
+
+
+void SALOME_PYQT_DataModelLight::update ( LightApp_DataObject* theObj, LightApp_Study* theStudy )
+{
+ // Nothing to do here: we always keep the data tree in the up-to-date state
+ // The only goal of this method is to hide default behavior from LightApp_DataModel
+ return;
+}
+
+CAM_DataObject* SALOME_PYQT_DataModelLight::getRoot()
+{
+ LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
+ CAM_ModuleObject *aModelRoot = dynamic_cast<CAM_ModuleObject*>(root());
+ if(study && aModelRoot == NULL) {
+ aModelRoot = createModuleObject( study->root() );
+ aModelRoot->setDataModel( this );
+ setRoot(aModelRoot);
+ }
+ return aModelRoot;
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+//
+#ifndef SALOME_PYQT_DATAMODELLIGHT_H
+#define SALOME_PYQT_DATAMODELLIGHT_H
+
+#include "SALOME_PYQT_GUILight.h"
+#include <LightApp_DataModel.h>
+
+#include <CAM_Module.h>
+#include "SALOME_PYQT_DataObjectLight.h"
+
+class SALOME_PYQT_RootObjectLight;
+
+
+
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_DataModelLight : public LightApp_DataModel
+{
+ Q_OBJECT
+
+public:
+ SALOME_PYQT_DataModelLight( CAM_Module* theModule );
+ virtual ~SALOME_PYQT_DataModelLight();
+
+ virtual bool open ( const QString&, CAM_Study*, QStringList );
+ virtual bool save ( QStringList& );
+ virtual bool saveAs ( const QString&, CAM_Study*, QStringList& );
+ virtual bool close ();
+ virtual bool create ( CAM_Study* );
+ virtual bool dumpPython( const QString&,
+ CAM_Study*,
+ bool,
+ QStringList& );
+
+ virtual bool isModified () const;
+ void setModified( bool );
+
+ virtual void update ( LightApp_DataObject* = 0, LightApp_Study* = 0 );
+
+ CAM_DataObject* getRoot();
+
+ private:
+ QString myFileName;
+ QString myStudyURL;
+ bool myModified;
+};
+
+#endif // SALOME_PYQT_DATAMODELLIGHT_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+//
+#include "SALOME_PYQT_DataObjectLight.h"
+#include <LightApp_Application.h>
+#include <SUIT_Session.h>
+#include <utilities.h>
+#include <SUIT_ResourceMgr.h>
+
+
+#include <CAM_DataModel.h>
+#include <CAM_Module.h>
+
+
+/*!
+ * Class: SALOME_PYQT_DataObjectLight
+ * Description: LIGHT PYTHON module's data object
+ */
+
+static int _ID = 0;
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight()
+// purpose : constructor
+//=================================================================================
+SALOME_PYQT_DataObjectLight::SALOME_PYQT_DataObjectLight ( SUIT_DataObject* parent )
+ : CAM_DataObject(parent),
+ LightApp_DataObject( parent )
+
+{
+ _ID++;
+ myEntry = QString("PYLIGHT_OBJ_%1").arg(_ID);
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight()
+// purpose : destructor
+//=================================================================================
+SALOME_PYQT_DataObjectLight::~SALOME_PYQT_DataObjectLight()
+{
+
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::entry()
+// purpose : return entry of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::entry() const
+{
+ return myEntry;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::refEntry()
+// purpose : return entry of the data object referenced by this one (if any)
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::refEntry() const
+{
+ return myRefEntry;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::setRefEntry()
+// purpose : sets entry of the data object referenced by this one
+//=================================================================================
+void SALOME_PYQT_DataObjectLight::setRefEntry( const QString& refEntry )
+{
+ myRefEntry = refEntry;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::name()
+// purpose : return name of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::name() const
+{
+ return myName;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::icon()
+// purpose : return icon of object
+//=================================================================================
+QPixmap SALOME_PYQT_DataObjectLight::icon(const int index) const
+{
+ if(index == NameId)
+ return myIcon;
+ else
+ return LightApp_DataObject::icon( index );
+}
+
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::toolTip()
+// purpose : return toolTip of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::toolTip(const int index) const
+{
+ return myToolTip;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::toolTip()
+// purpose : return toolTip of object
+//=================================================================================
+QColor SALOME_PYQT_DataObjectLight::color( const ColorRole role, const int id ) const
+{
+ QColor c;
+
+ switch ( role )
+ {
+ case Text:
+ case Foreground:
+ if ( !isReference() )
+ c = myColor;
+ break;
+
+ default:
+ break;
+ }
+
+ // Issue 21379: LightApp_DataObject::color() defines colors for valid references
+ if ( !c.isValid() )
+ c = LightApp_DataObject::color( role, id );
+
+ return c;
+}
+
+bool SALOME_PYQT_DataObjectLight::setName(const QString& name)
+{
+ myName = name;
+ return true;
+}
+
+void SALOME_PYQT_DataObjectLight::setIcon(const QString& iconname)
+{
+ if(!iconname.isEmpty()) {
+ LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
+ if(anApp) {
+ QString modulename = anApp->activeModule()->name();
+ if(!modulename.isEmpty())
+ {
+ myIcon = SUIT_Session::session()->resourceMgr()->loadPixmap(modulename,
+ QObject::tr(iconname.toLatin1()));
+ }
+ }
+ }
+}
+
+void SALOME_PYQT_DataObjectLight::setToolTip(const QString& tooltip)
+{
+ myToolTip = tooltip;
+}
+
+void SALOME_PYQT_DataObjectLight::setColor(const QColor& color)
+{
+ myColor = color;
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+//
+#ifndef SALOME_PYQT_DATAOBJECTLIGHT_H
+#define SALOME_PYQT_DATAOBJECTLIGHT_H
+
+
+#include "SALOME_PYQT_GUILight.h"
+#include <LightApp_DataObject.h>
+#include <LightApp_Study.h>
+
+#include <qstring.h>
+
+/*!
+ * SALOME_PYQT_DataObjectLight - PYTHON LIGHT module's data object class
+ */
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_DataObjectLight : public virtual LightApp_DataObject
+{
+
+ public:
+ SALOME_PYQT_DataObjectLight( SUIT_DataObject* = 0 );
+
+ virtual ~SALOME_PYQT_DataObjectLight();
+
+ virtual QString entry() const;
+
+ virtual QString refEntry() const;
+ void setRefEntry( const QString& refEntry );
+
+ virtual QString name() const;
+ virtual QPixmap icon(const int = NameId) const;
+ virtual QString toolTip(const int = NameId) const;
+
+ bool setName(const QString& name);
+ void setIcon(const QString& icon);
+ void setToolTip(const QString& tooltip);
+
+ virtual QColor color( const ColorRole, const int = NameId ) const;
+ void setColor(const QColor& color);
+
+ private:
+ QString myEntry;
+ QString myRefEntry;
+ QString myName;
+ QString myToolTip;
+ QPixmap myIcon;
+ QColor myColor;
+};
+
+#endif // SALOME_PYQT_DATAOBJECTLIGHT_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File : SALOME_PYQT_GUI.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+#if !defined ( SALOME_PYQT_GUILIGHT_H )
+#define SALOME_PYQT_GUIILIGHT_H
+
+// ========================================================
+// set dllexport type for Win platform
+#ifdef WNT
+
+#if defined SALOME_PYQT_LIGHT_EXPORTS || defined SalomePyQtGUILight_EXPORTS
+#define SALOME_PYQT_LIGHT_EXPORT __declspec(dllexport)
+#else
+#define SALOME_PYQT_LIGHT_EXPORT __declspec(dllimport)
+#endif
+
+#else // WNT
+
+#define SALOME_PYQT_LIGHT_EXPORT
+
+#endif // WNT
+
+// ========================================================
+// avoid warning messages
+#ifdef WNT
+#pragma warning (disable : 4786)
+#pragma warning (disable : 4251)
+#endif
+
+#endif // SALOME_PYQT_GUIILIGHT_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : SALOME_PYQT_GUI.sip
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+%Module SalomePyQtGUILight
+
+%Import QtGuimod.sip
+%Import QtXmlmod.sip
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File : SALOME_PYQT_Module.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+#include "SALOME_PYQT_PyInterp.h"
+#include <SUITApp_init_python.hxx>
+#include <PyInterp_Interp.h>
+#include <PyConsole_Interp.h>
+#include <PyConsole_Console.h>
+#include <PyInterp_Dispatcher.h>
+
+#include "SALOME_PYQT_ModuleLight.h"
+#include "SALOME_PYQT_DataModelLight.h"
+
+#ifndef GUI_DISABLE_CORBA
+#include <Container_init_python.hxx>
+#endif
+
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_DataObjectIterator.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_ViewModel.h>
+#include <SUIT_ViewWindow.h>
+#include <SUIT_ViewManager.h>
+#include <STD_MDIDesktop.h>
+#include <STD_TabDesktop.h>
+#include <LightApp_Preferences.h>
+#include <LightApp_Application.h>
+#include <LightApp_Study.h>
+
+#include <QtxWorkstack.h>
+#include <QtxWorkspace.h>
+#include <QtxActionGroup.h>
+#include <QtxActionMenuMgr.h>
+#include <QtxActionToolMgr.h>
+
+#include <QFile>
+#include <QDomDocument>
+#include <QDomNode>
+#include <QDomElement>
+#include <QMenuBar>
+#include <QMenu>
+#include <QAction>
+
+#include "sipAPISalomePyQtGUILight.h"
+
+#include <sip.h>
+#if SIP_VERSION < 0x040700
+#include "sipQtGuiQWidget.h"
+#include "sipQtGuiQMenu.h"
+#endif
+
+#include <utilities.h>
+
+/*!
+ \brief Default name of the module, replaced at the moment
+ of module creation.
+ \internal
+*/
+const char* DEFAULT_NAME = "SALOME_PYQT_ModuleLight";
+
+/*!
+ \brief Default menu group number.
+ \internal
+*/
+const int DEFAULT_GROUP = 40;
+
+/*!
+ \var IsCallOldMethods
+ \brief Allow calling obsolete callback methods.
+ \internal
+
+ If the macro CALL_OLD_METHODS is not defined, the invoking
+ of obsolete Python module's methods like setSetting(), definePopup(),
+ etc. is blocked.
+
+ CALL_OLD_METHODS macro can be defined for example by adding
+ -DCALL_OLD_METHODS compilation option to the Makefile.
+*/
+#ifdef CALL_OLD_METHODS
+const bool IsCallOldMethods = true;
+#else
+const bool IsCallOldMethods = false;
+#endif
+
+/* Py_ssize_t for old Pythons */
+/* This code is as recommended by: */
+/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+# define PY_SSIZE_T_MAX INT_MAX
+# define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+//
+// NB: Python requests.
+// General rule for Python requests created by SALOME_PYQT_Module:
+// all requests should be executed SYNCHRONOUSLY within the main GUI thread.
+// However, it is obligatory that ANY Python call is wrapped with a request object,
+// so that ALL Python API calls are serialized with PyInterp_Dispatcher.
+//
+
+/*!
+ \class SALOME_PYQT_Module::XmlHandler
+ \brief XML resource files parser.
+ \internal
+
+ This class is used to provide backward compatibility with
+ existing Python modules in which obsolete menu definition system
+ (via XML files) is used.
+*/
+
+class SALOME_PYQT_ModuleLight::XmlHandler
+{
+public:
+ XmlHandler( SALOME_PYQT_ModuleLight* module, const QString& fileName );
+ void createActions();
+ void createPopup ( QMenu* menu,
+ const QString& context,
+ const QString& parent,
+ const QString& object );
+ void activateMenus( bool );
+
+protected:
+ void createToolBar ( QDomNode& parentNode );
+ void createMenu ( QDomNode& parentNode,
+ const int parentMenuId = -1,
+ QMenu* parentPopup = 0 );
+
+ void insertPopupItems( QDomNode& parentNode,
+ QMenu* menu );
+
+private:
+ SALOME_PYQT_ModuleLight* myModule;
+ QDomDocument myDoc;
+ QList<int> myMenuItems;
+};
+
+//
+// NB: Library initialization
+// Since the SalomePyQtGUILight library is not imported in Python it's initialization function
+// should be called manually (and only once) in order to initialize global sip data
+// and to get C API from sip : sipBuildResult for example
+//
+
+#define INIT_FUNCTION initSalomePyQtGUILight
+#if defined(SIP_STATIC_MODULE)
+extern "C" void INIT_FUNCTION();
+#else
+PyMODINIT_FUNC INIT_FUNCTION();
+#endif
+
+/*!
+ \fn CAM_Module* createModule()
+ \brief Module factory function.
+ \internal
+
+ Creates an instance of SALOME_PYQT_Module object by request
+ of an application when the module is loaded and initialized.
+
+ \return new module object
+*/
+
+extern "C" {
+ SALOME_PYQT_LIGHT_EXPORT CAM_Module* createModule() {
+
+ static bool alreadyInitialized = false;
+ if ( !alreadyInitialized ) {
+ // call only once (see comment above) !
+ static PyThreadState *gtstate = 0;
+#ifndef GUI_DISABLE_CORBA
+ if(SUIT_PYTHON::initialized)
+ gtstate = SUIT_PYTHON::_gtstate;
+ else
+ gtstate = KERNEL_PYTHON::_gtstate;
+#else
+ gtstate = SUIT_PYTHON::_gtstate;
+#endif
+ PyEval_RestoreThread( gtstate );
+ INIT_FUNCTION();
+ PyEval_ReleaseThread( gtstate );
+ alreadyInitialized = !alreadyInitialized;
+ }
+ return new SALOME_PYQT_ModuleLight();
+ }
+}
+
+/*!
+ \class FuncMsg
+ \brief Function call in/out tracer.
+ \internal
+*/
+
+class FuncMsg
+{
+public:
+ FuncMsg( const QString& funcName )
+ {
+ myName = funcName;
+ MESSAGE( myName.toLatin1().constData() << " [ begin ]" );
+ }
+ ~FuncMsg()
+ {
+ MESSAGE( myName.toLatin1().constData() << " [ end ]" );
+ }
+ void message( const QString& msg )
+ {
+ MESSAGE( myName.toLatin1().constData() << " : " << msg.toLatin1().constData() );
+ }
+private:
+ QString myName;
+};
+
+/*!
+ \class SALOME_PYQT_ModuleLight
+ \brief This class implements module API for all the Python-based
+ SALOME modules.
+*/
+
+//
+// Static variables definition
+//
+SALOME_PYQT_ModuleLight::InterpMap SALOME_PYQT_ModuleLight::myInterpMap;
+SALOME_PYQT_ModuleLight* SALOME_PYQT_ModuleLight::myInitModule = 0;
+
+/*!
+ \brief Get the module being initialized.
+
+ This is a little trick :) needed to provide an access from Python
+ (SalomePyQt) to the module being currently activated. The problem
+ that during the process of module initialization (initialize()
+ function) it is not yet available via application->activeModule()
+ call.
+
+ This method returns valid pointer only if called in scope of
+ initialize() function.
+
+ \return the module being currently initialized
+*/
+SALOME_PYQT_ModuleLight* SALOME_PYQT_ModuleLight::getInitModule()
+{
+ return myInitModule;
+}
+
+/*!
+ \brief Constructor
+*/
+SALOME_PYQT_ModuleLight::SALOME_PYQT_ModuleLight()
+: LightApp_Module( DEFAULT_NAME ),
+ myInterp( 0 ),
+ myModule( 0 ),
+ myXmlHandler ( 0 ),
+ myLastActivateStatus( true )
+{
+}
+
+/*!
+ \brief Destructor
+*/
+SALOME_PYQT_ModuleLight::~SALOME_PYQT_ModuleLight()
+{
+ if ( myXmlHandler )
+ delete myXmlHandler;
+ if ( myInterp && myModule ) {
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+ Py_XDECREF(myModule);
+ }
+}
+
+/*!
+ \brief Initialization of the module.
+
+ This method can be used for creation of the menus, toolbars and
+ other such staff.
+
+ There are two ways to do this:
+ - for obsolete modules this method first tries to read
+ <module>_<language>.xml resource file which contains a menu,
+ toolbars and popup menus description;
+ - new modules can create menus by direct calling of the
+ corresponding methods of SalomePyQt Python API in the Python
+ module's initialize() method which is called from here.
+
+ NOTE: SALOME supports two modes of modules loading:
+ - immediate (all the modules are created and initialized
+ immediately when the application object is created;
+ - postponed modules loading (used currently); in this mode
+ the module is loaded only be request.
+ If postponed modules loading is not used, the active
+ study might be not yet defined at this stage, so initialize()
+ method should not perform any study-based initialization.
+
+ \param app parent application object
+*/
+void SALOME_PYQT_ModuleLight::initialize( CAM_Application* app )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initialize()" );
+
+ // call base implementation
+ LightApp_Module::initialize( app );
+
+ // try to get XML resource file name
+ SUIT_ResourceMgr* aResMgr = getApp()->resourceMgr();
+ if ( !myXmlHandler && aResMgr ) {
+ // get current language
+ QString aLang = aResMgr->stringValue( "language", "language", QString() );
+ if ( aLang.isEmpty() )
+ aLang = "en";
+ // define resource file name
+ QString aFileName = name() + "_" + aLang + ".xml";
+ aFileName = aResMgr->path( "resources", name(), aFileName );
+ // create XML handler instance
+ if ( !aFileName.isEmpty() && QFile::exists( aFileName ) )
+ myXmlHandler = new SALOME_PYQT_ModuleLight::XmlHandler( this, aFileName );
+ // create menus & toolbars from XML file if required
+ if ( myXmlHandler )
+ myXmlHandler->createActions();
+ }
+
+ // perform internal initialization and call module's initialize() funtion
+ // InitializeReq: request class for internal init() operation
+ class InitializeReq : public PyInterp_Request
+ {
+ public:
+ InitializeReq( CAM_Application* _app,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myApp( _app ),
+ myObj( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->init( myApp );
+ }
+
+ private:
+ CAM_Application* myApp;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new InitializeReq( app, this ) );
+}
+
+/*!
+ \brief Activation of the module.
+
+ This function is usually used in order to show the module's
+ specific menus and toolbars, update actions state and perform
+ other such actions required when the module is activated.
+
+ Note, that returning \c false in this function prevents the
+ module activation.
+
+ \param theStudy parent study
+ \return \c true if activation is successful and \c false otherwise
+*/
+bool SALOME_PYQT_ModuleLight::activateModule( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::activateModule()" );
+
+ // call base implementation
+ bool res = LightApp_Module::activateModule( theStudy );
+
+ if ( !res )
+ return res;
+
+ // internal activation
+ return activateModuleInternal( theStudy );
+}
+
+/*!
+ \brief Perform internal activation of the module.
+
+ The only goal of this function is to extract common functionality
+ for LightApp_Module and SalomeApp_module classes requried by the
+ specific architecture aspects of "light" / "full" SALOME modes.
+
+ \sa activateModule()
+*/
+bool SALOME_PYQT_ModuleLight::activateModuleInternal( SUIT_Study* theStudy )
+{
+ // reset the activation status to the default value
+ myLastActivateStatus = true;
+
+ // perform internal activation
+ // ActivateReq: request class for internal activate() operation
+ class ActivateReq : public PyInterp_Request
+ {
+ public:
+ ActivateReq( SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->activate( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new ActivateReq( theStudy, this ) );
+
+ // check activation status (set by activate())
+ if ( !lastActivationStatus() )
+ return false;
+
+ // activate menus, toolbars, etc
+ if ( myXmlHandler ) myXmlHandler->activateMenus( true );
+ setMenuShown( true );
+ setToolShown( true );
+
+ // connect preferences changing signal
+ connect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
+ this, SLOT( preferenceChanged( const QString&, const QString&, const QString& ) ) );
+
+ // perform custom activation actions
+ // CustomizeReq: request class for internal customize() operation
+ class CustomizeReq : public PyInterp_Request
+ {
+ public:
+ CustomizeReq( SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->customize( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new CustomizeReq( theStudy, this ) );
+
+ return true;
+}
+
+/*!
+ \brief Deactivation of the module.
+
+ This function is usually used in order to hide the module's
+ specific menus and toolbars and perform other such actions
+ required when the module is deactivated.
+
+ \param theStudy parent study
+ \return \c true if deactivation is successful and \c false otherwise
+*/
+bool SALOME_PYQT_ModuleLight::deactivateModule( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::deactivateModule()" );
+
+ // disconnect preferences changing signal
+ disconnect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
+ this, SLOT( preferenceChanged( const QString&, const QString&, const QString& ) ) );
+
+ // perform internal deactivation
+ // DeactivateReq: request class for internal deactivate() operation
+ class DeactivateReq : public PyInterp_LockRequest
+ {
+ public:
+ DeactivateReq( PyInterp_Interp* _py_interp,
+ SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->deactivate( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new DeactivateReq( myInterp, theStudy, this ) );
+
+ // deactivate menus, toolbars, etc
+ if ( myXmlHandler ) myXmlHandler->activateMenus( false );
+ setMenuShown( false );
+ setToolShown( false );
+
+ // call base implementation
+ return LightApp_Module::deactivateModule( theStudy );
+}
+
+/*!
+ \brief Get last activation status.
+ \return status of last module activation operation
+ \sa activateModule()
+*/
+bool SALOME_PYQT_ModuleLight::lastActivationStatus() const
+{
+ return myLastActivateStatus;
+}
+
+/*!
+ \breif Process application preferences changing.
+
+ Called when any application setting is changed.
+
+ \param module preference module
+ \param section preference resource file section
+ \param setting preference resource name
+*/
+void SALOME_PYQT_ModuleLight::preferenceChanged( const QString& module,
+ const QString& section,
+ const QString& setting )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::preferenceChanged()" );
+
+ // perform synchronous request to Python event dispatcher
+ class Event : public PyInterp_LockRequest
+ {
+ public:
+ Event( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ const QString& _section,
+ const QString& _setting )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj ( _obj ),
+ mySection( _section ),
+ mySetting( _setting ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->prefChanged( mySection, mySetting );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QString mySection, mySetting;
+ };
+
+ if ( module != moduleName() ) {
+ // module's own preferences are processed by preferencesChanged() method
+ // ...
+ // post the request only if dispatcher is not busy!
+ // execute request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
+ }
+}
+
+/*!
+ \brief Process study activation.
+
+ Called when study desktop is activated. Used for notifying the Python
+ module about changing of the active study.
+*/
+void SALOME_PYQT_ModuleLight::studyActivated()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::studyActivated()" );
+
+ // StudyChangedReq: request class for internal studyChanged() operation
+ class StudyChangedReq : public PyInterp_Request
+ {
+ public:
+ StudyChangedReq( SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->studyChanged( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new StudyChangedReq( application()->activeStudy(), this ) );
+}
+
+/*!
+ \brief Process GUI action (from main menu, toolbar or
+ context popup menu action).
+*/
+void SALOME_PYQT_ModuleLight::onGUIEvent()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::onGUIEvent()" );
+
+ // get sender action
+ QAction* action = qobject_cast<QAction*>( sender() );
+ if ( !action )
+ return;
+
+ // get action ID
+ int id = actionId( action );
+ fmsg.message( QString( "action id = %1" ).arg( id ) );
+
+ // perform synchronous request to Python event dispatcher
+ class GUIEvent : public PyInterp_LockRequest
+ {
+ public:
+ GUIEvent( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ int _id )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myId ( _id ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->guiEvent( myId );
+ }
+
+ private:
+ int myId;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new GUIEvent( myInterp, this, id ) );
+}
+
+/*!
+ \brief Process context popup menu request.
+
+ Called when user activates popup menu in some window
+ (view, object browser, etc).
+
+ \param theContext popup menu context (e.g. "ObjectBrowser")
+ \param thePopupMenu popup menu
+ \param title popup menu title (not used)
+*/
+void SALOME_PYQT_ModuleLight::contextMenuPopup( const QString& theContext,
+ QMenu* thePopupMenu,
+ QString& /*title*/ )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::contextMenuPopup()" );
+ fmsg.message( QString( "context: %1" ).arg( theContext ) );
+
+ // perform synchronous request to Python event dispatcher
+ class PopupMenuEvent : public PyInterp_LockRequest
+ {
+ public:
+ PopupMenuEvent( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ const QString& _context,
+ QMenu* _popup )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myContext( _context ),
+ myPopup ( _popup ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->contextMenu( myContext, myPopup );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QString myContext;
+ QMenu* myPopup;
+ };
+
+ // post request only if dispatcher is not busy!
+ // execute request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new PopupMenuEvent( myInterp, this, theContext, thePopupMenu ) );
+}
+
+/*!
+ \brief Export preferences for the Python module.
+
+ Called only once when the first instance of the module is created.
+*/
+void SALOME_PYQT_ModuleLight::createPreferences()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::createPreferences()" );
+
+ // perform synchronous request to Python event dispatcher
+ class Event : public PyInterp_LockRequest
+ {
+ public:
+ Event( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->initPreferences();
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request only if dispatcher is not busy!
+ // execute request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this ) );
+}
+
+/*!
+ \brief Define the dockable windows associated with the module.
+
+ To fill the list of windows the correspondind Python module's windows()
+ method is called from SALOME_PYQT_ModuleLight::init() method.
+
+ By default, ObjectBrowser, PythonConsole and LogWindow windows are
+ associated to the module.
+
+ Allowed dockable windows:
+ - LightApp_Application::WT_ObjectBrowser : object browser
+ - LightApp_Application::WT_PyConsole : python console
+ - LightApp_Application::WT_LogWindow : log messages output window
+
+ Dock area is defined by Qt::DockWidgetArea enumeration:
+ - Qt::TopDockWidgetArea : top dock area
+ - Qt::BottomDockWidgetArea : bottom dock area
+ - Qt::LeftDockWidgetArea : left dock area
+ - Qt::RightDockWidgetArea : right dock area
+
+ \param mappa map of dockable windows: { <window_type> : <dock_area> }
+*/
+void SALOME_PYQT_ModuleLight::windows( QMap<int, int>& mappa ) const
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::windows()" );
+
+ mappa = myWindowsMap;
+}
+
+/*!
+ \brief Define the compatible view windows associated with the module.
+
+ The associated view windows are opened automatically when the module
+ is activated.
+
+ To fill the list of views the correspondind Python module's views()
+ method is called from SALOME_PYQT_ModuleLight::init() method.
+ By default, the list is empty.
+
+ \param listik list of view windows types
+*/
+void SALOME_PYQT_ModuleLight::viewManagers( QStringList& lst ) const
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::viewManagers()" );
+
+ lst = myViewMgrList;
+}
+
+/*!
+ \brief Process module's preferences changing.
+
+ Called when the module's preferences are changed.
+
+ \param section setting section
+ \param setting setting name
+*/
+void SALOME_PYQT_ModuleLight::preferencesChanged( const QString& section, const QString& setting )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::preferencesChanged()" );
+
+ // perform synchronous request to Python event dispatcher
+ class Event : public PyInterp_LockRequest
+ {
+ public:
+ Event( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ const QString& _section,
+ const QString& _setting )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj ( _obj ),
+ mySection( _section ),
+ mySetting( _setting ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->prefChanged( mySection, mySetting );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QString mySection, mySetting;
+ };
+
+ // post request only if dispatcher is not busy!
+ // execut request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
+}
+
+/*!
+ \brief Internal module initialization:
+
+ Performs the following actions:
+ - initialize or get the Python interpreter (one per study)
+ - import the Python module
+ - pass the workspace widget to the Python module
+ - call Python module's initialize() method
+ - call Python module's windows() method
+ - call Python module's views() method
+
+ \param app parent application object
+*/
+void SALOME_PYQT_ModuleLight::init( CAM_Application* app )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::init()" );
+
+ // reset interpreter to NULL
+ myInterp = NULL;
+
+ // get study Id
+ LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( app );
+ if ( !anApp )
+ return;
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( app->activeStudy() );
+ if ( !aStudy )
+ return;
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp )
+ return; // Error
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule )
+ return; // Error
+
+ // this module is being activated now!
+ myInitModule = this;
+
+ // then call Python module's initialize() method
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+ // ... (the Python module is already imported)
+ // ... finally call Python module's initialize() method
+ if ( PyObject_HasAttrString( myModule, (char*)"initialize" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"initialize", (char*)"" ) );
+ if ( !res ) {
+ PyErr_Print();
+ }
+ }
+
+ // get required dockable windows list from the Python module
+ // by calling windows() method
+ // ... first put default values
+ myWindowsMap.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+ myWindowsMap.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
+ myWindowsMap.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
+
+ if ( PyObject_HasAttrString( myModule , (char*)"windows" ) ) {
+ PyObjWrapper res1( PyObject_CallMethod( myModule, (char*)"windows", (char*)"" ) );
+ if ( !res1 ) {
+ PyErr_Print();
+ }
+ else {
+ myWindowsMap.clear();
+ if ( PyDict_Check( res1 ) ) {
+ PyObject* key;
+ PyObject* value;
+ Py_ssize_t pos = 0;
+ while ( PyDict_Next( res1, &pos, &key, &value ) ) {
+ // parse the return value
+ // it should be a map: {integer:integer}
+ int aKey, aValue;
+ if( key && PyInt_Check( key ) && value && PyInt_Check( value ) ) {
+ aKey = PyInt_AsLong( key );
+ aValue = PyInt_AsLong( value );
+ myWindowsMap[ aKey ] = aValue;
+ }
+ }
+ }
+ }
+ }
+
+ // get compatible view windows types from the Python module
+ // by calling views() method
+ if ( PyObject_HasAttrString( myModule , (char*)"views" ) ) {
+ PyObjWrapper res2( PyObject_CallMethod( myModule, (char*)"views", (char*)"" ) );
+ if ( !res2 ) {
+ PyErr_Print();
+ }
+ else {
+ // parse the return value
+ // result can be one string...
+ if ( PyString_Check( res2 ) ) {
+ myViewMgrList.append( PyString_AsString( res2 ) );
+ }
+ // ... or list of strings
+ else if ( PyList_Check( res2 ) ) {
+ int size = PyList_Size( res2 );
+ for ( int i = 0; i < size; i++ ) {
+ PyObject* value = PyList_GetItem( res2, i );
+ if( value && PyString_Check( value ) ) {
+ myViewMgrList.append( PyString_AsString( value ) );
+ }
+ }
+ }
+ }
+ }
+ // module is already activated!
+ myInitModule = 0;
+}
+
+/*!
+ \brief Internal activation:
+
+ Performs the following actions:
+ - initialize or get the Python interpreter (one per study)
+ - import the Python GUI module
+ - call Python module's activate() method
+
+ \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::activate( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::activate()" );
+
+ // get study Id
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp ) {
+ myLastActivateStatus = false;
+ return; // Error
+ }
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule ) {
+ myLastActivateStatus = false;
+ return; // Error
+ }
+
+ // get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ // call Python module's activate() method (for the new modules)
+ if ( PyObject_HasAttrString( myModule , (char*)"activate" ) ) {
+ PyObject* res1 = PyObject_CallMethod( myModule, (char*)"activate", (char*)"" );
+ if ( !res1 || !PyBool_Check( res1 ) ) {
+ PyErr_Print();
+ // always true for old modules (no return value)
+ myLastActivateStatus = true;
+ }
+ else {
+ // detect return status
+ myLastActivateStatus = PyObject_IsTrue( res1 );
+ }
+ }
+
+ // Connect the SUIT_Desktop signal windowActivated() to this->onActiveViewChanged()
+ SUIT_Desktop* aDesk = theStudy->application()->desktop();
+ if ( aDesk )
+ {
+ connect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+ this, SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );
+ // If a active window exists send activeViewChanged
+ // If a getActiveView() in SalomePyQt available we no longer need this
+ SUIT_ViewWindow* aView = aDesk->activeWindow();
+ if ( aView )
+ activeViewChanged( aView );
+
+ // get all view currently opened in the study and connect their signals to
+ // the corresponding slots of the class.
+ QList<SUIT_ViewWindow*> wndList = aDesk->windows();
+ SUIT_ViewWindow* wnd;
+ foreach ( wnd, wndList )
+ connectView( wnd );
+ }
+}
+
+/*!
+ \brief Additional customization after module is activated:
+
+ Performs the following actions:
+ - get the Python interpreter (one per study)
+ - import the Python GUI module
+ - call Python module's setSettings() method (obsolete function,
+ used for compatibility with old code)
+
+ \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::customize( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::customize()" );
+
+ // get study Id
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp )
+ return; // Error
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule )
+ return; // Error
+
+ if ( IsCallOldMethods ) {
+ // call Python module's setWorkspace() method
+ setWorkSpace();
+ }
+
+ // get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ if ( IsCallOldMethods ) {
+ // call Python module's setSettings() method (obsolete)
+ if ( PyObject_HasAttrString( myModule , (char*)"setSettings" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setSettings", (char*)"" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Internal deactivation:
+
+ Performs the following actions:
+ - call Python module's deactivate() method
+
+ \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::deactivate( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::deactivate()" );
+
+ // check if the subinterpreter is initialized and Python module is imported
+ if ( !myInterp || !myModule ) {
+ // Error! Python subinterpreter should be initialized and module should be imported first!
+ return;
+ }
+ // then call Python module's deactivate() method
+ if ( PyObject_HasAttrString( myModule , (char*)"deactivate" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"deactivate", (char*)"" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+
+ // Disconnect the SUIT_Desktop signal windowActivated()
+ SUIT_Desktop* aDesk = theStudy->application()->desktop();
+ if ( aDesk )
+ {
+ disconnect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+ this, SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );
+ }
+}
+
+/*!
+ \brief Perform internal actions when active study is changed.
+
+ Called when active the study is actived (user brings its
+ desktop to top):
+ - initialize or get the Python interpreter (one per study)
+ - import the Python GUI module
+ - call Python module's activeStudyChanged() method
+
+ \param theStudy study being activated
+*/
+void SALOME_PYQT_ModuleLight::studyChanged( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::studyChanged()" );
+
+ // get study Id
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp )
+ return; // Error
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule )
+ return; // Error
+
+ if ( IsCallOldMethods ) {
+ // call Python module's setWorkspace() method
+ setWorkSpace();
+ }
+
+ // get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ // call Python module's activeStudyChanged() method
+ if ( PyObject_HasAttrString( myModule, (char*)"activeStudyChanged" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeStudyChanged", (char*)"i", aStudyId ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Process (internally) context popup menu request.
+
+ Performs the following actions:
+ - calls Python module's definePopup(...) method (obsolete function,
+ used for compatibility with old code) to define the popup menu context
+ - parses XML resourses file (if exists) and fills the popup menu with the items)
+ - calls Python module's customPopup(...) method (obsolete function,
+ used for compatibility with old code) to allow module to customize the popup menu
+ - for new modules calls createPopupMenu() function to allow the
+ modules to build the popup menu by using insertItem(...) Qt functions.
+
+ \param theContext popup menu context
+ \param thePopupMenu popup menu
+*/
+void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* thePopupMenu )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::contextMenu()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ QString aContext( "" ), aObject( "" ), aParent( theContext );
+
+ if ( IsCallOldMethods && PyObject_HasAttrString( myModule, (char*)"definePopup" ) ) {
+ // call definePopup() Python module's function
+ // this is obsolete function, used only for compatibility reasons
+ PyObjWrapper res( PyObject_CallMethod( myModule,
+ (char*)"definePopup",
+ (char*)"sss",
+ theContext.toLatin1().constData(),
+ aObject.toLatin1().constData(),
+ aParent.toLatin1().constData() ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ else {
+ // parse return value
+ char *co, *ob, *pa;
+ if( PyArg_ParseTuple( res, "sss", &co, &ob, &pa ) ) {
+ aContext = co;
+ aObject = ob;
+ aParent = pa;
+ }
+ }
+ } // if ( IsCallOldMethods ... )
+
+ // first try to create menu via XML parser:
+ // we create popup menus without help of QtxPopupMgr
+ if ( myXmlHandler )
+ myXmlHandler->createPopup( thePopupMenu, aContext, aParent, aObject );
+
+#if SIP_VERSION < 0x040800
+ PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QMenu) );
+#else
+ PyObjWrapper sipPopup( sipBuildResult( 0, "D", thePopupMenu, sipType_QMenu, NULL) );
+#endif
+
+ // then call Python module's createPopupMenu() method (for new modules)
+ if ( PyObject_HasAttrString( myModule, (char*)"createPopupMenu" ) ) {
+ PyObjWrapper res1( PyObject_CallMethod( myModule,
+ (char*)"createPopupMenu",
+ (char*)"Os",
+ sipPopup.get(),
+ theContext.toLatin1().constData() ) );
+ if( !res1 ) {
+ PyErr_Print();
+ }
+ }
+
+ if ( IsCallOldMethods && PyObject_HasAttrString( myModule, (char*)"customPopup" ) ) {
+ // call customPopup() Python module's function
+ // this is obsolete function, used only for compatibility reasons
+ PyObjWrapper res2( PyObject_CallMethod( myModule,
+ (char*)"customPopup",
+ (char*)"Osss",
+ sipPopup.get(),
+ aContext.toLatin1().constData(),
+ aObject.toLatin1().constData(),
+ aParent.toLatin1().constData() ) );
+ if( !res2 ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Internal GUI event handling.
+
+ Performs the following actions:
+ - calls Python module's OnGUIEvent() method
+
+ \param theId GUI action ID
+*/
+void SALOME_PYQT_ModuleLight::guiEvent( const int theId )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::guiEvent()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ if ( PyObject_HasAttrString( myModule, (char*)"OnGUIEvent" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"OnGUIEvent", (char*)"i", theId ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Initialize (internally) preferences for the module.
+
+ Performs the following actions:
+ - calls Python module's createPreferences() method
+*/
+void SALOME_PYQT_ModuleLight::initPreferences()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initPreferences()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ // temporary set myInitModule because createPreferences() method
+ // might be called during the module intialization process
+ myInitModule = this;
+
+ if ( PyObject_HasAttrString( myModule, (char*)"createPreferences" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"createPreferences", (char*)"" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+
+ myInitModule = 0;
+}
+
+/*!
+ \brief Initialize python subinterpreter (one per study).
+ \param theStudyId study ID
+*/
+void SALOME_PYQT_ModuleLight::initInterp( int theStudyId )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initInterp()" );
+
+ // check study Id
+ if ( !theStudyId ) {
+ // Error! Study Id must not be 0!
+ myInterp = NULL;
+ return;
+ }
+ // try to find the subinterpreter
+ if( myInterpMap.contains( theStudyId ) ) {
+ // found!
+ myInterp = myInterpMap[ theStudyId ];
+ return;
+ }
+
+ myInterp = new SALOME_PYQT_PyInterp();
+ if(!myInterp)
+ return;
+
+ myInterp->initialize();
+ myInterpMap[ theStudyId ] = myInterp;
+
+#ifndef GUI_DISABLE_CORBA
+ if(!SUIT_PYTHON::initialized) {
+ // import 'salome' module and call 'salome_init' method;
+ // do it only once on interpreter creation
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+ // ... then import a module
+ PyObjWrapper aMod = PyImport_ImportModule( "salome" );
+ if( !aMod ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+ // ... then call a method
+ int embedded = 1;
+ PyObjWrapper aRes( PyObject_CallMethod( aMod, (char*)"salome_init", (char*)"ii", theStudyId, embedded ) );
+ if( !aRes ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+ }
+#endif
+}
+
+/*!
+ \brief Import Python GUI module and remember the reference to the module.
+
+ Attention! initInterp() should be called first!!!
+*/
+void SALOME_PYQT_ModuleLight::importModule()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::importModule()" );
+
+ // check if the subinterpreter is initialized
+ if ( !myInterp ) {
+ // Error! Python subinterpreter should be initialized first!
+ myModule = 0;
+ return;
+ }
+ // import Python GUI module and puts it in <myModule> attribute
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+ // ... then import a module
+ QString aMod = name() + "GUI";
+ try {
+ myModule = PyImport_ImportModule( aMod.toLatin1().data() );
+ }
+ catch (...) {
+ }
+ if( !myModule ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+}
+
+/*!
+ \brief Set study workspace to the Python module.
+
+ Calls setWorkSpace() method of the Pythohn module with
+ PyQt QWidget object to use with interpreter.
+
+ Attention! initInterp() and importModule() should be called first!!!
+*/
+void SALOME_PYQT_ModuleLight::setWorkSpace()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::setWorkSpace()" );
+
+ // check if the subinterpreter is initialized and Python module is imported
+ if ( !myInterp || !myModule ) {
+ // Error! Python subinterpreter should be initialized and module should be imported first!
+ return;
+ }
+
+ // call setWorkspace() method
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ // ... then try to import SalomePyQt module. If it's not possible don't go on.
+ PyObjWrapper aQtModule( PyImport_ImportModule( "SalomePyQt" ) );
+ if( !aQtModule ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+
+ if ( IsCallOldMethods ) {
+ // ... then get workspace object
+ QWidget* aWorkspace = 0;
+ if ( getApp()->desktop()->inherits( "STD_MDIDesktop" ) ) {
+ STD_MDIDesktop* aDesktop = dynamic_cast<STD_MDIDesktop*>( getApp()->desktop() );
+ if ( aDesktop )
+ aWorkspace = aDesktop->workspace();
+ }
+ else if ( getApp()->desktop()->inherits( "STD_TabDesktop" ) ) {
+ STD_TabDesktop* aDesktop = dynamic_cast<STD_TabDesktop*>( getApp()->desktop() );
+ if ( aDesktop )
+ aWorkspace = aDesktop->workstack();
+ }
+#if SIP_VERSION < 0x040800
+ PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget) );
+#else
+ PyObjWrapper pyws( sipBuildResult( 0, "D", aWorkspace, sipType_QWidget , NULL) );
+#endif
+ // ... and finally call Python module's setWorkspace() method (obsolete)
+ if ( PyObject_HasAttrString( myModule, (char*)"setWorkSpace" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setWorkSpace", (char*)"O", pyws.get() ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Preference changing callback function (internal).
+
+ Performs the following actions:
+ - call Python module's preferenceChanged() method
+
+ \param section setting section name
+ \param setting setting name
+*/
+void SALOME_PYQT_ModuleLight::prefChanged( const QString& section, const QString& setting )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::prefChanged()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ if ( PyObject_HasAttrString( myModule, (char*)"preferenceChanged" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule,
+ (char*)"preferenceChanged",
+ (char*)"ss",
+ section.toLatin1().constData(),
+ setting.toLatin1().constData() ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Get default menu group identifier
+ \return menu group ID (40 by default)
+*/
+int SALOME_PYQT_ModuleLight::defaultMenuGroup()
+{
+ return DEFAULT_GROUP;
+}
+
+//
+// The next methods call the parent implementation.
+// This is done to open protected methods from CAM_Module class.
+//
+
+/*!
+ \brief Create toolbar with specified \a name.
+ \param name toolbar name
+ \return toolbar ID or -1 if toolbar creation is failed
+*/
+int SALOME_PYQT_ModuleLight::createTool( const QString& name )
+{
+ return LightApp_Module::createTool( name );
+}
+
+/*!
+ \brief Insert action with specified \a id to the toolbar.
+ \param id action ID
+ \param tBar toolbar ID
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( const int id, const int tBar, const int idx )
+{
+ return LightApp_Module::createTool( id, tBar, idx );
+}
+
+/*!
+ \brief Insert action with specified \a id to the toolbar.
+ \param id action ID
+ \param tBar toolbar name
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( const int id, const QString& tBar, const int idx )
+{
+ return LightApp_Module::createTool( id, tBar, idx );
+}
+
+/*!
+ \brief Insert action to the toolbar.
+ \param a action
+ \param tBar toolbar ID
+ \param id required action ID
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( QAction* a, const int tBar, const int id, const int idx )
+{
+ return LightApp_Module::createTool( a, tBar, id, idx );
+}
+
+/*!
+ \brief Insert action to the toolbar.
+ \param a action
+ \param tBar toolbar name
+ \param id required action ID
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( QAction* a, const QString& tBar, const int id, const int idx )
+{
+ return LightApp_Module::createTool( a, tBar, id, idx );
+}
+
+/*!
+ \brief Create main menu.
+ \param subMenu menu name
+ \param menu parent menu ID
+ \param id required menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return menu ID or -1 if menu could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const QString& subMenu, const int menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+
+/*!
+ \brief Create main menu.
+ \param subMenu menu name
+ \param menu parent menu name (list of menu names separated by "|")
+ \param id required menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return menu ID or -1 if menu could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const QString& subMenu, const QString& menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param id action ID
+ \param menu parent menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const int id, const int menu, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( id, menu, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param id action ID
+ \param menu parent menu name (list of menu names separated by "|")
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const int id, const QString& menu, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( id, menu, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param a action
+ \param menu parent menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( a, menu, id, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param a action
+ \param menu parent menu name (list of menu names separated by "|")
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( a, menu, id, group, idx );
+}
+
+/*!
+ \brief Create separator action which can be used in the menu or toolbar.
+ \return new separator action
+*/
+QAction* SALOME_PYQT_ModuleLight::separator()
+{
+ return LightApp_Module::separator();
+}
+
+/*!
+ \brief Get action by specified \a id.
+ \return action or 0 if it is not found
+*/
+QAction* SALOME_PYQT_ModuleLight::action( const int id ) const
+{
+ QAction* a = LightApp_Module::action( id );
+ if ( !a ) {
+ // try menu
+ QMenu* m = menuMgr()->findMenu( id );
+ if ( m ) a = m->menuAction();
+ }
+ return a;
+}
+
+/*!
+ \brief Get action identifier.
+ \return action ID or -1 if action is not registered
+*/
+int SALOME_PYQT_ModuleLight::actionId( const QAction* a ) const
+{
+ return LightApp_Module::actionId( a );
+}
+
+/*!
+ \brief Create new action.
+
+ If the action with specified identifier already registered
+ it is not created, but its attributes are only modified.
+
+ \param id action ID
+ \param text tooltip text
+ \param icon icon
+ \param menu menu text
+ \param tip status tip
+ \param key keyboard shortcut
+ \param toggle \c true for checkable action
+ \return created action
+*/
+QAction* SALOME_PYQT_ModuleLight::createAction( const int id, const QString& text, const QString& icon,
+ const QString& menu, const QString& tip, const int key,
+ const bool toggle, QObject* parent )
+{
+ QIcon anIcon = loadIcon( icon );
+ QAction* a = action( id );
+ if ( a ) {
+ if ( a->toolTip().isEmpty() && !text.isEmpty() ) a->setToolTip( text );
+ if ( a->text().isEmpty() && !menu.isEmpty() ) a->setText( menu );
+ if ( a->icon().isNull() && !anIcon.isNull() ) a->setIcon( anIcon );
+ if ( a->statusTip().isEmpty() && !tip.isEmpty() ) a->setStatusTip( tip );
+ if ( a->shortcut().isEmpty() && key ) a->setShortcut( key );
+ if ( a->isCheckable() != toggle ) a->setCheckable( toggle );
+ disconnect( a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
+ connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
+ }
+ else {
+ a = LightApp_Module::createAction( id,
+ text,
+ anIcon,
+ menu,
+ tip,
+ key,
+ parent ? parent : this,
+ toggle,
+ this,
+ SLOT( onGUIEvent() ) );
+ }
+ return a;
+}
+
+/*!
+ \brief Create new action group.
+
+ If the action with specified identifier already registered
+ it is not created, but its attributes are only modified.
+
+ \param id action ID
+ \param text tooltip text
+ \param icon icon
+ \param menu menu text
+ \param tip status tip
+ \param key keyboard shortcut
+ \param toggle \c true for checkable action
+ \return created action
+*/
+QtxActionGroup* SALOME_PYQT_ModuleLight::createActionGroup(const int id, const bool exclusive)
+{
+ QtxActionGroup* a = qobject_cast<QtxActionGroup*>( action( id ) );
+ if ( !a ) {
+ a = new QtxActionGroup( this );
+ LightApp_Module::registerAction( id, a );
+ }
+ a->setExclusive( exclusive );
+ return a;
+}
+
+/*!
+ \brief Load icon from resource file.
+ \param fileName icon file name
+ \return icon (null icon if loading failed)
+*/
+QIcon SALOME_PYQT_ModuleLight::loadIcon( const QString& fileName )
+{
+ QIcon anIcon;
+ if ( !fileName.isEmpty() ) {
+ QPixmap pixmap = getApp()->resourceMgr()->loadPixmap( name(), tr( fileName.toLatin1() ) );
+ if ( !pixmap.isNull() )
+ anIcon = QIcon( pixmap );
+ }
+ return anIcon;
+}
+
+/*!
+ \brief Add global application preference (for example,
+ application specific section).
+ \param label preference name
+ \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addGlobalPreference( const QString& label )
+{
+ LightApp_Preferences* pref = preferences();
+ if ( !pref )
+ return -1;
+
+ return pref->addPreference( label, -1 );
+}
+
+/*!
+ \brief Add preference.
+ \param label preference name
+ \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addPreference( const QString& label )
+{
+ return LightApp_Module::addPreference( label );
+}
+
+/*!
+ \brief Add preference.
+ \param label preference name
+ \param pId parent preference ID
+ \param type preference type
+ \param section resource file section name
+ \param param resource file setting name
+ \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addPreference( const QString& label,
+ const int pId, const int type,
+ const QString& section,
+ const QString& param )
+{
+ return LightApp_Module::addPreference( label, pId, type, section, param );
+}
+
+/*!
+ \brief Get the preference property.
+ \param id preference ID
+ \param prop property name
+ \return property value (invalid QVariant() if property is not found)
+*/
+QVariant SALOME_PYQT_ModuleLight::preferenceProperty( const int id,
+ const QString& prop ) const
+{
+ QVariant v = LightApp_Module::preferenceProperty( id, prop );
+ return v;
+}
+
+/*!
+ \brief Set the preference property.
+ \param id preference ID
+ \param prop property name
+ \param var property value
+*/
+void SALOME_PYQT_ModuleLight::setPreferenceProperty( const int id,
+ const QString& prop,
+ const QVariant& var )
+{
+ LightApp_Module::setPreferenceProperty( id, prop, var );
+}
+
+
+/*!
+ \brief Signal handler windowActivated(SUIT_ViewWindow*) of SUIT_Desktop
+ \param pview view being activated
+*/
+void SALOME_PYQT_ModuleLight::onActiveViewChanged( SUIT_ViewWindow* pview )
+{
+ class ActiveViewChange : public PyInterp_LockRequest
+ {
+ public:
+ ActiveViewChange( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+ : PyInterp_LockRequest( _py_interp, 0, true ),
+ myObj(_obj),myView(_pview) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->activeViewChanged( myView );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ const SUIT_ViewWindow * myView;
+ };
+
+ PyInterp_Dispatcher::Get()->Exec( new ActiveViewChange( myInterp, this, pview ) );
+}
+
+/*!
+ \brief Processes the view changing, calls Python module's activeViewChanged() method
+ \param pview view being activated
+*/
+void SALOME_PYQT_ModuleLight::activeViewChanged( const SUIT_ViewWindow* pview )
+{
+ if ( !myInterp || !myModule )
+ return;
+
+ // Do not use SUIT_ViewWindow::closing() signal here. View manager reacts on
+ // this signal and deletes view. So our slot does not works if it is connected
+ // on this signal. SUIT_ViewManager::deleteView(SUIT_ViewWindow*) is used here
+
+ connectView( pview );
+
+ if ( PyObject_HasAttrString( myModule, (char*)"activeViewChanged" ) )
+ {
+ if ( !pview )
+ return;
+
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeViewChanged", (char*)"i" , pview->getId() ) );
+ if( !res )
+ PyErr_Print();
+ }
+}
+
+/*!
+ \brief Signal handler cloneView() of OCCViewer_ViewWindow
+ \param pview view being cloned
+*/
+void SALOME_PYQT_ModuleLight::onViewCloned( SUIT_ViewWindow* pview )
+{
+ class ViewClone : public PyInterp_LockRequest
+ {
+ public:
+ ViewClone( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+ : PyInterp_LockRequest( _py_interp, 0, true ),
+ myObj(_obj), myView(_pview) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->viewCloned( myView );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ const SUIT_ViewWindow* myView;
+ };
+
+ PyInterp_Dispatcher::Get()->Exec( new ViewClone( myInterp, this, pview ) );
+}
+
+/*!
+ \brief Processes the view cloning, calls Python module's activeViewCloned() method
+ \param pview view being cloned
+*/
+void SALOME_PYQT_ModuleLight::viewCloned( const SUIT_ViewWindow* pview )
+{
+ if ( !myInterp || !myModule || !pview )
+ return;
+
+ if ( PyObject_HasAttrString( myModule, (char*)"viewCloned" ) )
+ {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewCloned", (char*)"i", pview->getId() ) );
+ if( !res )
+ PyErr_Print();
+ }
+}
+
+/*!
+ \brief Signal handler tryClose(SUIT_ViewWindow*) of a view
+ \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::onViewTryClose( SUIT_ViewWindow* pview )
+{
+ class ViewTryClose : public PyInterp_LockRequest
+ {
+ public:
+ ViewTryClose( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+ : PyInterp_LockRequest( _py_interp, 0, true ),
+ myObj(_obj),myView(_pview) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->viewTryClose( myView );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ const SUIT_ViewWindow * myView;
+ };
+
+ PyInterp_Dispatcher::Get()->Exec( new ViewTryClose( myInterp, this, pview ) );
+}
+
+/*!
+ \brief Processes the view closing attempt, calls Python module's viewTryClose() method
+ \param pview view user tries to close
+*/
+void SALOME_PYQT_ModuleLight::viewTryClose( const SUIT_ViewWindow* pview )
+{
+ if ( !myInterp || !myModule )
+ return;
+
+ if ( PyObject_HasAttrString( myModule, (char*)"viewTryClose" ) )
+ {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewTryClose", (char*)"i", pview->getId() ) );
+ if ( !res )
+ {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Signal handler closing(SUIT_ViewWindow*) of a view
+ \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::onViewClosed( SUIT_ViewWindow* pview )
+{
+ class ViewClose : public PyInterp_LockRequest
+ {
+ public:
+ ViewClose( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+ : PyInterp_LockRequest( _py_interp, 0, true ),
+ myObj(_obj),myView(_pview) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->viewClosed( myView );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ const SUIT_ViewWindow * myView;
+ };
+
+ PyInterp_Dispatcher::Get()->Exec( new ViewClose( myInterp, this, pview ) );
+}
+
+/*!
+ \brief Processes the view closing, calls Python module's viewClosed() method
+ \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::viewClosed( const SUIT_ViewWindow* pview )
+{
+ if ( !myInterp || !myModule )
+ return;
+
+ if ( PyObject_HasAttrString( myModule, (char*)"viewClosed" ) )
+ {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewClosed", (char*)"i", pview->getId() ) );
+ if ( !res )
+ {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Connects or disconnects signals about activating and cloning view on the module slots
+ \param pview view which is connected/disconnected
+*/
+void SALOME_PYQT_ModuleLight::connectView( const SUIT_ViewWindow* pview )
+{
+ SUIT_ViewManager* viewMgr = pview->getViewManager();
+ SUIT_ViewModel* viewModel = viewMgr ? viewMgr->getViewModel() : 0;
+
+ if ( viewMgr )
+ {
+ disconnect( viewMgr, SIGNAL( tryCloseView( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewTryClose( SUIT_ViewWindow* ) ) );
+ disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+
+ connect( viewMgr, SIGNAL( tryCloseView( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewTryClose( SUIT_ViewWindow* ) ) );
+ connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+ }
+
+ // Connect cloneView() signal of an OCC View
+ if ( pview->inherits( "OCCViewer_ViewWindow" ) )
+ {
+ disconnect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ connect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ }
+ // Connect cloneView() signal of Plot2d View manager
+ else if ( viewModel && viewModel->inherits( "Plot2d_Viewer" ) )
+ {
+ disconnect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ connect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ }
+}
+
+/*!
+ \brief Get tag name for the DOM element.
+ \param element DOM element
+ \return empty string if the element does not have tag name
+ \internal
+*/
+static QString tagName( const QDomElement& element )
+{
+ return element.tagName().trimmed();
+}
+
+/*!
+ \brief Get DOM element's attribute by its name.
+ \param element DOM element
+ \param attName attribute name
+ \return empty string if the element does not have such attribute
+ \internal
+*/
+static QString attribute( const QDomElement& element, const QString& attName )
+{
+ return element.attribute( attName ).trimmed();
+}
+
+/*!
+ \brief Inspect specified string for the boolean value.
+
+ This function returns \c true if string represents boolean value:
+ - "true", "yes" or "1" for \c true
+ - "false", "no" or "0" for \c false
+ Second parameter allows to specify what boolean value is expected:
+ - 1: \c true
+ - 0: \c false
+ - other value is not taken into account (return represented value)
+
+ \param value inspected string
+ \param check expected boolean value
+ \return boolean value represented by the string (\a check is not 1 or 0)
+ or \c true if value correspond to the specified \a check
+*/
+static bool checkBool( const QString& value, const int check = -1 )
+{
+ QString v = value.toLower();
+ if ( ( v == "true" || v == "yes" || v == "1" ) && ( check != 0 ) )
+ return true;
+ if ( ( v == "false" || v == "no" || v == "0" ) && ( check == 0 ) )
+ return true;
+ return false;
+}
+
+/*!
+ \brief Inspect specified string for the integer value.
+
+ This function returns returns -1 if item is empty or represents
+ an invalid number.
+ \param value inspected string
+ \param def default value
+ \param shift shift value (it is added to the integer value to produce shifted result)
+*/
+static int checkInt( const QString& value, const int def = -1, const int shift = -1 )
+{
+ bool bOk;
+ int val = value.toInt( &bOk );
+ if ( !bOk ) val = def;
+ if ( shift > 0 && bOk && val < 0 )
+ val += shift;
+ return val;
+}
+
+/*!
+ \brief Constructor
+ \internal
+ \param module parent module pointer
+ \param fileName XML file path
+*/
+SALOME_PYQT_ModuleLight::XmlHandler::XmlHandler( SALOME_PYQT_ModuleLight* module,
+ const QString& fileName )
+: myModule( module )
+{
+ if ( fileName.isEmpty() )
+ return;
+ QFile aFile( fileName );
+ if ( !aFile.open( QIODevice::ReadOnly ) )
+ return;
+ myDoc.setContent( &aFile );
+ aFile.close();
+}
+
+/*!
+ \brief Parse XML file and create actions.
+ \internal
+
+ Called by SALOME_PYQT_ModuleLight::activate() in order to create actions
+ (menus, toolbars).
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createActions()
+{
+ // get document element
+ QDomElement aDocElem = myDoc.documentElement();
+
+ // create main menu actions
+ QDomNodeList aMenuList = aDocElem.elementsByTagName( "menu-item" );
+ for ( int i = 0; i < aMenuList.count(); i++ ) {
+ QDomNode n = aMenuList.item( i );
+ createMenu( n );
+ }
+
+ // create toolbars actions
+ QDomNodeList aToolsList = aDocElem.elementsByTagName( "toolbar" );
+ for ( int i = 0; i < aToolsList.count(); i++ ) {
+ QDomNode n = aToolsList.item( i );
+ createToolBar( n );
+ }
+}
+
+/*!
+ \brief Create popup menu.
+ \internal
+ \param menu popup menu
+ \param context popup menu context
+ \param context popup menu parent object name
+ \param context popup menu object name
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createPopup( QMenu* menu,
+ const QString& context,
+ const QString& parent,
+ const QString& object )
+{
+ // get document element
+ QDomElement aDocElem = myDoc.documentElement();
+
+ // get popup menus actions
+ QDomNodeList aPopupList = aDocElem.elementsByTagName( "popupmenu" );
+ for ( int i = 0; i < aPopupList.count(); i++ ) {
+ QDomNode n = aPopupList.item( i );
+ if ( !n.isNull() && n.isElement() ) {
+ QDomElement e = n.toElement();
+ // QString lab = attribute( e, "label-id" ); // not used //
+ QString ctx = attribute( e, "context-id" );
+ QString prt = attribute( e, "parent-id" );
+ QString obj = attribute( e, "object-id" );
+ if ( ctx == context && prt == parent && obj == object ) {
+ insertPopupItems( n, menu );
+ break;
+ }
+ }
+ }
+}
+
+/*!
+ \brief Activate menus
+ \internal
+ \param enable if \c true menus are activated, otherwise menus are deactivated
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::activateMenus( bool enable )
+{
+ if ( !myModule )
+ return;
+
+ QtxActionMenuMgr* mgr = myModule->menuMgr();
+ int id;
+ foreach( id, myMenuItems ) mgr->setEmptyEnabled( id, enable );
+}
+
+/*!
+ \brief Create main menu item and insert actions to it.
+ \internal
+ \param parentNode XML node with menu description
+ \param parentMenuId parent menu ID (-1 for top-level menu)
+ \param parentPopup parent popup menu (0 for top-level menu)
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createMenu( QDomNode& parentNode,
+ const int parentMenuId,
+ QMenu* parentPopup )
+{
+ if ( !myModule || parentNode.isNull() )
+ return;
+
+ QDomElement parentElement = parentNode.toElement();
+ if ( !parentElement.isNull() ) {
+ QString plabel = attribute( parentElement, "label-id" );
+ int pid = checkInt( attribute( parentElement, "item-id" ) );
+ int ppos = checkInt( attribute( parentElement, "pos-id" ) );
+ int group = checkInt( attribute( parentElement, "group-id" ),
+ myModule->defaultMenuGroup() );
+ if ( !plabel.isEmpty() ) {
+ QMenu* popup = 0;
+ int menuId = -1;
+ // create menu
+ menuId = myModule->createMenu( plabel, // label
+ parentMenuId, // parent menu ID, -1 for top-level menu
+ pid, // ID
+ group, // group ID
+ ppos ); // position
+ myMenuItems.append( menuId );
+ QDomNode node = parentNode.firstChild();
+ while ( !node.isNull() ) {
+ if ( node.isElement() ) {
+ QDomElement elem = node.toElement();
+ QString aTagName = tagName( elem );
+ if ( aTagName == "popup-item" ) {
+ int id = checkInt( attribute( elem, "item-id" ) );
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ int group = checkInt( attribute( elem, "group-id" ),
+ myModule->defaultMenuGroup() );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+ QString tooltip = attribute( elem, "tooltip-id" );
+ QString accel = attribute( elem, "accel-id" );
+ bool toggle = checkBool( attribute( elem, "toggle-id" ) );
+
+ // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+ // also check if the action with given ID is already created
+ if ( id != -1 ) {
+ // create menu action
+ QAction* action = myModule->createAction( id, // ID
+ tooltip, // tooltip
+ icon, // icon
+ label, // menu text
+ tooltip, // status-bar text
+ QKeySequence( accel ), // keyboard accelerator
+ toggle ); // toogled action
+ myModule->createMenu( action, // action
+ menuId, // parent menu ID
+ id, // ID (same as for createAction())
+ group, // group ID
+ pos ); // position
+ }
+ }
+ else if ( aTagName == "submenu" ) {
+ // create sub-menu
+ createMenu( node, menuId, popup );
+ }
+ else if ( aTagName == "separator" ) {
+ // create menu separator
+ int id = checkInt( attribute( elem, "item-id" ) ); // separator can have ID
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ int group = checkInt( attribute( elem, "group-id" ),
+ myModule->defaultMenuGroup() );
+ QAction* action = myModule->separator();
+ myModule->createMenu( action, // separator action
+ menuId, // parent menu ID
+ id, // ID
+ group, // group ID
+ pos ); // position
+ }
+ }
+ node = node.nextSibling();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Create a toolbar and insert actions to it.
+ \param parentNode XML node with toolbar description
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createToolBar( QDomNode& parentNode )
+{
+ if ( !myModule || parentNode.isNull() )
+ return;
+
+ QDomElement parentElement = parentNode.toElement();
+ if ( !parentElement.isNull() ) {
+ QString aLabel = attribute( parentElement, "label-id" );
+ if ( !aLabel.isEmpty() ) {
+ // create toolbar
+ int tbId = myModule->createTool( aLabel );
+ QDomNode node = parentNode.firstChild();
+ while ( !node.isNull() ) {
+ if ( node.isElement() ) {
+ QDomElement elem = node.toElement();
+ QString aTagName = tagName( elem );
+ if ( aTagName == "toolbutton-item" ) {
+ int id = checkInt( attribute( elem, "item-id" ) );
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+ QString tooltip = attribute( elem, "tooltip-id" );
+ QString accel = attribute( elem, "accel-id" );
+ bool toggle = checkBool( attribute( elem, "toggle-id" ) );
+
+ // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+ // also check if the action with given ID is already created
+ if ( id != -1 ) {
+ // create toolbar action
+ QAction* action = myModule->createAction( id, // ID
+ tooltip, // tooltip
+ icon, // icon
+ label, // menu text
+ tooltip, // status-bar text
+ QKeySequence( accel ), // keyboard accelerator
+ toggle ); // toogled action
+ myModule->createTool( action, tbId, -1, pos );
+ }
+ }
+ else if ( aTagName == "separatorTB" || aTagName == "separator" ) {
+ // create toolbar separator
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QAction* action = myModule->separator();
+ myModule->createTool( action, tbId, -1, pos );
+ }
+ }
+ node = node.nextSibling();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Fill popup menu with the items.
+ \param parentNode XML node with popup menu description
+ \param menu popup menu
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::insertPopupItems( QDomNode& parentNode, QMenu* menu )
+{
+ if ( !myModule && parentNode.isNull() )
+ return;
+
+ // we create popup menus without help of QtxPopupMgr
+ QDomNode node = parentNode.firstChild();
+ while ( !node.isNull() ) {
+ if ( node.isElement() ) {
+ QDomElement elem = node.toElement();
+ QString aTagName = tagName( elem );
+ QList<QAction*> actions = menu->actions();
+ if ( aTagName == "popup-item" ) {
+ // insert a command item
+ int id = checkInt( attribute( elem, "item-id" ) );
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+ QString tooltip = attribute( elem, "tooltip-id" );
+ QString accel = attribute( elem, "accel-id" );
+ bool toggle = checkBool( attribute( elem, "toggle-id" ) );
+
+ // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+ // also check if the action with given ID is already created
+ if ( id != -1 ) {
+ QAction* action = myModule->createAction( id, // ID
+ tooltip, // tooltip
+ icon, // icon
+ label, // menu text
+ tooltip, // status-bar text
+ QKeySequence( accel ), // keyboard accelerator
+ toggle ); // toogled action
+ QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+ menu->insertAction( before, action );
+ }
+ }
+ else if ( aTagName == "submenu" ) {
+ // create sub-menu
+ ////int id = checkInt( attribute( elem, "item-id" ) ); // not used //
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+
+ QIcon anIcon;
+ if ( !icon.isEmpty() ) {
+ QPixmap pixmap = myModule->getApp()->resourceMgr()->loadPixmap( myModule->name(), icon );
+ if ( !pixmap.isNull() )
+ anIcon = QIcon( pixmap );
+ }
+
+ QMenu* newPopup = menu->addMenu( anIcon, label );
+ QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+ menu->insertMenu( before, newPopup );
+ insertPopupItems( node, newPopup );
+ }
+ else if ( aTagName == "separator" ) {
+ // create menu separator
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QAction* action = myModule->separator();
+ QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+ menu->insertAction( before, action );
+ }
+ }
+ node = node.nextSibling();
+ }
+}
+
+/*
+ * Save study request.
+ * Called when user save study.
+ */
+void SALOME_PYQT_ModuleLight::save(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::save()")
+ // perform synchronous request to Python event dispatcher
+ class SaveEvent: public PyInterp_LockRequest
+ {
+ public:
+ SaveEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ QStringList& _files_list)
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myFilesList(_files_list) {}
+ protected:
+ virtual void execute()
+ {
+ myObj->saveEvent(myFilesList);
+ }
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QStringList& myFilesList;
+ };
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new SaveEvent( myInterp, this, theListOfFiles ) );
+}
+
+void SALOME_PYQT_ModuleLight::saveEvent(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::saveEvent()");
+ QStringList::Iterator it = theListOfFiles.begin();
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || (it == theListOfFiles.end()))
+ return;
+
+ if ( PyObject_HasAttrString(myModule, (char*)"saveFiles") ) {
+ // temporary set myInitModule because saveEvent() method
+ // might be called by the framework when this module is inactive,
+ // but still it should be possible to access this module's data
+ // from Python
+ myInitModule = this;
+
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"saveFiles",
+ (char*)"s", (*it).toLatin1().constData()));
+
+ myInitModule = 0;
+
+ if( !res ) {
+ PyErr_Print();
+ }
+ else{
+ // parse the return value
+ // result can be one string...
+ if ( PyString_Check( res ) ) {
+ QString astr = PyString_AsString( res );
+ //SCRUTE(astr);
+ theListOfFiles.append(astr);
+ }
+ //also result can be a list...
+ else if ( PyList_Check( res ) ) {
+ int size = PyList_Size( res );
+ for ( int i = 0; i < size; i++ ) {
+ PyObject* value = PyList_GetItem( res, i );
+ if( value && PyString_Check( value ) ) {
+ theListOfFiles.append( PyString_AsString( value ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Python dump request.
+ * Called when user activates dump study operation.
+ */
+void SALOME_PYQT_ModuleLight::dumpPython(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::dumpPython()")
+ // perform synchronous request to Python event dispatcher
+ class DumpEvent: public PyInterp_LockRequest
+ {
+ public:
+ DumpEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ QStringList& _files_list)
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myFilesList(_files_list) {}
+ protected:
+ virtual void execute()
+ {
+ myObj->dumpEvent(myFilesList);
+ }
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QStringList& myFilesList;
+ };
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new DumpEvent( myInterp, this, theListOfFiles ) );
+}
+
+void SALOME_PYQT_ModuleLight::dumpEvent(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::dumpEvent()");
+ QStringList::Iterator it = theListOfFiles.begin();
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || (it == theListOfFiles.end()))
+ return;
+
+ if ( PyObject_HasAttrString(myModule, (char*)"dumpStudy") ) {
+ // temporary set myInitModule because dumpEvent() method
+ // might be called by the framework when this module is inactive,
+ // but still it should be possible to access this module's data
+ // from Python
+ myInitModule = this;
+
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"dumpStudy",
+ (char*)"s", (*it).toLatin1().constData()));
+
+ myInitModule = 0;
+
+ if( !res ) {
+ PyErr_Print();
+ }
+ else{
+ // parse the return value
+ // result can be one string...
+ if ( PyString_Check( res ) ) {
+ QString astr = PyString_AsString( res );
+ //SCRUTE(astr);
+ theListOfFiles.append(astr);
+ }
+ //also result can be a list...
+ else if ( PyList_Check( res ) ) {
+ int size = PyList_Size( res );
+ for ( int i = 0; i < size; i++ ) {
+ PyObject* value = PyList_GetItem( res, i );
+ if( value && PyString_Check( value ) ) {
+ theListOfFiles.append( PyString_AsString( value ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Open study request.
+ * Called when user open study.
+ */
+bool SALOME_PYQT_ModuleLight::open(QStringList theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::open()");
+ // perform synchronous request to Python event dispatcher
+ bool opened = false;
+ class OpenEvent: public PyInterp_LockRequest
+ {
+ public:
+ OpenEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ QStringList _files_list,
+ bool& _opened)
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myFilesList(_files_list),
+ myOpened(_opened) {}
+ protected:
+ virtual void execute()
+ {
+ myObj->openEvent(myFilesList,myOpened);
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QStringList myFilesList;
+ bool& myOpened;
+ };
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new OpenEvent( myInterp, this, theListOfFiles, opened) );
+ return opened;
+}
+
+
+void SALOME_PYQT_ModuleLight::openEvent(QStringList theListOfFiles, bool &opened)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::openEvent()");
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || theListOfFiles.isEmpty())
+ return;
+ QStringList* theList = new QStringList(theListOfFiles);
+
+#if SIP_VERSION < 0x040800
+ PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList) );
+#else
+ PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) );
+#endif
+ if ( PyObject_HasAttrString(myModule , (char*)"openFiles") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"openFiles",
+ (char*)"O", sipList.get()));
+ if( !res || !PyBool_Check( res )) {
+ PyErr_Print();
+ opened = false;
+ }
+ else{
+ opened = PyObject_IsTrue( res );
+
+ }
+ }
+}
+
+/*
+ * Create new empty Data Object and return its entry
+ */
+QString SALOME_PYQT_ModuleLight::createObject(const QString& parent)
+{
+ SALOME_PYQT_DataObjectLight* obj=0;
+ if(!parent.isEmpty())
+ {
+ SALOME_PYQT_DataObjectLight* parentObj = findObject(parent);
+ if(parentObj)
+ {
+ obj = new SALOME_PYQT_DataObjectLight(parentObj);
+ }
+ }
+ else
+ {
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(dm)
+ {
+ obj = new SALOME_PYQT_DataObjectLight(dm->getRoot());
+ }
+ }
+ if (obj)
+ return obj->entry();
+ else
+ return QString::null;
+}
+
+/*
+ * Create new Data Object with name, icon and tooltip
+ * and return its entry
+ */
+QString SALOME_PYQT_ModuleLight::createObject(const QString& aname,
+ const QString& iconname,
+ const QString& tooltip,
+ const QString& parent)
+{
+ QString entry = createObject(parent);
+ SALOME_PYQT_DataObjectLight* obj = findObject(entry);
+
+ if(obj)
+ {
+ obj->setName(aname);
+ obj->setToolTip(tooltip);
+ obj->setIcon(iconname);
+ return obj->entry();
+ }
+ else
+ return QString::null;
+}
+
+/*
+ * Find object by entry
+ */
+SALOME_PYQT_DataObjectLight* SALOME_PYQT_ModuleLight::findObject(const QString& entry)
+{
+ SALOME_PYQT_DataObjectLight* obj = 0;
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(!entry.isEmpty() && dm ){
+ for ( SUIT_DataObjectIterator it( dm->getRoot(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
+ SALOME_PYQT_DataObjectLight* curentobj =
+ dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.current() );
+
+ if(curentobj && curentobj->entry() == entry) {
+ obj = curentobj;
+ return obj;
+ }
+ }
+ }
+ return obj;
+}
+
+/*
+ * Set Name for object
+ */
+void SALOME_PYQT_ModuleLight::setName(const QString& obj, const QString& name)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->setName(name);
+ }
+}
+
+/*
+ * Set Icon for object
+ */
+void SALOME_PYQT_ModuleLight::setIcon(const QString& obj, const QString& iconname)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->setIcon(iconname);
+ }
+}
+
+/*
+ * Return Name of object
+ */
+QString SALOME_PYQT_ModuleLight::getName(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ return dataObj->name();
+ }
+ return QString::null;
+}
+
+/*
+ * Return Tool Tip of object
+ */
+QString SALOME_PYQT_ModuleLight::getToolTip(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ return dataObj->toolTip();
+ }
+ return QString::null;
+}
+
+
+/*
+ * Set Tool Tip for object
+ */
+void SALOME_PYQT_ModuleLight::setToolTip(const QString& obj, const QString& tooltip)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->setToolTip(tooltip);
+ }
+}
+
+/*
+ * Return color of object
+ */
+QColor SALOME_PYQT_ModuleLight::getColor(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject( obj );
+ if( dataObj ) {
+ return dataObj->color( SUIT_DataObject::Foreground );
+ }
+ return QColor();
+}
+
+/*
+ * Set color for object
+ */
+void SALOME_PYQT_ModuleLight::setColor(const QString& obj, const QColor& color)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject( obj );
+ if( dataObj ) {
+ dataObj->setColor( color );
+ }
+}
+
+/*
+ * Return entry of the referenced object (if any)
+ */
+QString SALOME_PYQT_ModuleLight::getReference(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ return dataObj->refEntry();
+ }
+ return QString::null;
+}
+
+
+/*
+ * Set entry of the referenced object
+ */
+void SALOME_PYQT_ModuleLight::setReference(const QString& obj, const QString& refEntry)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->setRefEntry(refEntry);
+ }
+}
+
+/*
+ * Remove object by entry
+ */
+void SALOME_PYQT_ModuleLight::removeObject(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->parent()->removeChild(dataObj);
+ }
+}
+
+
+/*
+ * Remove chields from object
+ */
+void SALOME_PYQT_ModuleLight::removeChild(const QString& obj)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::removeChild()");
+ DataObjectList lst;
+ if(!obj.isEmpty())
+ {
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj)
+ {
+ dataObj->children(lst);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while( it.hasNext() )
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ dataObj->removeChild(sobj);
+ }
+ }
+ }
+ else
+ {
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(dm)
+ {
+ dm->getRoot()->children(lst);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while(it.hasNext() )
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ dm->getRoot()->removeChild(sobj);
+ }
+ }
+ }
+}
+
+QStringList SALOME_PYQT_ModuleLight::getChildren(const QString& obj, const bool rec)
+{
+ DataObjectList lst;
+ QStringList entryList;
+ if(!obj.isEmpty())
+ {
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj)
+ {
+ dataObj->children(lst,rec);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while(it.hasNext())
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ entryList.append(sobj->entry());
+ }
+ }
+ }
+ else
+ {
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(dm)
+ {
+ dm->getRoot()->children(lst);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while( it.hasNext() )
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ entryList.append(sobj->entry());
+ }
+ }
+ }
+ return entryList;
+}
+
+/*!
+ * Create new instance of data model and return it.
+ */
+CAM_DataModel* SALOME_PYQT_ModuleLight::createDataModel()
+{
+ MESSAGE( "SALOME_PYQT_ModuleLight::createDataModel()" );
+ return new SALOME_PYQT_DataModelLight(this);
+}
+
+/*!
+ * Returns the Python module object currently loaded.
+ */
+PyObject* SALOME_PYQT_ModuleLight::getPythonModule()
+{
+ return myModule;
+}
+
+bool SALOME_PYQT_ModuleLight::isDraggable( const SUIT_DataObject* what ) const
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::isDraggable()");
+ // perform synchronous request to Python event dispatcher
+ bool draggable = false;
+ class IsDraggableEvent: public PyInterp_LockRequest
+ {
+ public:
+ IsDraggableEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ LightApp_DataObject* _data_object,
+ bool& _is_draggable )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myDataObject( _data_object ),
+ myIsDraggable( _is_draggable ) {}
+ protected:
+ virtual void execute()
+ {
+ myIsDraggable = myObj->isDraggableEvent( myDataObject );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ LightApp_DataObject* myDataObject;
+ bool& myIsDraggable;
+ };
+
+ const LightApp_DataObject* data_object = dynamic_cast<const LightApp_DataObject*>( what );
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new IsDraggableEvent( myInterp,
+ const_cast<SALOME_PYQT_ModuleLight*>( this ),
+ const_cast<LightApp_DataObject*>( data_object ),
+ draggable ) );
+ return draggable;
+}
+
+bool SALOME_PYQT_ModuleLight::isDraggableEvent( LightApp_DataObject* what )
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::isDraggableEvent()");
+
+ bool draggable = false;
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || !what )
+ return draggable;
+
+ if ( PyObject_HasAttrString(myModule , (char*)"isDraggable") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"isDraggable",
+ (char*)"s", what->entry().toLatin1().constData() ) );
+ if( !res || !PyBool_Check( res )) {
+ PyErr_Print();
+ draggable = false;
+ }
+ else{
+ draggable = PyObject_IsTrue( res );
+ }
+ }
+
+ return draggable;
+}
+
+bool SALOME_PYQT_ModuleLight::isDropAccepted( const SUIT_DataObject* where ) const
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::isDropAccepted()");
+ // perform synchronous request to Python event dispatcher
+ bool dropAccepted = false;
+ class IsDropAcceptedEvent: public PyInterp_LockRequest
+ {
+ public:
+ IsDropAcceptedEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ LightApp_DataObject* _data_object,
+ bool& _is_drop_accepted )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myDataObject( _data_object ),
+ myIsDropAccepted( _is_drop_accepted ) {}
+ protected:
+ virtual void execute()
+ {
+ myIsDropAccepted = myObj->isDropAcceptedEvent( myDataObject );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ LightApp_DataObject* myDataObject;
+ bool& myIsDropAccepted;
+ };
+
+ const LightApp_DataObject* data_object = dynamic_cast<const LightApp_DataObject*>( where );
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new IsDropAcceptedEvent( myInterp,
+ const_cast<SALOME_PYQT_ModuleLight*>( this ),
+ const_cast<LightApp_DataObject*>( data_object ),
+ dropAccepted ) );
+ return dropAccepted;
+}
+
+bool SALOME_PYQT_ModuleLight::isDropAcceptedEvent( LightApp_DataObject* where )
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::isDropAcceptedEvent()");
+
+ bool dropAccepted = false;
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || !where )
+ return dropAccepted;
+
+ if ( PyObject_HasAttrString(myModule , (char*)"isDropAccepted") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"isDropAccepted",
+ (char*)"s", where->entry().toLatin1().constData() ) );
+ if( !res || !PyBool_Check( res )) {
+ PyErr_Print();
+ dropAccepted = false;
+ }
+ else{
+ dropAccepted = PyObject_IsTrue( res );
+ }
+ }
+
+ return dropAccepted;
+}
+
+void SALOME_PYQT_ModuleLight::dropObjects( const DataObjectList& what, SUIT_DataObject* where,
+ const int row, Qt::DropAction action )
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::dropObjects()");
+ // perform synchronous request to Python event dispatcher
+ class DropObjectsEvent: public PyInterp_LockRequest
+ {
+ public:
+ DropObjectsEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ const DataObjectList& _what,
+ SUIT_DataObject* _where,
+ const int _row,
+ Qt::DropAction _action )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myWhat( _what ),
+ myWhere( _where ),
+ myRow ( _row ),
+ myAction ( _action ){}
+ protected:
+ virtual void execute()
+ {
+ myObj->dropObjectsEvent( myWhat, myWhere, myRow, myAction );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ DataObjectList myWhat;
+ SUIT_DataObject* myWhere;
+ int myRow;
+ Qt::DropAction myAction;
+ };
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new DropObjectsEvent( myInterp, this, what, where, row, action ) );
+}
+
+void SALOME_PYQT_ModuleLight::dropObjectsEvent( const DataObjectList& what, SUIT_DataObject* where,
+ const int row, Qt::DropAction action )
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::dropObjectsEvent()");
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || what.isEmpty() || !where )
+ return;
+
+ QStringList* theList = new QStringList();
+
+ LightApp_DataObject* whereObject = dynamic_cast<LightApp_DataObject*>( where );
+ if ( !whereObject ) return;
+
+ for ( int i = 0; i < what.count(); i++ ) {
+ LightApp_DataObject* dataObject = dynamic_cast<LightApp_DataObject*>( what[i] );
+ if ( dataObject ) theList->append( dataObject->entry() );
+ }
+
+#if SIP_VERSION < 0x040800
+ PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList) );
+#else
+ PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL) );
+#endif
+ if ( PyObject_HasAttrString(myModule, (char*)"dropObjects") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"dropObjects", (char*)"Osii",
+ sipList.get(),
+ whereObject->entry().toLatin1().constData(),
+ row, action ) );
+
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File : SALOME_PYQT_Module.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+#ifndef SALOME_PYQT_MODULELIGHT_H
+#define SALOME_PYQT_MODULELIGHT_H
+
+#include "PyInterp_Interp.h" // // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+#include "SALOME_PYQT_GUILight.h"
+#include "LightApp_Module.h"
+#include "SALOME_PYQT_DataObjectLight.h"
+#include <CAM_Module.h>
+
+#include <map>
+#include <QStringList>
+#include <QList>
+#include <QMap>
+#include <QIcon>
+
+class SALOME_PYQT_RootObjectLight;
+class SALOME_PYQT_PyInterp;
+class SUIT_ViewWindow;
+class QAction;
+class QtxActionGroup;
+class QMenu;
+
+
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_ModuleLight: virtual public LightApp_Module
+{
+ Q_OBJECT;
+
+private:
+ class XmlHandler;
+
+ //! study to Python subinterpreter map
+ typedef QMap<int, PyInterp_Interp*> InterpMap;
+ static SALOME_PYQT_ModuleLight* myInitModule; //!< Python GUI being initialized (not zero only during the initialization)
+
+ XmlHandler* myXmlHandler; //!< XML resource file parser
+ QMap<int, int> myWindowsMap; //!< windows map
+ QStringList myViewMgrList;//!< compatible view managers list
+ bool myLastActivateStatus; //!< latest module activation status
+
+protected:
+ PyObject* myModule; //!< Python GUI module
+ PyInterp_Interp* myInterp; //!< current Python subinterpreter
+ static InterpMap myInterpMap; //!< study to Python subinterpreter map
+
+public:
+ SALOME_PYQT_ModuleLight();
+ ~SALOME_PYQT_ModuleLight();
+
+public:
+ static SALOME_PYQT_ModuleLight* getInitModule();
+
+ void initialize( CAM_Application* );
+ void windows( QMap<int, int>& ) const;
+ void viewManagers( QStringList& ) const;
+ void contextMenuPopup( const QString&, QMenu*, QString& );
+ void createPreferences();
+ void studyActivated();
+ void preferencesChanged( const QString&, const QString& );
+
+ static int defaultMenuGroup();
+
+ int createTool( const QString& );
+ int createTool( const int, const int, const int = -1 );
+ int createTool( const int, const QString&, const int = -1 );
+ int createTool( QAction*, const int,
+ const int = -1, const int = -1 );
+ int createTool( QAction*, const QString&,
+ const int = -1, const int = -1 );
+
+ int createMenu( const QString&, const int,
+ const int = -1, const int = -1, const int = -1 );
+ int createMenu( const QString&, const QString&,
+ const int = -1, const int = -1, const int = -1 );
+ int createMenu( const int, const int,
+ const int = -1, const int = -1 );
+ int createMenu( const int, const QString&,
+ const int = -1, const int = -1 );
+ int createMenu( QAction*, const int,
+ const int = -1, const int = -1, const int = -1 );
+ int createMenu( QAction*, const QString&,
+ const int = -1, const int = -1, const int = -1 );
+
+ QAction* separator();
+
+ QAction* action( const int ) const;
+ int actionId( const QAction* ) const;
+ QAction* createAction( const int, const QString&, const QString&,
+ const QString&, const QString&, const int,
+ const bool = false, QObject* = 0 );
+ QtxActionGroup* createActionGroup( const int, const bool );
+
+
+ QIcon loadIcon( const QString& fileName );
+
+ int addGlobalPreference( const QString& );
+ int addPreference( const QString& );
+ int addPreference( const QString&, const int, const int = LightApp_Preferences::Auto,
+ const QString& = QString(),
+ const QString& = QString() );
+ QVariant preferenceProperty( const int, const QString& ) const;
+ void setPreferenceProperty( const int, const QString&,
+ const QVariant& );
+
+ void save(QStringList& theListOfFiles);
+ bool open(QStringList theListOfFiles);
+ void dumpPython(QStringList& theListOfFiles);
+
+ /*create new SALOME_PYQT_DataObjectLight and return its entry*/
+ QString createObject(const QString& parent);
+ QString createObject(const QString& name,
+ const QString& iconname,
+ const QString& tooltip,
+ const QString& parent);
+ /*Sets Name, Icon and Tool Tip for object*/
+ void setName(const QString& obj,const QString& iconname);
+ void setIcon(const QString& obj,const QString& name);
+ void setToolTip(const QString& obj, const QString& tooltip);
+
+ /*Gets Name and Tool Tip for object*/
+ QString getName(const QString& obj);
+ QString getToolTip(const QString& obj);
+
+ void setColor(const QString& obj, const QColor& color);
+ QColor getColor(const QString& obj);
+
+ void setReference( const QString& obj,
+ const QString& refEntry );
+ QString getReference( const QString& obj );
+
+ /*remove object*/
+ void removeObject(const QString& obj);
+ /*remove child*/
+ void removeChild(const QString& obj);
+ /*return list of child objets*/
+ QStringList getChildren(const QString& obj, const bool rec);
+
+ /*Access to the underlying Python module object */
+ PyObject* getPythonModule();
+
+ /*Drag and drop support*/
+ virtual bool isDraggable( const SUIT_DataObject* ) const;
+ virtual bool isDropAccepted( const SUIT_DataObject* ) const;
+ virtual void dropObjects( const DataObjectList&, SUIT_DataObject*,
+ const int, Qt::DropAction );
+
+public slots:
+ virtual bool activateModule( SUIT_Study* );
+ virtual bool deactivateModule( SUIT_Study* );
+ void preferenceChanged( const QString&,
+ const QString&,
+ const QString& );
+ void onGUIEvent();
+
+ void onActiveViewChanged( SUIT_ViewWindow* );
+ void onViewTryClose( SUIT_ViewWindow* );
+ void onViewClosed( SUIT_ViewWindow* );
+ void onViewCloned( SUIT_ViewWindow* );
+
+protected:
+ /* create data model */
+ virtual CAM_DataModel* createDataModel();
+ virtual bool activateModuleInternal( SUIT_Study* );
+
+private:
+ void init( CAM_Application* );
+ void activate( SUIT_Study* );
+ void deactivate( SUIT_Study* );
+ bool lastActivationStatus() const;
+ void customize( SUIT_Study* );
+ void studyChanged( SUIT_Study* );
+ void contextMenu( const QString&, QMenu* );
+ void guiEvent( const int );
+ void initPreferences();
+ void prefChanged( const QString&, const QString& );
+
+ virtual void initInterp ( int );
+ void importModule();
+ void setWorkSpace();
+
+ void activeViewChanged( const SUIT_ViewWindow* );
+ void viewTryClose( const SUIT_ViewWindow* );
+ void viewClosed( const SUIT_ViewWindow* );
+ void viewCloned( const SUIT_ViewWindow* );
+ void connectView( const SUIT_ViewWindow* );
+
+ void saveEvent(QStringList& theListOfFiles);
+ void dumpEvent(QStringList& theListOfFiles);
+ void openEvent(QStringList theListOfFiles, bool& opened);
+
+ bool isDraggableEvent( LightApp_DataObject* );
+ bool isDropAcceptedEvent( LightApp_DataObject* );
+ void dropObjectsEvent( const DataObjectList&, SUIT_DataObject*,
+ const int, Qt::DropAction );
+
+ SALOME_PYQT_DataObjectLight* findObject(const QString& entry);
+
+ friend class XmlHandler;
+};
+
+#endif // SALOME_PYQT_MODULELIGHT_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SALOME_PYQT_PyInterp.h" // this include must be first !!
+
+#include <SUITApp_init_python.hxx>
+#include <PyInterp_Interp.h>
+#include <utilities.h>
+
+#ifndef GUI_DISABLE_CORBA
+#include <Container_init_python.hxx>
+#endif
+
+
+
+
+/*!
+ * constructor : the main SALOME Python interpreter is used for PyQt GUI.
+ * calls initialize method defined in base class, which calls virtual methods
+ * initstate & initcontext redefined here
+ */
+SALOME_PYQT_PyInterp::SALOME_PYQT_PyInterp(): PyInterp_Interp()
+{
+}
+
+SALOME_PYQT_PyInterp::~SALOME_PYQT_PyInterp()
+{
+}
+
+void SALOME_PYQT_PyInterp::initPython()
+{
+ /*
+ * Do nothing
+ * The initialization has been done in main
+ */
+ MESSAGE("SALOME_PYQT_PyInterp::initPython");
+#ifndef GUI_DISABLE_CORBA
+ if(SUIT_PYTHON::initialized) {
+ ASSERT(SUIT_PYTHON::_gtstate); // initialisation in main
+ SCRUTE(SUIT_PYTHON::_gtstate);
+ _tstate = SUIT_PYTHON::_gtstate;
+ }
+ else {
+ ASSERT(KERNEL_PYTHON::_gtstate); // initialisation in main
+ SCRUTE(KERNEL_PYTHON::_gtstate);
+ _tstate = KERNEL_PYTHON::_gtstate;
+ }
+#else
+ SCRUTE(SUIT_PYTHON::_gtstate);
+ _tstate = SUIT_PYTHON::_gtstate;
+#endif
+}
+
+bool SALOME_PYQT_PyInterp::initState()
+{
+ /*
+ * The GIL is assumed to not be held on the call
+ * The GIL is acquired in initState and will be held on initState exit
+ * It is the caller responsability to release the lock on exit if needed
+ */
+ PyEval_AcquireThread(_tstate);
+ SCRUTE(_tstate);
+ PyEval_ReleaseThread(_tstate);
+ return true;
+}
+
+
+bool SALOME_PYQT_PyInterp::initContext()
+{
+ /*
+ * The GIL is assumed to be held
+ * It is the caller responsability to acquire the GIL before calling initContext
+ * It will still be held on initContext exit
+ */
+ _g = PyDict_New(); // create interpreter dictionnary context
+ PyObject *bimod = PyImport_ImportModule("__builtin__");
+ PyDict_SetItemString(_g, "__builtins__", bimod);
+ Py_DECREF(bimod);
+ return true;
+}
+
+int SALOME_PYQT_PyInterp::run(const char *command)
+{
+ MESSAGE("compile");
+ PyObject *code = Py_CompileString((char *)command,"PyGUI",Py_file_input);
+ if(!code){
+ // Une erreur s est produite en general SyntaxError
+ PyErr_Print();
+ return -1;
+ }
+ //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+ // PyObject *r = PyEval_EvalCode(code,_g,_g);
+ //#else
+ PyObject *r = PyEval_EvalCode((PyCodeObject *)code,_g,_g);
+ //#endif
+ Py_DECREF(code);
+ if(!r){
+ // Une erreur s est produite a l execution
+ PyErr_Print();
+ return -1 ;
+ }
+ Py_DECREF(r);
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File : SALOME_PYQT_Module.h
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 13/04/2009
+//
+#ifndef SALOME_PYQT_PYINTERP_H
+#define SALOME_PYQT_PYINTERP_H
+
+#include "SALOME_PYQT_GUILight.h"
+
+#include "PyInterp_Interp.h" // this include must be first !!!
+
+class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_PyInterp : public PyInterp_Interp
+{
+ public:
+ SALOME_PYQT_PyInterp();
+ ~SALOME_PYQT_PyInterp();
+
+ int run(const char *command);
+
+ protected:
+ virtual void initPython();
+ virtual bool initState();
+ virtual bool initContext();
+};
+
+#endif // SALOME_PYQT_PYINTERP_H
--- /dev/null
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+#
+# Note that the plugins files should be installed in the directory
+# <salomepluginsdir> (ROOT_DIR/share/salome/plugins) or one of this
+# sub-directories (the search of plugins by the plugin manager is
+# recurcive from this folder, in each SALOME module, i.e. each
+# variable *_ROOT_DIR).
+#
+pluginsdir =$(salomepluginsdir)/demo
+plugins_PYTHON = \
+ salome_plugins.py \
+ smesh_plugins.py \
+ trihedron.py \
+ tubedialog_ui.py \
+ tubedialog.py \
+ tubebuilder.py \
+ xalome.py \
+ minmax_dialog.py \
+ minmax_plugin.py
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>178</width>
+ <height>156</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Get min and max value of control</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Mesh</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QLineEdit" name="mesh">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Control</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QComboBox" name="control"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Min</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QLineEdit" name="minvalue">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Max</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2">
+ <widget class="QLineEdit" name="maxvalue">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>mesh</tabstop>
+ <tabstop>control</tabstop>
+ <tabstop>minvalue</tabstop>
+ <tabstop>maxvalue</tabstop>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>OnCancel()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>253</x>
+ <y>371</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>262</x>
+ <y>101</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>helpRequested()</signal>
+ <receiver>Dialog</receiver>
+ <slot>helpMessage()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>131</x>
+ <y>373</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>131</x>
+ <y>64</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>control</sender>
+ <signal>activated(QString)</signal>
+ <receiver>Dialog</receiver>
+ <slot>compute_minmax()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>250</x>
+ <y>137</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>131</x>
+ <y>81</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <slot>compute_minmax()</slot>
+ <slot>helpMessage()</slot>
+ <slot>OnCancel()</slot>
+ <slot>OnOk()</slot>
+ </slots>
+</ui>
--- /dev/null
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'minmax.ui'
+#
+# Created: Thu Mar 1 15:23:57 2012
+# by: PyQt4 UI code generator 4.8.1
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+try:
+ _fromUtf8 = QtCore.QString.fromUtf8
+except AttributeError:
+ _fromUtf8 = lambda s: s
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ Dialog.setObjectName(_fromUtf8("Dialog"))
+ Dialog.resize(178, 156)
+ Dialog.setSizeGripEnabled(True)
+ self.gridLayout = QtGui.QGridLayout(Dialog)
+ self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
+ self.label_2 = QtGui.QLabel(Dialog)
+ self.label_2.setObjectName(_fromUtf8("label_2"))
+ self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
+ self.mesh = QtGui.QLineEdit(Dialog)
+ self.mesh.setReadOnly(True)
+ self.mesh.setObjectName(_fromUtf8("mesh"))
+ self.gridLayout.addWidget(self.mesh, 0, 1, 1, 2)
+ self.label_3 = QtGui.QLabel(Dialog)
+ self.label_3.setObjectName(_fromUtf8("label_3"))
+ self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
+ self.control = QtGui.QComboBox(Dialog)
+ self.control.setObjectName(_fromUtf8("control"))
+ self.gridLayout.addWidget(self.control, 1, 1, 1, 2)
+ self.label = QtGui.QLabel(Dialog)
+ self.label.setObjectName(_fromUtf8("label"))
+ self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
+ self.minvalue = QtGui.QLineEdit(Dialog)
+ self.minvalue.setReadOnly(True)
+ self.minvalue.setObjectName(_fromUtf8("minvalue"))
+ self.gridLayout.addWidget(self.minvalue, 2, 1, 1, 2)
+ self.label_4 = QtGui.QLabel(Dialog)
+ self.label_4.setObjectName(_fromUtf8("label_4"))
+ self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1)
+ self.maxvalue = QtGui.QLineEdit(Dialog)
+ self.maxvalue.setReadOnly(True)
+ self.maxvalue.setObjectName(_fromUtf8("maxvalue"))
+ self.gridLayout.addWidget(self.maxvalue, 3, 1, 1, 2)
+ self.buttonBox = QtGui.QDialogButtonBox(Dialog)
+ self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.Help)
+ self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
+ self.gridLayout.addWidget(self.buttonBox, 4, 0, 1, 3)
+
+ self.retranslateUi(Dialog)
+ QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.OnCancel)
+ QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("helpRequested()")), Dialog.helpMessage)
+ QtCore.QObject.connect(self.control, QtCore.SIGNAL(_fromUtf8("activated(QString)")), Dialog.compute_minmax)
+ QtCore.QMetaObject.connectSlotsByName(Dialog)
+ Dialog.setTabOrder(self.mesh, self.control)
+ Dialog.setTabOrder(self.control, self.minvalue)
+ Dialog.setTabOrder(self.minvalue, self.maxvalue)
+ Dialog.setTabOrder(self.maxvalue, self.buttonBox)
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Get min and max value of control", None, QtGui.QApplication.UnicodeUTF8))
+ self.label_2.setText(QtGui.QApplication.translate("Dialog", "Mesh", None, QtGui.QApplication.UnicodeUTF8))
+ self.label_3.setText(QtGui.QApplication.translate("Dialog", "Control", None, QtGui.QApplication.UnicodeUTF8))
+ self.label.setText(QtGui.QApplication.translate("Dialog", "Min", None, QtGui.QApplication.UnicodeUTF8))
+ self.label_4.setText(QtGui.QApplication.translate("Dialog", "Max", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+def minmax(context):
+ # get context study, studyId, salomeGui
+ study = context.study
+ studyId = context.studyId
+ sg = context.sg
+
+ from PyQt4.QtGui import QDialog
+ from PyQt4.QtGui import QMessageBox
+ from PyQt4.QtCore import Qt
+ from PyQt4.QtCore import SIGNAL
+
+ from minmax_dialog import Ui_Dialog
+
+ import salome
+ import smesh
+
+ controls_dict = {
+ "Aspect Ratio 3D" : smesh.FT_AspectRatio3D,
+ "Volume" : smesh.FT_Volume3D,
+ "Element Diameter 3D" : smesh.FT_MaxElementLength3D,
+ "Length 2D" : smesh.FT_Length2D,
+ "MultiConnection 2D" : smesh.FT_MultiConnection2D,
+ "Area" : smesh.FT_Area,
+ "Taper" : smesh.FT_Taper,
+ "Aspect Ratio" : smesh.FT_AspectRatio,
+ "Minimum Angle" : smesh.FT_MinimumAngle,
+ "Warping" : smesh.FT_Warping,
+ "Skew" : smesh.FT_Skew,
+ "Element Diameter 2D" : smesh.FT_MaxElementLength2D,
+ "Length" : smesh.FT_Length,
+ "MultiConnection" : smesh.FT_MultiConnection,
+ }
+
+ controls_3d = [
+ "Aspect Ratio 3D",
+ "Volume",
+ "Element Diameter 3D",
+ ]
+ controls_2d = [
+ "Length 2D",
+ "MultiConnection 2D",
+ "Area",
+ "Taper",
+ "Aspect Ratio",
+ "Minimum Angle",
+ "Warping",
+ "Skew",
+ "Element Diameter 2D"
+ ]
+ controls_1d = [
+ "Length",
+ "MultiConnection",
+ ]
+
+ class MinmaxDialog(QDialog):
+ def __init__(self):
+ QDialog.__init__(self, None, Qt.Tool)
+ # Set up the user interface from Designer.
+ self.ui = Ui_Dialog()
+ self.ui.setupUi(self)
+ self.show()
+
+ self.clearLineEdit()
+
+ # Connect up the selectionChanged() event of the object browser.
+ self.connect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+
+ self.mm = None
+ self.ui.control.setFocus()
+ self.select()
+
+ pass
+
+ def OnCancel(self):
+ self.disconnect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+ self.reject()
+ pass
+
+ def clearLineEdit(self):
+ self.ui.mesh.setText("Select a Mesh")
+ self.ui.mesh.setStyleSheet("QLineEdit { color: grey }")
+ self.ui.minvalue.setText("")
+ self.ui.maxvalue.setText("")
+
+ def select(self):
+ self.disconnect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+ self.ui.control.clear()
+ self.ui.minvalue.setText("")
+ self.ui.maxvalue.setText("")
+ objId = salome.sg.getSelected(0)
+ if objId:
+ mm = study.FindObjectID(objId).GetObject()
+ mesh = None
+ try:
+ mesh = mm.GetMEDMesh()
+ except:
+ #print "No mesh selected"
+ self.clearLineEdit()
+ mesh = None
+ pass
+ if mesh:
+ self.ui.mesh.setStyleSheet("")
+ self.ui.mesh.setText(mesh.getName())
+ #print "Mesh selected: ", mesh.getName()
+ self.mm = mm
+ e = self.mm.NbEdges()
+ f = self.mm.NbFaces()
+ v = self.mm.NbVolumes()
+ #print "NbEdges: ",e
+ #print "NbFaces: ",f
+ #print "NbVolumes: ",v
+ controls = []
+ if e:
+ controls += controls_1d
+ pass
+ if f:
+ controls += controls_2d
+ pass
+ if v:
+ controls += controls_3d
+ pass
+ self.ui.control.addItems(controls)
+ self.compute_minmax()
+ self.connect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select)
+ pass
+
+ def helpMessage(self):
+ QMessageBox.about(None, "About Min/Max value of control",
+ """
+ Displays the min/max value of a control
+ ---------------------------------
+
+This plugin displays the min and max value of a control
+on a mesh.
+Inputs:
+ - The mesh to analyse
+ - The control to compute
+ """)
+ pass
+
+ def compute_minmax(self):
+ if self.mm:
+ control = self.ui.control.currentText()
+ #print "Compute control: ",control
+ fun = smesh.GetFunctor(controls_dict[str(control)])
+ fun.SetMesh(self.mm.GetMesh())
+ hist = fun.GetHistogram(1)
+ maxVal = hist[0].max
+ minVal = hist[0].min
+ #print "Max value for %s: %f"%(control, maxVal)
+ #print "Min value for %s: %f"%(control, minVal)
+ self.ui.maxvalue.setText("%f"%(maxVal))
+ self.ui.minvalue.setText("%f"%(minVal))
+ else:
+ print "Pas de maillage"
+ pass
+ pass
+ pass
+
+ window = MinmaxDialog()
+ window.exec_()
+ pass
+
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import salome_pluginsmanager
+
+DEMO_IS_ACTIVATED = False
+
+if DEMO_IS_ACTIVATED:
+ # Check that GEOM and SMESH modules are present
+ try:
+ import geompy, smesh
+ except:
+ DEMO_IS_ACTIVATED = False
+
+if DEMO_IS_ACTIVATED:
+ # -------------------------------------------------------------------------
+ # Example 1: creation of basic objects.
+ # The plugin function is implemented here and declared in the pluginsmanager.
+ #
+ import salome
+
+ def trihedron(context):
+ import geompy
+
+ # Intialize the geompy factory with the active study
+ activeStudy = context.study
+ geompy.init_geom(activeStudy)
+
+ # Create the objects
+ Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
+ Vy = geompy.MakeVectorDXDYDZ(0, 10, 0)
+ Vz = geompy.MakeVectorDXDYDZ(0, 0, 10)
+ origin = geompy.MakeVertex(0, 0, 0)
+
+ # Register the objects in the active study
+ geompy.addToStudy( Vx, "Vx" )
+ geompy.addToStudy( Vy, "Vy" )
+ geompy.addToStudy( Vz, "Vz" )
+ geompy.addToStudy( origin, "origin" )
+
+
+ salome_pluginsmanager.AddFunction('DEMO/O,Vx,Vy,Vz',
+ 'Creates the trihedron',
+ trihedron)
+
+
+ # -------------------------------------------------------------------------
+ # Example 1 bis: creation of basic objects and automatic display
+ def trihedron_withdisplay(context):
+ import geompy
+
+ # Intialize the geompy factory with the active study
+ activeStudy = context.study
+ geompy.init_geom(activeStudy)
+
+ # Create the objects
+ Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
+ Vy = geompy.MakeVectorDXDYDZ(0, 10, 0)
+ Vz = geompy.MakeVectorDXDYDZ(0, 0, 10)
+ origin = geompy.MakeVertex(0, 0, 0)
+
+ # Register the objects in the active study
+ entries=[]
+ entries.append(geompy.addToStudy( Vx, "Vx" ))
+ entries.append(geompy.addToStudy( Vy, "Vy" ))
+ entries.append(geompy.addToStudy( Vz, "Vz" ))
+ entries.append(geompy.addToStudy( origin, "origin" ))
+
+ # This part is to automatically display the objects in the active viewer.
+ gcomp = salome.ImportComponentGUI("GEOM")
+ for entry in entries:
+ gcomp.createAndDisplayFitAllGO(entry)
+
+
+ salome_pluginsmanager.AddFunction('DEMO/O,Vx,Vy,Vz (2)',
+ 'Creates Basic GEOM objects',
+ trihedron_withdisplay)
+
+ # -------------------------------------------------------------------------
+ # Example 2: creation of a shape with parameters that can be read from a GUI.
+ # The plugin function (tube_shapewithgui) delegates some action to
+ # dedicated imported modules (tube.py and tubedialog.py).
+ #
+
+ import tubebuilder
+ import xalome
+
+ # A single dialog box is defined and recycled for every call. The
+ # fields are initialized with default values given by the tube factory
+ # tube.py.
+ import tubedialog
+ dialog = tubedialog.TubeDialog()
+ dialog.setData(tubebuilder.DEFAULT_RADIUS,
+ tubebuilder.DEFAULT_LENGTH,
+ tubebuilder.DEFAULT_WIDTH)
+
+ def tube_shapewithgui(context):
+ global tubebuilder, xalome, dialog
+ activeStudy = context.study
+
+ # Get the parameter values from a gui dialog box. If the dialog is
+ # closed using the Ok button, then the data are requested from the
+ # gui and used to create the shape of the tube.
+ dialog.exec_()
+ if dialog.wasOk():
+ radius, length, width = dialog.getData()
+ shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+ entry = xalome.addToStudy(activeStudy, shape, "Tube" )
+ xalome.displayShape(entry)
+
+
+ salome_pluginsmanager.AddFunction('DEMO/Tube shape from parameters',
+ 'Creates a tube object from specified parameters',
+ tube_shapewithgui)
+
+
+ # -------------------------------------------------------------------------
+ # Example 2 bis: creation of a mesh with parameters that can be read from a GUI.
+ # The plugin function (tube_meshwithgui) delegates some action to
+ # dedicated imported modules (tubebuilder.py and tubedialog.py).
+ #
+ def tube_meshwithgui(context):
+ global tube, dialog
+ activeStudy = context.study
+
+ # Get the parameter values from a gui dialog box. If the dialog is
+ # closed using the Ok button, then the data are requested from the
+ # gui and used to create the shape of the tube.
+ dialog.exec_()
+ if dialog.wasOk():
+ radius, length, width = dialog.getData()
+ mesh = tubebuilder.createModel(activeStudy, radius, length, width)
+
+
+ salome_pluginsmanager.AddFunction('DEMO/Tube mesh from parameters',
+ 'Creates a tube object from specified parameters',
+ tube_meshwithgui)
+
+
+ # -------------------------------------------------------------------------
+ # Example 2 ter: creation of a geom object with a preview function in
+ # the dialog box. This use case is more complex from the gui point of
+ # view because the dialog box is a not modal so that we can have
+ # interaction with the complete SALOME application. This modal
+ # situation requires to connect button click signal on global
+ # functions as a "callback" mechanism.
+ #
+ # TODO:
+ # - coloring the preview in pink
+ # - store the tmp study objects in a "preview" folder
+ #
+ dialogWithApply = tubedialog.TubeDialogOnTopWithApply()
+ dialogWithApply.setData(tubebuilder.DEFAULT_RADIUS,
+ tubebuilder.DEFAULT_LENGTH,
+ tubebuilder.DEFAULT_WIDTH)
+ activeStudy = None
+ previewShapeEntry = None
+
+ DEFAULT_FOLDER_NAME="TubeList"
+ DEFAULT_SHAPE_NAME="tube"
+ PREVIEW_SHAPE_NAME="preview"
+
+ def acceptCallback():
+ """Action to be done when click on Ok"""
+ global tubebuilder, xalome
+ global dialogWithApply, activeStudy
+ global previewShapeEntry, deletePreviewShape
+ global DEFAULT_FOLDER_NAME,DEFAULT_SHAPE_NAME
+
+ dialogWithApply.accept()
+
+ if previewShapeEntry is not None:
+ deletePreviewShape()
+
+ radius, length, width = dialogWithApply.getData()
+ shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+ entry = xalome.addToStudy(activeStudy, shape, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME)
+ xalome.displayShape(entry)
+
+ def rejectCallback():
+ """Action to be done when click on Cancel"""
+ global dialogWithApply, previewShapeEntry, deletePreviewShape
+
+ dialogWithApply.reject()
+
+ if previewShapeEntry is not None:
+ deletePreviewShape()
+
+ import SALOMEDS
+ PREVIEW_COLOR=SALOMEDS.Color(1,0.6,1) # pink
+
+ def applyCallback():
+ """Action to be done when click on Apply"""
+ global tubebuilder, xalome
+ global dialogWithApply, activeStudy
+ global previewShapeEntry, deletePreviewShape
+ global PREVIEW_COLOR, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME, PREVIEW_SHAPE_NAME
+
+ # We first have to destroy the currently displayed preview shape.
+ if previewShapeEntry is not None:
+ deletePreviewShape()
+
+ # Then we can create the new shape with the new parameter values
+ radius, length, width = dialogWithApply.getData()
+ shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+ # We apply a specific color on the shape for the preview state
+ shape.SetColor(PREVIEW_COLOR)
+ previewShapeEntry = xalome.addToStudy(activeStudy, shape, PREVIEW_SHAPE_NAME, DEFAULT_FOLDER_NAME )
+ xalome.displayShape(previewShapeEntry)
+
+ def deletePreviewShape():
+ """This delete the shape currently being displayed as a preview"""
+ global activeStudy, previewShapeEntry, xsalome
+ xalome.deleteShape(activeStudy,previewShapeEntry)
+ previewShapeEntry = None
+
+ # Connection of callback functions to the dialog butoon click signals
+ dialogWithApply.handleAcceptWith(acceptCallback)
+ dialogWithApply.handleRejectWith(rejectCallback)
+ dialogWithApply.handleApplyWith(applyCallback)
+
+ def tube_shapewithguiAndPreview(context):
+ """
+ This plugin open a dialog in an asynchronous mode. Then it
+ required callback functions to be associated to the button
+ signals.
+ """
+ global dialogWithApply, activeStudy
+ activeStudy = context.study
+ dialogWithApply.open()
+
+
+ salome_pluginsmanager.AddFunction('DEMO/Tube geometry from parameters with preview',
+ 'Creates a tube object from specified parameters',
+ tube_shapewithguiAndPreview)
+
+
+
+# -------------------------------------------------------------------------
+# Example 3: run a shell session in a xterm to get a SALOME python console
+def runSalomeShellSession(context):
+ import os,subprocess
+ import salome_version
+ version = salome_version.getVersion(full=True)
+ kernel_appli_dir = os.environ['KERNEL_ROOT_DIR']
+ command = ""
+ if os.path.exists("/usr/bin/xterm"):
+ command = 'xterm -T "SALOME %s - Shell session" -e %s/runSession &'%(version,kernel_appli_dir)
+ elif os.path.exists("/usr/bin/gnome-terminal"):
+ command = 'gnome-terminal -t "SALOME %s - Shell session" -e %s/runSession &'%(version,kernel_appli_dir)
+ else:
+ print "Neither xterm nor gnome-terminal is installed."
+
+ if command is not "":
+ try:
+ subprocess.check_call(command, shell = True)
+ except Exception, e:
+ print "Error: ",e
+
+
+salome_pluginsmanager.AddFunction('SALOME shell session',
+ 'Execute a SALOME shell session in an external xterm',
+ runSalomeShellSession)
--- /dev/null
+# -*- coding: utf-8 -*-
+#!/usr/bin/env python
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import salome_pluginsmanager
+
+DEMO_IS_ACTIVATED = True
+
+from minmax_plugin import *
+
+# register the function in the plugin manager
+if DEMO_IS_ACTIVATED:
+ salome_pluginsmanager.AddFunction('Get min or max value of control',
+ 'Get min or max value of control',
+ minmax)
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+# Example 1: creation of basic objects (O, Vx, Vy, Vz)
+#
+
+# Intialize the geompy factory with the active study
+import geompy
+import salome
+geompy.init_geom(salome.myStudy)
+
+# Create the objects
+Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
+Vy = geompy.MakeVectorDXDYDZ(0, 10, 0)
+Vz = geompy.MakeVectorDXDYDZ(0, 0, 10)
+origin = geompy.MakeVertex(0, 0, 0)
+
+# Register the objects in the active study
+geompy.addToStudy( Vx, "Vx" )
+geompy.addToStudy( Vy, "Vy" )
+geompy.addToStudy( Vz, "Vz" )
+geompy.addToStudy( origin, "origin" )
+
+
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import salome
+
+DEFAULT_RADIUS = 100
+DEFAULT_LENGTH = 300
+DEFAULT_WIDTH = 20
+
+from salome.geom import geomtools
+
+def createGeometry(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+ '''
+ This function creates the geometry on the specified study and with
+ given parameters.
+ '''
+ print "TUBE: creating the geometry ..."
+ studyId = study._get_StudyId()
+ geompy = geomtools.getGeompy(studyId)
+
+ radius_ext = radius
+ radius_int = radius_ext - width
+
+ CylinderExt = geompy.MakeCylinderRH(radius_ext, length)
+ CylinderInt = geompy.MakeCylinderRH(radius_int, length)
+ Tube = geompy.MakeCut(CylinderExt, CylinderInt)
+ return Tube
+
+def createGeometryWithPartition(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+ '''
+ This function create the geometrical shape with a partition so
+ that the hexaedric algorithm could be used for meshing.
+ '''
+ shape = createGeometry(study,radius,length,width)
+
+ # We have to create a partition so that we can use an hexaedric
+ # meshing algorithm.
+ studyId = study._get_StudyId()
+ geompy = geomtools.getGeompy(studyId)
+
+ print "TUBE: creating a partition ..."
+ toolPlane = geompy.MakeFaceHW(2.1*length,2.1*radius,3)
+ partition = geompy.MakePartition([shape], [toolPlane], [], [], geompy.ShapeType["SOLID"], 0, [], 0)
+ entry = geompy.addToStudy( partition, "TubeWithPartition" )
+ return partition
+
+def createMesh(study, shape):
+ '''This function creates the mesh of the specified shape on the specified study'''
+ print "TUBE: creating the mesh ..."
+ import smesh
+
+ smesh.SetCurrentStudy(study)
+ mesh = smesh.Mesh(shape)
+ Regular_1D = mesh.Segment()
+ Nb_Segments = Regular_1D.NumberOfSegments(10)
+ Nb_Segments.SetDistrType( 0 )
+ Quadrangle_2D = mesh.Quadrangle()
+ Hexa_3D = mesh.Hexahedron()
+
+ isDone = mesh.Compute()
+
+ if salome.sg.hasDesktop():
+ smesh.SetName(mesh.GetMesh(), 'TubeMesh')
+ smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+ smesh.SetName(Nb_Segments, 'Nb. Segments_1')
+ smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
+ smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D')
+ salome.sg.updateObjBrowser(0)
+
+ return mesh
+
+
+def createModel(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH,width=DEFAULT_WIDTH):
+ '''
+ This function create the geomtrical shape AND the associated mesh.
+ '''
+ # We first create a shape with a partition so that the hexaedric
+ # algorithm could be used.
+ shape = createGeometryWithPartition(study,radius,length,width)
+
+ # Then the mesh can be defined and computed
+ mesh = createMesh(study,shape)
+
+def exportModel(mesh, filename):
+ '''
+ This exports the mesh to the specified filename in the med format
+ '''
+ print "TUBE: exporting mesh to file %s ..."%filename
+ import SMESH
+ mesh.ExportMED(filename, 0, SMESH.MED_V2_2, 1 )
+
+
+#
+# ===================================================================
+# Use cases and test functions
+# ===================================================================
+#
+def TEST_createGeometry():
+ salome.salome_init()
+ theStudy=salome.myStudy
+ createGeometry(theStudy)
+
+def TEST_createMesh():
+ salome.salome_init()
+ theStudy=salome.myStudy
+ shape = createGeometryWithPartition(theStudy)
+ mesh = createMesh(theStudy, shape)
+
+def TEST_createModel():
+ salome.salome_init()
+ theStudy=salome.myStudy
+ createModel(theStudy)
+
+def TEST_exportModel():
+ salome.salome_init()
+ theStudy=salome.myStudy
+ shape = createGeometryWithPartition(theStudy)
+ mesh = createMesh(theStudy, shape)
+ exportModel(mesh,"tubemesh.med")
+
+if __name__ == "__main__":
+ #TEST_createGeometry()
+ #TEST_createMesh()
+ TEST_createModel()
+ #TEST_exportModel()
--- /dev/null
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import sys
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+from tubedialog_ui import TubeDialog_UI
+
+
+class TubeDialog(TubeDialog_UI):
+ def setupUi(self):
+ TubeDialog_UI.setupUi(self)
+ self.handleAcceptWith(self.accept)
+ self.handleRejectWith(self.reject)
+
+ def handleAcceptWith(self,callbackFunction):
+ """This defines the function to be connected to the signal 'accepted()' (click on Ok)"""
+ QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), callbackFunction)
+
+ def handleRejectWith(self,callbackFunction):
+ """This defines the function to be connected to the signal 'rejected()' (click on Cancel)"""
+ QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), callbackFunction)
+
+ def handleApplyWith(self,callbackFunction):
+ """This defines the function to be connected to the signal 'apply()' (click on Apply)"""
+ button = self.buttonBox.button(QtGui.QDialogButtonBox.Apply)
+ QtCore.QObject.connect(button, QtCore.SIGNAL("clicked()"), callbackFunction);
+
+ def accept(self):
+ '''Callback function when dialog is accepted (click Ok)'''
+ self._wasOk = True
+ # We should test here the validity of values
+ QtGui.QDialog.accept(self)
+
+ def reject(self):
+ '''Callback function when dialog is rejected (click Cancel)'''
+ self._wasOk = False
+ QtGui.QDialog.reject(self)
+
+ def wasOk(self):
+ return self._wasOk
+
+ def setData(self, radius, length, width):
+ self.txtRadius.setText(str(radius))
+ self.txtLength.setText(str(length))
+ self.txtWidth.setText(str(width))
+
+ def getData(self):
+ try:
+ radius=eval(str(self.txtRadius.text()))
+ length=eval(str(self.txtLength.text()))
+ width=eval(str(self.txtWidth.text()))
+ except:
+ print "pb a la saisie"
+
+ return radius, length, width
+
+
+class TubeDialogOnTopWithApply(TubeDialog):
+ def setupUi(self):
+ """
+ This setupUi adds a button 'Apply' to execute a processing
+ tasks (ex: preview), and set a flag that keeps the dialog on
+ top of all windows.
+ """
+ TubeDialog.setupUi(self)
+ # Add a button "Apply"
+ self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|
+ QtGui.QDialogButtonBox.Apply|
+ QtGui.QDialogButtonBox.Ok)
+
+ # Keep the dialog on top of the windows
+ self.setWindowFlags(self.windowFlags() |
+ QtCore.Qt.WindowStaysOnTopHint)
+
+
+#
+# ======================================================================
+# Unit test
+# ======================================================================
+#
+def TEST_getData_synchrone():
+ """This use case illustrates the MVC pattern on this simple dialog example"""
+ tubedialog = TubeDialog()
+ tubedialog.setData(10,50,3)
+ tubedialog.exec_()
+ if tubedialog.wasOk():
+ radius, length, width = tubedialog.getData()
+ print radius, length, width
+
+
+def main( args ):
+ a = QtGui.QApplication(sys.argv)
+ TEST_getData_synchrone()
+ sys.exit(0)
+
+if __name__=="__main__":
+ main(sys.argv)
+
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+import sys
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+
+class TubeDialog_UI(QtGui.QDialog):
+ """
+ This class defines the design of a Qt dialog box dedicated to the
+ salome plugin examples. It presents a UI form that contains
+ parameters for the spatial dimensions of geometrical object.
+ """
+ def __init__(self, parent=None):
+ QtGui.QDialog.__init__(self, parent)
+ self.setupUi()
+
+ def setupUi(self):
+ self.setObjectName("Dialog")
+ self.resize(400, 300)
+ self.hboxlayout = QtGui.QHBoxLayout(self)
+ self.hboxlayout.setMargin(9)
+ self.hboxlayout.setSpacing(6)
+ self.hboxlayout.setObjectName("hboxlayout")
+ self.vboxlayout = QtGui.QVBoxLayout()
+ self.vboxlayout.setMargin(0)
+ self.vboxlayout.setSpacing(6)
+ self.vboxlayout.setObjectName("vboxlayout")
+ self.hboxlayout1 = QtGui.QHBoxLayout()
+ self.hboxlayout1.setMargin(0)
+ self.hboxlayout1.setSpacing(6)
+ self.hboxlayout1.setObjectName("hboxlayout1")
+ self.vboxlayout1 = QtGui.QVBoxLayout()
+ self.vboxlayout1.setMargin(0)
+ self.vboxlayout1.setSpacing(6)
+ self.vboxlayout1.setObjectName("vboxlayout1")
+ self.lblRadius = QtGui.QLabel(self)
+ self.lblRadius.setObjectName("lblRadius")
+ self.vboxlayout1.addWidget(self.lblRadius)
+ self.lblLength = QtGui.QLabel(self)
+ self.lblLength.setObjectName("lblLength")
+ self.vboxlayout1.addWidget(self.lblLength)
+ self.lblWidth = QtGui.QLabel(self)
+ self.lblWidth.setObjectName("lblWidth")
+ self.vboxlayout1.addWidget(self.lblWidth)
+ self.hboxlayout1.addLayout(self.vboxlayout1)
+ self.vboxlayout2 = QtGui.QVBoxLayout()
+ self.vboxlayout2.setMargin(0)
+ self.vboxlayout2.setSpacing(6)
+ self.vboxlayout2.setObjectName("vboxlayout2")
+ self.txtRadius = QtGui.QLineEdit(self)
+ self.txtRadius.setObjectName("txtRadius")
+ self.vboxlayout2.addWidget(self.txtRadius)
+ self.txtLength = QtGui.QLineEdit(self)
+ self.txtLength.setObjectName("txtLength")
+ self.vboxlayout2.addWidget(self.txtLength)
+ self.txtWidth = QtGui.QLineEdit(self)
+ self.txtWidth.setObjectName("txtWidth")
+ self.vboxlayout2.addWidget(self.txtWidth)
+ self.hboxlayout1.addLayout(self.vboxlayout2)
+ self.vboxlayout.addLayout(self.hboxlayout1)
+ spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+ self.vboxlayout.addItem(spacerItem)
+ self.buttonBox = QtGui.QDialogButtonBox(self)
+ self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
+ self.buttonBox.setObjectName("buttonBox")
+ self.vboxlayout.addWidget(self.buttonBox)
+ self.hboxlayout.addLayout(self.vboxlayout)
+
+ self.setWindowTitle("Tube construction")
+ self.lblRadius.setText("Rayon")
+ self.lblLength.setText("Longueur")
+ self.lblWidth.setText("Epaisseur")
+
+#
+# ======================================================================
+# Unit test
+# ======================================================================
+#
+def main( args ):
+ a = QtGui.QApplication(sys.argv)
+ tubedialog = TubeDialog_UI()
+ sys.exit(tubedialog.exec_())
+
+if __name__=="__main__":
+ main(sys.argv)
+
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+
+#
+# XALOME means "eXtension for sALOME. This module contains specific
+# helper functions that extends salome for the needs of the salome
+# plugin examples, or hide some complex technical parts of SALOME to
+# ease the global understanding of the examples.
+#
+# (gboulant - 09/02/2012)
+#
+import salome
+from salome.kernel.studyedit import getStudyEditor
+from salome.kernel.services import IDToSObject, IDToObject
+from salome.geom import geomtools
+
+# ======================================================================
+# Helper functions to add/remove a geometrical shape in/from the study
+# ======================================================================
+
+def addToStudy(study,shape,shapeName,folderName=None):
+ """
+ Add a GEOM shape in the study. It returns the associated entry
+ that corresponds to the identifier of the entry in the study. This
+ entry can be used to retrieve an object in the study. A folderName
+ can be specified. In this case, a folder with this name is first
+ created in the Geometry part of the study, and the shape study
+ object is stored in this folder of the study.
+ """
+ studyId = study._get_StudyId()
+ geompy = geomtools.getGeompy(studyId)
+
+ if folderName is None:
+ # Insert the shape in the study by the standard way
+ entry = geompy.addToStudy( shape, shapeName )
+ else:
+ # A folder name has been specified to embed this shape. Find
+ # or create a folder with this name in the Geometry study, and
+ # then store the shape in this folder.
+ studyEditor = getStudyEditor(studyId)
+ geomStudyFolder = studyEditor.findOrCreateComponent("GEOM")
+ shapeStudyFolder = studyEditor.findOrCreateItem(geomStudyFolder,folderName)
+
+ shapeIor = salome.orb.object_to_string(shape)
+ geomgui = salome.ImportComponentGUI("GEOM")
+ shapeIcon = geomgui.getShapeTypeIcon(shapeIor)
+
+ shapeStudyObject = studyEditor.createItem(shapeStudyFolder,
+ name=shapeName,
+ IOR=shapeIor,
+ icon=shapeIcon)
+ entry = shapeStudyObject.GetID()
+
+ return entry
+
+def removeFromStudy(study,shapeStudyEntry):
+ """
+ This removes the specified entry from the study. Note that this
+ operation does not destroy the underlying GEOM object, neither
+ erase the drawing in the viewer.
+ The underlying GEOM object is returned (so that it can be destroyed)
+ """
+ studyId = study._get_StudyId()
+ shape = IDToObject(shapeStudyEntry)
+ studyObject = IDToSObject(shapeStudyEntry)
+ studyEditor = getStudyEditor(studyId)
+ studyEditor.removeItem(studyObject,True)
+ return shape
+
+
+# ======================================================================
+# Helper functions to display/erase a shape in/from the viewer. The
+# shape must be previously put in the study and the study entry must
+# be known.
+# ======================================================================
+
+ModeShading = 1
+DisplayMode=ModeShading
+PreviewColor=[236,163,255]
+def displayShape(shapeStudyEntry, color=None):
+ """This displays the shape specified by its entry in the study"""
+ geomgui = salome.ImportComponentGUI("GEOM")
+ geomgui.createAndDisplayFitAllGO(shapeStudyEntry)
+ geomgui.setDisplayMode(shapeStudyEntry, DisplayMode)
+ if color is not None:
+ geomgui.setColor(shapeStudyEntry, color[0], color[1], color[2])
+
+def eraseShape(shapeStudyEntry):
+ """
+ This erases from the viewers the shape specified by its study
+ entry.
+ """
+ geomgui = salome.ImportComponentGUI("GEOM")
+ eraseFromAllWindows=True
+ geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows)
+
+# Available in SALOME 6.5 only
+def displayShape_version65(shapeStudyEntry):
+ gst = geomtools.GeomStudyTools()
+ gst.displayShapeByEntry(shapeStudyEntry)
+
+def eraseShape_version65(shapeStudyEntry):
+ gst = geomtools.GeomStudyTools()
+ gst.eraseShapeByEntry(shapeStudyEntry)
+
+
+# ======================================================================
+# Helper functions for a complete suppression of a shape from the
+# SALOME session.
+# ======================================================================
+def deleteShape(study,shapeStudyEntry):
+ """
+ This completly deletes a geom shape.
+
+ WARNING: please be aware that to delete a geom object, you have
+ three operations to perform:
+
+ 1. erase the shape from the viewers
+ 2. remove the entry from the study
+ 3. destroy the underlying geom object
+ """
+ eraseShape(shapeStudyEntry)
+ shape = removeFromStudy(study, shapeStudyEntry)
+ if shape is not None:
+ shape.Destroy()
+
+
+#
+# ======================================================================
+# Unit tests
+# ======================================================================
+#
+# To experiment this unit test, just execute this script in
+# SALOME. The script is self-consistent.
+
+def TEST_createAndDeleteShape():
+ """
+ This test is a simple use case that illustrates how to create a
+ GEOM shape in a SALOME session (create the GEOM object, put in in
+ the study, and display the shape in a viewer) and delete a shape
+ from a SALOME session (erase the shape from the viewer, delete the
+ entry from the study, and finally destroy the underlying GEOM
+ object).
+ """
+ import salome
+ salome.salome_init()
+ study = salome.myStudy
+ studyId = salome.myStudyId
+
+ from salome.geom import geomtools
+ geompy = geomtools.getGeompy(studyId)
+
+ # --------------------------------------------------
+ # Create a first shape (GEOM object)
+ radius = 5
+ length = 100
+ cylinder = geompy.MakeCylinderRH(radius, length)
+
+ # Register the shape in the study, at the root of the GEOM
+ # folder. A name must be specified. The register operation
+ # (addToStudy) returns an identifier of the entry in the study.
+ cylinderName = "cyl.r%s.l%s"%(radius,length)
+ cylinderStudyEntry = addToStudy(study, cylinder, cylinderName)
+
+ # Display the registered shape in a viewer
+ displayShape(cylinderStudyEntry)
+
+ # --------------------------------------------------
+ # A second shape
+ radius = 10
+ sphere = geompy.MakeSphereR(radius)
+ sphereName = "sph.r%s"%radius
+ sphereStudyEntry = addToStudy(study, sphere, sphereName)
+ displayShape(sphereStudyEntry)
+
+ # --------------------------------------------------
+ # This new shape is stored in the study, but in a specific
+ # sub-folder, and is displayed in the viewer with a specific
+ # color.
+ length = 20
+ box = geompy.MakeBoxDXDYDZ(length,length,length)
+ boxName = "box.l%s"%length
+ folderName = "boxset"
+ boxStudyEntry = addToStudy(study, box, boxName, folderName)
+ displayShape(boxStudyEntry,PreviewColor)
+
+ # --------------------------------------------------
+ # In this example, we illustrate how to erase a shape (the sphere)
+ # from the viewer. After this operation, the sphere is no longer
+ # displayed but still exists in the study. You can then redisplay
+ # it using the context menu of the SALOME object browser.
+ eraseShape(sphereStudyEntry)
+
+ # --------------------------------------------------
+ # In this last example, we completly delete an object from the
+ # SALOME session (erase from viewer, remove from study and finnaly
+ # destroy the object). This is done by a simple call to
+ # deleteShape().
+ deleteShape(study,cylinderStudyEntry)
+
+ # --------------------------------------------------
+ # At the end of the executioon of this test, you should have in
+ # the SALOME session:
+ # - the box, in a dedicated folder of the study, and displayed in the viewer
+ # - the sphere, in the standard place of the study, and not displayed
+
+ # If you comment the deleteShape line, you should see the cylinder
+ # in the study and displayed in the viewer.
+
+if __name__=="__main__":
+ TEST_createAndDeleteShape()
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DataModel.hxx"
+
+DataModel::DataModel() {
+
+}
+
+DataModel::~DataModel() {
+ _mapDataObjects.clear();
+}
+
+bool DataModel::addDataObject(DataObject * dataObject) {
+ _mapDataObjects[dataObject->getNameId()] = dataObject;
+ return true;
+}
+bool DataModel::removeDataObject(string nameId) {
+ _mapDataObjects.erase(nameId);
+ return true;
+}
+bool DataModel::removeDataObject(DataObject * dataObject) {
+ if ( dataObject == NULL ) return false;
+ return removeDataObject(dataObject->getNameId());
+}
+
+DataObject * DataModel::getDataObject(string id) {
+ return _mapDataObjects[id];
+}
+
+
+
+map<string, DataObject *>::iterator DataModel::begin() {
+ return _mapDataObjects.begin();
+}
+
+map<string, DataObject *>::iterator DataModel::end() {
+ return _mapDataObjects.end();
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef DATAMODEL_H
+#define DATAMODEL_H
+
+#include "TreeData.hxx"
+
+#include <map>
+#include "DataObject.hxx"
+
+class TREEDATA_EXPORT DataModel {
+
+public:
+ DataModel();
+ ~DataModel();
+
+ /*!
+ * This function can be used to create a specific instance of
+ * DataObject. Note that this function is a pure virtual method and
+ * then no default behavior is done. In particular, the newly
+ * created object is not automatically added to the data model. This
+ * behavior should be implemented in a dedicated version of this
+ * class.
+ */
+ virtual DataObject * newDataObject() = 0;
+
+ /*! Function to add data object to the model */
+ bool addDataObject(DataObject * dataObject);
+ /*! Functions to remove data object from the model */
+ bool removeDataObject(string nameId);
+ bool removeDataObject(DataObject * dataObject);
+ /*! Function to retrieve a data object in the model */
+ DataObject * getDataObject(string nameId);
+
+ map<string, DataObject *>::iterator begin();
+ map<string, DataObject *>::iterator end();
+
+private:
+ map<string, DataObject *> _mapDataObjects;
+
+
+};
+
+#endif // DATAMODEL_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DataObject.hxx"
+#include <Basics_Utils.hxx>
+
+// Static assignement
+int DataObject::_lastId=0;
+const string DataObject::_BASENAME = string("object_");
+const string DataObject::pathsep = string("/");
+
+DataObject::DataObject() {
+ _nameId = _BASENAME+ToString(_lastId);
+ _lastId++;
+ // The default label is set to the nameId, but it can be modified
+ // using setLabel whereas the nameId can't be modified.
+ _label = _nameId;
+}
+
+DataObject::~DataObject() {
+ _properties.clear();
+}
+
+void DataObject::setLabel(string label) {
+ _label = label;
+}
+string DataObject::getLabel() {
+ return _label;
+}
+
+string DataObject::getPathName() {
+ string pathName;
+ pathName = this->getPath() + pathsep + this->getLabel();
+ return pathName;
+}
+
+
+string DataObject::getNameId() {
+ return _nameId;
+}
+
+void DataObject::setProperty(string key, string value) {
+ _properties[key] = value;
+}
+string DataObject::getProperty(string key) {
+ return _properties[key];
+}
+
+string DataObject::toString() {
+ string serialize="\n";
+ serialize+="nameId = "+getNameId()+"\n";
+ serialize+="label = "+getLabel()+"\n";
+ serialize+="path = "+getPath();
+ return serialize;
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef DATAOBJECT_H
+#define DATAOBJECT_H
+
+#include "TreeData.hxx"
+
+#include <map>
+#include <string>
+using namespace std;
+
+class TREEDATA_EXPORT DataObject {
+
+public:
+ DataObject();
+ ~DataObject();
+
+ void setLabel(string label);
+ string getLabel();
+ void setProperty(string key, string value);
+ string getProperty(string key);
+
+ /*!
+ * This function specifies the localization of the object in the
+ * hierarchical organization that can be defined by the DataModel it
+ * belongs to.
+ */
+ virtual string getPath() = 0;
+ string getPathName();
+ string getNameId();
+
+ static const string pathsep;
+
+ /*! This function can be used for debug */
+ string toString();
+
+private:
+ /*! The name this object can be displayed with */
+ string _label;
+ /*! The identifier of this object. An identifier is invariant all the session long */
+ string _nameId;
+ /*! The dictionnary of properties that characterize this object */
+ map<string, string> _properties;
+
+ static int _lastId;
+ static const string _BASENAME;
+};
+
+#endif // DATAOBJECT_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include "DataProcessor.hxx"
+#include <Basics_Utils.hxx>
+#include "QtHelper.hxx"
+
+DataProcessor::DataProcessor(DataModel * dataModel) {
+ _dataModel = dataModel;
+}
+
+/*!
+ * This function retrieves in the data model all the DataObject
+ * associated to the item nameIds contained in the specified list. The
+ * input list is what the TreeView sends via the notification signal.
+ */
+DataObjectVector * DataProcessor::extract(QStringList itemNameIdList) {
+ if ( _dataModel == NULL ) {
+ STDLOG("No data model associated to this processor");
+ return NULL;
+ }
+
+ DataObjectVector * dataObjectList = new DataObjectVector();
+
+ // We can request the dataModel to obtain the dataObject associated
+ // to each of the item (iteNameId is a TreeView id, Qt stuff only).
+ QStringList::const_iterator it;
+ for (it = itemNameIdList.constBegin(); it != itemNameIdList.constEnd(); ++it) {
+ QString itemNameId = *it;
+ DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+
+ if ( dataObject != NULL ) {
+ dataObjectList->push_back(dataObject);
+ } else {
+ LOG("No data object associated to the item "<<itemNameId);
+ }
+ }
+ return dataObjectList;
+}
+
+
+void DataProcessor::process(QStringList itemNameIdList) {
+ if ( _dataModel == NULL ) {
+ STDLOG("No data model");
+ return;
+ }
+
+ this->preprocess(itemNameIdList);
+
+ // We can request the dataModel to obtain the dataObject associated
+ // to each of the item (iteNameId is a TreeView id, Qt stuff only).
+ QStringList::const_iterator it;
+ for (it = itemNameIdList.constBegin(); it != itemNameIdList.constEnd(); ++it) {
+ QString itemNameId = *it;
+ DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+
+ if ( dataObject != NULL ) {
+ this->processDataObject(dataObject);
+ } else {
+ STDLOG("No data object associated to the item "<<QS2S(itemNameId));
+ }
+ }
+
+ this->postprocess(itemNameIdList);
+}
+
+
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _DATAPROCESSOR_H_
+#define _DATAPROCESSOR_H_
+
+#include "TreeData.hxx"
+
+#include "DataModel.hxx"
+#include "DataObject.hxx"
+#include <QStringList>
+#include <QString>
+
+#include <vector>
+typedef std::vector<DataObject *> DataObjectVector;
+
+//
+// =================================================================
+// This class can be used to automize processing on data objects.
+// The inputs of public functions are list of selected items in the
+// tree view. The function automize the extraction of associated
+// DataObject and can automize the processing of these object if the
+// virtual function processDataObject is implemented.
+// =================================================================
+//
+
+class TREEDATA_EXPORT DataProcessor {
+
+public:
+ DataProcessor(DataModel * dataModel);
+
+ DataObjectVector * extract(QStringList itemNameIdList);
+ void process(QStringList itemNameIdList);
+
+
+protected:
+ virtual void preprocess(QStringList itemNameIdList) {
+ // Implement something to be executed at the begining of the process function
+ };
+ virtual void postprocess(QStringList itemNameIdList) {
+ // Implement something to be executed at the end of the process function
+ };
+ // Implement what must be done with each DataObject during the process function
+ virtual void processDataObject(DataObject * dataObject) = 0;
+
+private:
+ DataModel * _dataModel;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DockWidgets.hxx"
+
+// Qt includes
+#include <QMainWindow>
+
+// SALOME includes
+#include <SUIT_Desktop.h>
+#include <SUIT_DataBrowser.h>
+#include <QtxTreeView.h>
+
+/*!
+ * This create a gui container to hold widgets dedicated to the XCAD
+ * data model. By default, the dock widgets are not visible. Use the
+ * show() method to control the visibility (usefull when activating
+ * and desactivating the module to show/hide the dock widgets).
+ *
+ * This class does not make any hypothesis on what will be embedded in
+ * the dock widgets (only that it is QTreeView). The QTreeView is
+ * defined elsewhere and is generaly rendering a tree model containing
+ * tree items.
+ */
+DockWidgets::DockWidgets(SalomeApp_Application* salomeApp,
+ bool tabify,
+ const char * title) {
+ _salomeApp = salomeApp;
+
+ QMainWindow *parent = _salomeApp->desktop();
+ _dwDataPanel = new QDockWidget(parent);
+ _dwDataPanel->setVisible(false);
+ _dwDataPanel->setWindowTitle(title);
+ parent->addDockWidget(Qt::LeftDockWidgetArea, _dwDataPanel);
+ //
+ // At this step, the _dwDataPanel is located side by side with the object
+ // browser (or one over the other).
+ //
+ // It is possible to tabify the different dock widgets in one single
+ // tabbed widget. See the above example:
+ this->tabify(tabify);
+}
+
+void DockWidgets::tabify(bool tabify) {
+ if ( tabify ) {
+ // We first get the object browser tree view, and then the
+ // associated DockWidget. Note that the tree view is a SALOME
+ // specific extention of the originate QTreeView and called
+ // QtxTreeView.
+ SUIT_DataBrowser* objectBrowser = _salomeApp->objectBrowser();
+ QtxTreeView* treeView = objectBrowser->treeView();
+ QWidget* pw = treeView->parentWidget();
+ QDockWidget* dwObjectBrowser = 0;
+ while ( pw && !dwObjectBrowser ) {
+ dwObjectBrowser = ::qobject_cast<QDockWidget*>( pw );
+ pw = pw->parentWidget();
+ };
+ QMainWindow *parent = _salomeApp->desktop();
+ parent->tabifyDockWidget(_dwDataPanel, dwObjectBrowser);
+ parent->setTabOrder(_dwDataPanel, dwObjectBrowser);
+ parent->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
+ }
+ else {
+ // TO BE IMPLEMENTED
+ }
+}
+
+/*!
+ * This function controls the visibility of the dock widgets.
+ */
+void DockWidgets::show(bool isVisible) {
+ _dwDataPanel->setVisible(isVisible);
+}
+
+/*!
+ * This function initializes the central part of the dock widget with
+ * a tree view that can hold a hierarchical data model.
+ */
+void DockWidgets::setDataView(QTreeView * dataView) {
+ _tvDataView = dataView;
+ _tvDataView->setParent(_dwDataPanel);
+ _tvDataView->setMinimumHeight(200);
+ _dwDataPanel->setWidget(_tvDataView);
+}
+
+void DockWidgets::setPropertiesView(QTreeView * propertiesView) {
+ // Not implemented yet
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _DOCKWIDGETS_H_
+#define _DOCKWIDGETS_H_
+
+#include "TreeData.hxx"
+
+// Qt includes
+#include <QDockWidget>
+#include <QTreeView>
+
+// SALOME includes
+#include <SalomeApp_Application.h>
+
+class TREEDATA_EXPORT DockWidgets {
+ public:
+ DockWidgets(SalomeApp_Application* salomeApp,
+ bool tabify=false,
+ const char * title="Data Model");
+
+ void tabify(bool tabify);
+ void show(bool isVisible);
+ void setDataView(QTreeView * dataView);
+ void setPropertiesView(QTreeView * propertyView);
+
+ private:
+ SalomeApp_Application* _salomeApp;
+ QDockWidget * _dwDataPanel;
+ QTreeView * _tvDataView;
+};
+
+#endif // _DOCKWIDGETS_H_
--- /dev/null
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+SUBDIRS = . Test
+
+# moc-files generation
+%_moc.cxx: %.hxx
+ $(MOC) $< -o $@
+
+mostlyclean-local:
+ rm -f @builddir@/*_moc.cxx
+ rm -f @builddir@/*.qm
+
+# Libraries targets
+lib_LTLIBRARIES = libSalomeTreeData.la
+
+#
+# Generic source files
+#
+salomeinclude_HEADERS = \
+ TreeData.hxx \
+ DockWidgets.hxx \
+ TreeModel.hxx \
+ TreeItem.hxx \
+ TreeView.hxx \
+ TreeObserver.hxx \
+ DataModel.hxx \
+ DataObject.hxx \
+ DataProcessor.hxx \
+ TreeGuiManager.hxx
+
+dist_libSalomeTreeData_la_SOURCES = \
+ DockWidgets.cxx \
+ TreeModel.cxx \
+ TreeItem.cxx \
+ TreeView.cxx \
+ TreeObserver.cxx \
+ DataModel.cxx \
+ DataObject.cxx \
+ DataProcessor.cxx \
+ TreeGuiManager.cxx
+
+# MOC pre-processing
+MOC_FILES_HXX = \
+ TreeModel_moc.cxx \
+ TreeView_moc.cxx \
+ TreeObserver_moc.cxx
+
+nodist_libSalomeTreeData_la_SOURCES = $(MOC_FILES_HXX)
+
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+CAS_CXXFLAGS=@CAS_CPPFLAGS@ @CAS_CXXFLAGS@
+
+BOOST_CPPFLAGS=@BOOST_CPPFLAGS@
+BOOST_LIBS=@BOOST_LIBS@
+
+libSalomeTreeData_la_CPPFLAGS = \
+ $(QT_CXXFLAGS) \
+ $(CAS_CXXFLAGS) \
+ $(BOOST_CPPFLAGS) \
+ $(CORBA_CXXFLAGS) \
+ $(KERNEL_CXXFLAGS) \
+ -I$(srcdir)/../SalomeApp \
+ -I$(srcdir)/../LightApp \
+ -I$(srcdir)/../CAM \
+ -I$(srcdir)/../STD \
+ -I$(srcdir)/../ObjBrowser \
+ -I$(srcdir)/../SUIT \
+ -I$(srcdir)/../Qtx \
+ -I$(srcdir)/../GuiHelpers
+
+
+
+
+libSalomeTreeData_la_LDFLAGS = \
+ $(CORBA_LIBS) $(QT_LIBS)\
+ $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeKernelHelpers \
+ $(top_builddir)/src/SalomeApp/libSalomeApp.la \
+ $(top_builddir)/src/LightApp/libLightApp.la \
+ $(top_builddir)/src/SUIT/libsuit.la \
+ $(top_builddir)/src/Qtx/libqtx.la \
+ $(top_builddir)/src/CAM/libCAM.la \
+ $(top_builddir)/src/STD/libstd.la \
+ $(top_builddir)/src/ObjBrowser/libObjBrowser.la
--- /dev/null
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF)
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# moc-files generation
+%_moc.cxx: %.hxx
+ $(MOC) $< -o $@
+
+mostlyclean-local:
+ rm -f @builddir@/*_moc.cxx
+ rm -f @builddir@/*.qm
+ rm -f @builddir@/*_moc.cxx @builddir@/ui_*.h
+
+# qt forms files generation (uic)
+ui_%.h: %.ui
+ $(UIC) -o $@ $<
+
+
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+
+TEST_CPPFLAGS = \
+ $(QT_CXXFLAGS) \
+ $(CORBA_CXXFLAGS) \
+ $(KERNEL_CXXFLAGS) \
+ -I$(top_srcdir)/src/GuiHelpers \
+ -I$(top_srcdir)/src/TreeData \
+ -I.
+
+TEST_LDFLAGS = \
+ $(CORBA_LIBS) $(QT_LIBS) \
+ $(top_builddir)/src/TreeData/libSalomeTreeData.la \
+ $(top_builddir)/src/GuiHelpers/libSalomeGuiHelpers.la \
+ $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeKernelHelpers
+
+# Program targets
+bin_PROGRAMS = TreeData_guitester TreeData_tester
+
+MOC_FILES_HXX = \
+ mainwindow_moc.cxx
+
+UIC_FILES = \
+ ui_mainwindow.h
+
+BUILT_SOURCES = $(UIC_FILES)
+
+nodist_TreeData_guitester_SOURCES = $(MOC_FILES_HXX) $(UIC_FILES)
+
+TreeData_guitester_SOURCES = \
+ testhelper.hxx \
+ testhelper.cxx \
+ guitester.cxx \
+ mainwindow.hxx \
+ mainwindow.cxx \
+ MyDataModel.hxx \
+ MyDataModel.cxx
+
+TreeData_guitester_CPPFLAGS = \
+ $(TEST_CPPFLAGS)
+
+TreeData_guitester_LDFLAGS = \
+ $(TEST_LDFLAGS)
+
+TreeData_tester_SOURCES = \
+ tester.cxx \
+ MyDataModel.cxx
+
+TreeData_tester_CPPFLAGS = \
+ $(TEST_CPPFLAGS)
+
+TreeData_tester_LDFLAGS = \
+ $(TEST_LDFLAGS)
+
+# test data files
+testdir = $(salomeresdir)/testdata
+test_DATA = \
+ data.txt
+
+EXTRA_DIST+=$(test_DATA)
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MyDataModel.hxx"
+
+//
+// =================================================================
+// MyDataObject implementation
+// =================================================================
+//
+
+const string MyDataObject::PROPERTY_KEY_TYPE = "type";
+const string MyDataObject::PROPERTY_KEY_CIRCUIT ="circuit";
+const string MyDataObject::PROPERTY_KEY_REPFONC ="rf";
+
+MyDataObject::MyDataObject() : DataObject() {
+ this->setProperty(PROPERTY_KEY_TYPE, "Tuyauterie");
+ this->setProperty(PROPERTY_KEY_CIRCUIT,"RRA");
+ this->setProperty(PROPERTY_KEY_REPFONC,"RF_01");
+}
+
+/*! This function specified the localization of the object in the
+ * hierarchical organization
+ */
+string MyDataObject::getPath() {
+ // We choose here a convention for organizing the path for this
+ // class of object.
+ /*
+ string path = getProperty(PROPERTY_KEY_CIRCUIT) + pathsep
+ + getProperty(PROPERTY_KEY_REPFONC) + pathsep
+ + getProperty(PROPERTY_KEY_TYPE);
+ */
+ string path = getProperty(PROPERTY_KEY_TYPE) + pathsep
+ + getProperty(PROPERTY_KEY_CIRCUIT) + pathsep
+ + getProperty(PROPERTY_KEY_REPFONC);
+
+ return path;
+}
+
+//
+// =================================================================
+// MyDataModel implementation
+// =================================================================
+//
+MyDataModel::MyDataModel() : DataModel() {
+}
+
+DataObject * MyDataModel::newDataObject() {
+ MyDataObject * dataObject = new MyDataObject();
+ return dataObject;
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _MYDATAMODEL_H_
+#define _MYDATAMODEL_H_
+
+//
+// =================================================================
+// Definition of an atom in the data model as an implementation of
+// the virtual class DataObject
+// =================================================================
+//
+
+#include "DataObject.hxx"
+class MyDataObject: public DataObject {
+public:
+ MyDataObject();
+ virtual string getPath();
+ static const string PROPERTY_KEY_TYPE;
+ static const string PROPERTY_KEY_CIRCUIT;
+ static const string PROPERTY_KEY_REPFONC;
+};
+
+
+//
+// =================================================================
+// Definition of the data model as an implementation of the virtual
+// class DataModel. It implements the DataObject factory.
+// =================================================================
+//
+#include "DataModel.hxx"
+class MyDataModel: public DataModel {
+public:
+ MyDataModel();
+ virtual DataObject * newDataObject();
+};
+
+#endif // _MYDATAMODEL_H_
--- /dev/null
+Tuyauterie;RF1;T1\r
+Tuyauterie;RF1;T2\r
+Tuyauterie;RF1;T3\r
+Tuyauterie;RF2;T1\r
+Tuyauterie;RF3;T1\r
+Tuyauterie;RF3;T2\r
+Composansts;RF1;T1\r
+Composansts;RF1;T2\r
+Composansts;RF3;T2\r
+Genie Civil;RF1;T1\r
+Genie Civil;RF1;T2\r
+Genie Civil;RF1;T3\r
+Genie Civil;RF2;T1\r
+Genie Civil;RF3;T1\r
+Genie Civil;RF3;T2\r
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <QApplication>
+#include <QMainWindow>
+#include <QDockWidget>
+#include <QTreeView>
+
+#include <Basics_Utils.hxx>
+
+//
+// =================================================================
+// Generic helper functions
+// =================================================================
+//
+/*!
+ * This functions displays a main window that embeds the specified
+ * widget. A dockwidget is used to create a context similar to as the
+ * SALOME target context.
+ */
+void showWidget(QWidget * widget) {
+
+ QMainWindow * window = new QMainWindow();
+
+ // Prepare a gui framework for testing the widget. We use a
+ // dockwidget, just to be in a context similar to as the SALOME
+ // target context.
+ QDockWidget * dwDataPanel = new QDockWidget(window);
+ dwDataPanel->setVisible(true);
+ dwDataPanel->setWindowTitle("XCAD data model");
+ window->addDockWidget(Qt::LeftDockWidgetArea, dwDataPanel);
+
+ // Then plug the widget in the dock widget framework:
+ widget->setParent(dwDataPanel);
+ widget->setMinimumHeight(300);
+ dwDataPanel->setWidget(widget);
+
+ window->show();
+}
+
+//
+// =================================================================
+// Tests functions for TreeModel
+// =================================================================
+//
+#include "TreeModel.hxx"
+#include "MyDataModel.hxx"
+#include "testhelper.hxx"
+
+
+/*!
+ * This function fills the specified tree with data that show
+ * different levels of path in the tree.
+ */
+void _TEST_treemodel_addData_01(TreeModel * dataTreeModel) {
+ // We can first add categories (for example to set categories
+ // properties)
+ QStringList path;
+ DataObject * folder;
+
+ path << "folder_1";
+ folder = TESTHELPER_dummyObject("folder_1.1");
+ dataTreeModel->addData(folder, path);
+ folder = TESTHELPER_dummyObject("folder_1.2");
+ dataTreeModel->addData(folder, path);
+
+ path.clear();
+ path << "folder_2";
+ folder = TESTHELPER_dummyObject("folder_2.1");
+ dataTreeModel->addData(folder, path);
+
+ // Then we can add data
+ DataObject * data;
+ path.clear();
+ path << "folder_1" << "folder_1.1";
+ data = TESTHELPER_dummyObject("data_1.1.1");
+ dataTreeModel->addData(data, path);
+ data = TESTHELPER_dummyObject("data_1.1.2");
+ dataTreeModel->addData(data, path);
+ // You can notice that there is no conceptual difference between a
+ // folder and an item, as in the QTreeModel.
+
+ // No limit to the depth
+ path.clear();
+ path << "xcad" << "data1" << "x" << "y";
+ data = TESTHELPER_dummyObject("z");
+ dataTreeModel->addData(data,path);
+}
+
+#define LOOPSIZE 15
+/*!
+ * This function fills the specified tree with a huge amount of data
+ */
+void _TEST_treemodel_addData_02(TreeModel * dataTreeModel) {
+ QStringList path;
+ DataObject * data;
+
+ START_TIMING(treemodel);
+ for (int i=0; i<LOOPSIZE; i++) {
+ END_TIMING(treemodel,1);
+ for (int j=0; j<LOOPSIZE; j++) {
+ for (int k=0; k<LOOPSIZE; k++) {
+ // The data list corresponds to the path of the item in the tree
+ path << QString("folder_%0").arg(i)
+ << QString("subfolder_%0_%1").arg(i).arg(j);
+ data = TESTHELPER_dummyObject(QString("item_%0_%1_%2").arg(i).arg(j).arg(k));
+ dataTreeModel->addData(data,path);
+ path.clear();
+ }
+ }
+ }
+ END_TIMING(treemodel,1);
+}
+
+void _TEST_treemodel_addData_03(TreeModel * dataTreeModel) {
+ MyDataObject * dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF2");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RRA");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Génie civil");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RRA");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+}
+
+/*!
+ * This test function shows how it's possible to load data from a file
+ * to populate the tree model.
+ */
+void _TEST_treemodel_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename) {
+ TESTHELPER_loadDataFromFile(dataTreeModel, filename);
+}
+
+/*!
+ * Main test function for the tree model demo.
+ */
+#include "TreeModel.hxx"
+#include "TreeView.hxx"
+void TEST_treemodel() {
+
+ START_TIMING(treemodel);
+
+ // We first prepare a data view embedding a tree model
+ TreeView * dataView = new TreeView();
+ QStringList headers;
+ headers << QObject::tr("Name") << QObject::tr("Value");
+ TreeModel * dataTreeModel = new TreeModel(headers);
+ dataView->setModel(dataTreeModel);
+ END_TIMING(treemodel,1);
+
+ // Then we can fill the tree model with data. Can proceed with
+ // different ways (comment/uncomment which you want to test):
+ _TEST_treemodel_loadDataFromFile(dataTreeModel, TESTHELPER_testfilename(DATAFILENAME));
+ //_TEST_treemodel_addData_01(dataTreeModel);
+ //_TEST_treemodel_addData_02(dataTreeModel);
+ //_TEST_treemodel_addData_03(dataTreeModel);
+ // Finally, show the widget in a main window
+ END_TIMING(treemodel,1);
+
+ showWidget(dataView);
+ END_TIMING(treemodel,1);
+}
+
+//
+// =================================================================
+// Tests functions for TreeModel with interactive changes
+// =================================================================
+//
+#include "mainwindow.hxx"
+void TEST_treemodel_interactif() {
+ MainWindow * window = new MainWindow();
+ window->show();
+}
+
+//
+// =================================================================
+//
+int main(int argc, char * argv[ ])
+{
+ QApplication app(argc, argv);
+ TEST_treemodel();
+ //TST_treemodel_interactif();
+ return app.exec();
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <QtGui>
+
+#include "mainwindow.hxx"
+#include "TreeModel.hxx"
+
+#include <Basics_Utils.hxx>
+#include "testhelper.hxx"
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+{
+ setupUi(this);
+
+ QStringList headers;
+ headers << tr("Title") << tr("Description");
+
+ TreeModel *model = new TreeModel(headers);
+ TESTHELPER_loadDataFromFile(model, TESTHELPER_testfilename(DATAFILENAME));
+
+ view->setModel(model);
+ for (int column = 0; column < model->columnCount(); ++column)
+ view->resizeColumnToContents(column);
+
+ connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+ connect(view->selectionModel(),
+ SIGNAL(selectionChanged(const QItemSelection &,
+ const QItemSelection &)),
+ this, SLOT(updateActions()));
+
+ connect(actionsMenu, SIGNAL(aboutToShow()), this, SLOT(updateActions()));
+ connect(insertRowAction, SIGNAL(triggered()), this, SLOT(insertRow()));
+ connect(insertColumnAction, SIGNAL(triggered()), this, SLOT(insertColumn()));
+ connect(removeRowAction, SIGNAL(triggered()), this, SLOT(removeRow()));
+ connect(removeColumnAction, SIGNAL(triggered()), this, SLOT(removeColumn()));
+ connect(insertChildAction, SIGNAL(triggered()), this, SLOT(insertChild()));
+ connect(newDataAction, SIGNAL(triggered()), this, SLOT(newData()));
+
+ updateActions();
+}
+
+void MainWindow::newData() {
+ LOG("MainWindow::newData(): START");
+
+ bool ok;
+ QString text = QInputDialog::getText(this, tr("QInputDialog::getText()"),
+ tr("Data path:"), QLineEdit::Normal,
+ "folder/subfolder/item", &ok);
+ if (!ok || text.trimmed().isEmpty())
+ return;
+
+ QStringList path = text.trimmed().split("/");
+ TreeModel *model = (TreeModel *)view->model();
+
+ QString label = path.last();
+ path.removeLast();
+ DataObject * data = TESTHELPER_dummyObject(label);
+ model->addData(data,path);
+
+ LOG("MainWindow::newData(): END");
+}
+
+void MainWindow::insertChild()
+{
+ QModelIndex index = view->selectionModel()->currentIndex();
+ QAbstractItemModel *model = view->model();
+
+ if (model->columnCount(index) == 0) {
+ if (!model->insertColumn(0, index))
+ return;
+ }
+
+ if (!model->insertRow(0, index))
+ return;
+
+ for (int column = 0; column < model->columnCount(index); ++column) {
+ QModelIndex child = model->index(0, column, index);
+ model->setData(child, QVariant("[No data]"), Qt::EditRole);
+ if (!model->headerData(column, Qt::Horizontal).isValid())
+ model->setHeaderData(column, Qt::Horizontal, QVariant("[No header]"),
+ Qt::EditRole);
+ }
+
+ view->selectionModel()->setCurrentIndex(model->index(0, 0, index),
+ QItemSelectionModel::ClearAndSelect);
+ updateActions();
+}
+
+bool MainWindow::insertColumn(const QModelIndex &parent)
+{
+ QAbstractItemModel *model = view->model();
+ int column = view->selectionModel()->currentIndex().column();
+
+ // Insert a column in the parent item.
+ bool changed = model->insertColumn(column + 1, parent);
+ if (changed)
+ model->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"),
+ Qt::EditRole);
+
+ updateActions();
+
+ return changed;
+}
+
+void MainWindow::insertRow()
+{
+ QModelIndex index = view->selectionModel()->currentIndex();
+ QAbstractItemModel *model = view->model();
+
+ if (!model->insertRow(index.row()+1, index.parent()))
+ return;
+
+ updateActions();
+
+ for (int column = 0; column < model->columnCount(index.parent()); ++column) {
+ QModelIndex child = model->index(index.row()+1, column, index.parent());
+ model->setData(child, QVariant("[No data]"), Qt::EditRole);
+ }
+}
+
+bool MainWindow::removeColumn(const QModelIndex &parent)
+{
+ QAbstractItemModel *model = view->model();
+ int column = view->selectionModel()->currentIndex().column();
+
+ // Insert columns in each child of the parent item.
+ bool changed = model->removeColumn(column, parent);
+
+ if (!parent.isValid() && changed)
+ updateActions();
+
+ return changed;
+}
+
+void MainWindow::removeRow()
+{
+ QModelIndex index = view->selectionModel()->currentIndex();
+ QAbstractItemModel *model = view->model();
+ if (model->removeRow(index.row(), index.parent()))
+ updateActions();
+}
+
+void MainWindow::updateActions()
+{
+ bool hasSelection = !view->selectionModel()->selection().isEmpty();
+ removeRowAction->setEnabled(hasSelection);
+ removeColumnAction->setEnabled(hasSelection);
+
+ bool hasCurrent = view->selectionModel()->currentIndex().isValid();
+ insertRowAction->setEnabled(hasCurrent);
+ insertColumnAction->setEnabled(hasCurrent);
+
+ if (hasCurrent) {
+ view->closePersistentEditor(view->selectionModel()->currentIndex());
+
+ int row = view->selectionModel()->currentIndex().row();
+ int column = view->selectionModel()->currentIndex().column();
+ if (view->selectionModel()->currentIndex().parent().isValid())
+ statusBar()->showMessage(tr("Position: (%1,%2)").arg(row).arg(column));
+ else
+ statusBar()->showMessage(tr("Position: (%1,%2) in top level").arg(row).arg(column));
+ }
+}
+
+void MainWindow::contextMenuEvent(QContextMenuEvent *event) {
+ QMenu menu(this);
+ menu.addAction(newDataAction);
+ menu.exec(event->globalPos());
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QModelIndex>
+
+#include "ui_mainwindow.h"
+
+class QAction;
+class QTreeView;
+class QWidget;
+
+class MainWindow : public QMainWindow, private Ui::MainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = 0);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event);
+
+public slots:
+ void updateActions();
+
+private slots:
+ void insertChild();
+ bool insertColumn(const QModelIndex &parent = QModelIndex());
+ void insertRow();
+ bool removeColumn(const QModelIndex &parent = QModelIndex());
+ void removeRow();
+ void newData();
+};
+
+#endif
--- /dev/null
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>573</width>
+ <height>468</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Editable Tree Model</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTreeView" name="view" >
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="selectionBehavior" >
+ <enum>QAbstractItemView::SelectItems</enum>
+ </property>
+ <property name="horizontalScrollMode" >
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
+ </property>
+ <property name="animated" >
+ <bool>false</bool>
+ </property>
+ <property name="allColumnsShowFocus" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>573</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="actionsMenu" >
+ <property name="title" >
+ <string>&Actions</string>
+ </property>
+ <addaction name="insertRowAction" />
+ <addaction name="insertColumnAction" />
+ <addaction name="separator" />
+ <addaction name="removeRowAction" />
+ <addaction name="removeColumnAction" />
+ <addaction name="separator" />
+ <addaction name="insertChildAction" />
+ </widget>
+ <widget class="QMenu" name="fileMenu" >
+ <property name="title" >
+ <string>&File</string>
+ </property>
+ <addaction name="exitAction" />
+ </widget>
+ <widget class="QMenu" name="menuData" >
+ <property name="title" >
+ <string>Data</string>
+ </property>
+ <addaction name="newDataAction" />
+ </widget>
+ <addaction name="fileMenu" />
+ <addaction name="actionsMenu" />
+ <addaction name="menuData" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <action name="exitAction" >
+ <property name="text" >
+ <string>E&xit</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="insertRowAction" >
+ <property name="text" >
+ <string>Insert Row</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+I, R</string>
+ </property>
+ </action>
+ <action name="removeRowAction" >
+ <property name="text" >
+ <string>Remove Row</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+R, R</string>
+ </property>
+ </action>
+ <action name="insertColumnAction" >
+ <property name="text" >
+ <string>Insert Column</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+I, C</string>
+ </property>
+ </action>
+ <action name="removeColumnAction" >
+ <property name="text" >
+ <string>Remove Column</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+R, C</string>
+ </property>
+ </action>
+ <action name="insertChildAction" >
+ <property name="text" >
+ <string>Insert Child</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ <action name="newDataAction" >
+ <property name="text" >
+ <string>new</string>
+ </property>
+ </action>
+ </widget>
+ <resources>
+ <include location="editabletreemodel.qrc" />
+ </resources>
+ <connections/>
+</ui>
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtHelper.hxx"
+
+//
+// =================================================================
+// Helper functions for DataObject and DataModel classes
+// =================================================================
+//
+
+// ----
+// A DataObject can't be used as is but must be specialized to
+// specify the behavior in the hierarchic model.
+#include "MyDataModel.hxx"
+
+void TEST_DataObject() {
+ // In this test, the object id should increase at each instance
+ DataObject * dataObject;
+ for (int i=0; i<100; i++) {
+ dataObject = new MyDataObject();
+ QLOG("object nameId = " << dataObject->getNameId().c_str());
+ }
+ QLOG("path = " << dataObject->getPath().c_str());
+ QLOG("pathname = " << dataObject->getPathName().c_str());
+
+ QLOG("serialize= " << dataObject->toString().c_str());
+
+}
+
+void TEST_DataModel() {
+ MyDataModel * dataModel = new MyDataModel();
+
+ int refIter = 53;
+ string refNameId;
+
+ DataObject * dataObject;
+ for (int i=0; i<100; i++) {
+ // We can either create the data object using its constructor or
+ // using the factory of the model (the prefered way):
+ // dataObject = new MyDataObject();
+ dataObject = dataModel->newDataObject();
+ dataObject->setLabel("myobject"+ToString(i));
+ if ( i == refIter ) {
+ refNameId = dataObject->getNameId();
+ }
+ dataModel->addDataObject(dataObject);
+ }
+
+ dataObject = dataModel->getDataObject(refNameId);
+ QLOG("object nameId = " << dataObject->getNameId().c_str());
+ QLOG("path = " << dataObject->getPath().c_str());
+ QLOG("pathname = " << dataObject->getPathName().c_str());
+}
+
+//
+// =================================================================
+//
+int main(int argc, char * argv[ ])
+{
+ TEST_DataObject();
+ //TEST_DataModel();
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "testhelper.hxx"
+
+#include <QFile>
+#include <QString>
+
+#include "QtHelper.hxx"
+#include "MyDataModel.hxx"
+
+// Standard C include (for getenv)
+#include <stdlib.h>
+
+QString TESTHELPER_testfilename(const char * basefilename) {
+ QString aFile;
+ char * GUI_ROOT_DIR = getenv("GUI_ROOT_DIR");
+ QString * root;
+ if ( GUI_ROOT_DIR != NULL ) {
+ root = new QString(GUI_ROOT_DIR);
+ }
+ else {
+ root = new QString("/home/gboulant/development/projets/salome/devel/XSALOME/install");
+ }
+ QString relativePathName = "/share/salome/resources/gui/testdata/";
+ aFile.append(*root + relativePathName + basefilename);
+
+ QLOG("The test file is : "<<aFile);
+ return aFile;
+}
+
+/*!
+ * This creates a dummy data object for the needs of the test
+ * functions. The label is the basename of the spécified pathname.
+ */
+DataObject * TESTHELPER_dummyObject(QString label) {
+ MyDataObject * dataObject = new MyDataObject();
+ dataObject->setLabel(QCHARSTAR(label));
+ return dataObject;
+}
+
+
+#define SEP ";"
+/*!
+ * This test function shows how it's possible to load data from a file
+ * to populate the tree model.
+ */
+void TESTHELPER_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename) {
+ QFile file ( filename );
+ file.open ( QIODevice::ReadOnly );
+
+ MyDataObject * dataObject;
+ while ( 1 ) {
+ QByteArray byteArray = file.readLine();
+
+ if ( byteArray.isEmpty() )
+ break;
+
+ QString data = (QString ( byteArray.mid(0, byteArray.size()-1))).trimmed();
+ QStringList dataList = data.split ( SEP );
+ // The data list is used here to set properties (and then the path
+ // of location in the tree model).
+
+ dataObject = new MyDataObject();
+ // The label is autogenerated, but we may specify here a custom
+ // one. We just fill the properties with data values read in the
+ // file.
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, QCHARSTAR(dataList[0]));
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, QCHARSTAR(dataList[1]));
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, QCHARSTAR(dataList[2]));
+ if ( ! dataTreeModel->addData(dataObject) ) {
+ QLOG("ERR: data not added");
+ }
+ }
+
+ file.close();
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _TESTHELPER_HXX_
+#define _TESTHELPER_HXX_
+
+#include <QString>
+#include "TreeModel.hxx"
+#include "DataObject.hxx"
+
+#define DATAFILENAME "data.txt"
+
+QString TESTHELPER_testfilename(const char * basefilename);
+DataObject * TESTHELPER_dummyObject(QString label);
+void TESTHELPER_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename);
+
+#endif // _TESTHELPER_HXX_
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef TREEDATA_HXX
+#define TREEDATA_HXX
+
+#ifdef WIN32
+# if defined SALOMETREEDATA_EXPORTS || defined SalomeTreeData_EXPORTS
+# define TREEDATA_EXPORT __declspec( dllexport )
+# else
+# define TREEDATA_EXPORT __declspec( dllimport )
+# endif
+#else
+# define TREEDATA_EXPORT
+#endif
+
+#endif //TREEDATA_HXX
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "TreeGuiManager.hxx"
+
+// SALOME includes
+#include <QStringList>
+
+// XCAD includes
+#include "TreeView.hxx"
+#include "QtHelper.hxx"
+
+// TODO:
+// IMP: The constructor should have a dockwidget as argument.
+// The creation of the void dockwidget (without the data tree
+// embedded) should be done previously by the StandardApp_Module.
+// The constructor would fill the dockwidget with a data tree view
+
+/*!
+ * The construction of the gui manager setups a graphic framework that
+ * consists in a set of dock widgets implanted in the SALOME GUI and
+ * embedding a tree view rendering a data model (collection of data
+ * objects) in a hierarchic graphical organisation.
+ *
+ * The data model is a straith list of data objects while the view is
+ * a tree representation of this collection where folders corresponds
+ * to specific properties of the objects.
+ *
+ * This represention is for the needs of navigation in a huge amount
+ * of data and to ease the selection and processing of items.
+ */
+TreeGuiManager::TreeGuiManager(SalomeApp_Application * salomeApp, const char * title)
+ : TreeObserver()
+{
+ _salomeApp = salomeApp;
+
+ bool tabify = false;
+ _dockWidgets = new DockWidgets(_salomeApp, tabify, title);
+
+ // Create a TreeView to be associated to a TreeModel dedicated to
+ // the Xcad data:
+ _dataTreeView = new TreeView();
+ QStringList headers;
+ headers << tr("Name") << tr("Value");
+ _dataTreeModel = new TreeModel(headers);
+ _dataTreeView->setModel(_dataTreeModel);
+
+ // Then plug the TreeView in the dock widget:
+ _dockWidgets->setDataView(_dataTreeView);
+
+ // We specify here the dataview to be observed
+ this->observe(_dataTreeView);
+}
+
+/*!
+ * This returns the SALOME application (SalomeApp_Application
+ * instance) associated to this TreeGuiManager.
+ */
+SalomeApp_Application * TreeGuiManager::getSalomeApplication() {
+ return _salomeApp;
+}
+
+
+/*!
+ * This function set a layout of the different dock widgets in one
+ * single tabbed widget.
+ */
+void TreeGuiManager::tabifyDockWidgets(bool tabify) {
+ _dockWidgets->tabify(tabify);
+}
+
+/*!
+ * This function switch on/off the dock widgets managed by this
+ * gui manager.
+ */
+void TreeGuiManager::showDockWidgets(bool isVisible) {
+ _dockWidgets->show(isVisible);
+}
+
+/*!
+ * This returns the data tree model defined in this
+ * TreeGuiManager. The data tree model is a tree representation of the
+ * data model associated to this TreeGuiManager.
+ */
+TreeModel * TreeGuiManager::getDataTreeModel() {
+ return _dataTreeModel;
+}
+
+/*!
+ * This returns the data tree view defined in this
+ * TreeGuiManager. The data tree view can be request to customize the
+ * popup menu associated to the tree representation.
+ */
+TreeView * TreeGuiManager::getDataTreeView() {
+ return _dataTreeView;
+}
+
+
+/*!
+ * This function specifies the data model to be used by the
+ * TreeGuiManager.
+ */
+void TreeGuiManager::setDataModel(DataModel * dataModel) {
+ _dataModel = dataModel;
+}
+
+DataModel * TreeGuiManager::getDataModel() {
+ return _dataModel;
+}
+
+/*!
+ * This function processes the edit signals received from the
+ * TreeView. This is a default implementation that only prints the
+ * reception of the signal and some information about the dataObject
+ * associated to the item whose id is specified. In practice, the data
+ * model could be requested here to retrieve the data object to be
+ * edited from the nameId.
+ * TO BE IMPLEMENTED IN A DOMAIN SPECIFIC VERSION OF THIS CLASS
+ */
+
+void TreeGuiManager::processItemList(QStringList itemNameIdList,
+ int actionId)
+{
+ // WARN: THIS IS A DEFAULT IMPLEMENTATION GIVEN FOR DEMONSTRATION
+ // OF WHAT TO DO WITH THE PARAMETERS
+
+ QString itemNameId = itemNameIdList[0];
+ LOG("TreeGuiManager: signal received : process item "<<itemNameId);
+ DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+ if ( dataObject != NULL ) {
+ LOG("TreeGuiManager: dataObject = "<<dataObject->toString().c_str());
+ } else {
+ LOG("TreeGuiManager: no data object associated to this item");
+ }
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _TREEGUIMANAGER_H_
+#define _TREEGUIMANAGER_H_
+
+#include "TreeData.hxx"
+
+// SALOME includes
+#include <SalomeApp_Application.h>
+
+// TREEDATA includes
+#include "DockWidgets.hxx"
+#include "TreeModel.hxx"
+#include "DataModel.hxx"
+#include "TreeView.hxx"
+#include "TreeObserver.hxx"
+
+class TREEDATA_EXPORT TreeGuiManager : public TreeObserver {
+
+public:
+ TreeGuiManager(SalomeApp_Application * salomeApp, const char * title="Data Model");
+ void tabifyDockWidgets(bool tabify);
+ void showDockWidgets(bool isVisible);
+ SalomeApp_Application * getSalomeApplication();
+
+ TreeModel * getDataTreeModel();
+ TreeView * getDataTreeView();
+
+ void setDataModel(DataModel * dataModel);
+ DataModel * getDataModel();
+
+private:
+ SalomeApp_Application * _salomeApp;
+
+ DockWidgets * _dockWidgets;
+ TreeView * _dataTreeView;
+
+ TreeModel * _dataTreeModel;
+ DataModel * _dataModel;
+
+public slots:
+ virtual void processItemList(QStringList itemNameIdList, int actionId);
+};
+
+#endif /* _TREEGUIMANAGER_H_ */
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include <QStringList>
+#include "TreeItem.hxx"
+
+TreeItem::TreeItem(const QString &nameId,
+ const QVector<QVariant> &columnValues,
+ TreeItem *parent)
+{
+ this->initialize(nameId, columnValues, parent);
+}
+
+/*!
+ * This initializes the tree item. Called by the constructors.
+ */
+void TreeItem::initialize(const QString &nameId,
+ const QVector<QVariant> &columnValues,
+ TreeItem *parent) {
+ _itemNameId = nameId;
+ _itemData = columnValues;
+ _parentItem = parent;
+
+ // An item is associated to the model of its parent. It can't be
+ //done automatically in the case where the item has no parent. Then
+ //the function associatedToModel has to be called explicitely from
+ //within the user code (for exemple at construction of the model,
+ //when creating the root item).
+ if ( parent != NULL ) {
+ this->associateToModel(parent->associatedModel());
+ }
+}
+
+TreeItem::~TreeItem()
+{
+ qDeleteAll(_childItems);
+ qDeleteAll(_childItemsMapById);
+ qDeleteAll(_childItemsMapByLabel);
+}
+
+/*!
+ * This must be used to specified which model this item belongs to. It
+ * is required because the item sometimes requests its model for
+ * global informations about the data tree. In standard usage, this
+ * function is automatically set when the item is instantiated by
+ * requested the parent item. Then only the root item needs a manual
+ * setting.
+ */
+void TreeItem::associateToModel(TreeModel * model) {
+ _associatedModel = model;
+}
+
+TreeModel * TreeItem::associatedModel() {
+ return _associatedModel;
+}
+
+/*!
+ * This provide an identifier for this item
+ */
+QString TreeItem::nameId() {
+ return _itemNameId;
+}
+
+/*!
+ * This creates an item from the specified dataObject and put it in
+ * the decendency of this item at the specified relativePath. The
+ * created item could not be a direct child of this item in the case
+ * where the relative path is not null. Note that no reference on the
+ * dataObject is kept in this instance. Only the identifier is used to
+ * set the item identifier, and the properties may be used to set the
+ * values of the item (stored in columns).
+ */
+void TreeItem::appendChild(DataObject * dataObject,
+ const QStringList &relativePath) {
+ // Definition of the nameId
+ QString nameId = QString(dataObject->getNameId().c_str());
+
+ // Definition of columns data values
+ QVector<QVariant> columnValues;
+ columnValues << QString(dataObject->getLabel().c_str());
+ columnValues << "No value"; // We could use the dataObject properties
+
+ // Append the item at the specified location with the specified values:
+ this->appendChild(nameId, columnValues, relativePath);
+}
+
+void TreeItem::appendChild(const QString &nameId,
+ const QVector<QVariant> &columnValues,
+ const QStringList &relativePath) {
+
+ if ( relativePath.isEmpty() ) {
+ // It is a direct child => just create and append to this.
+ TreeItem * child = new TreeItem(nameId, columnValues, this);
+ this->appendChild(child);
+ return;
+ }
+
+ // The child is embedded in a sub-folder (to be created if doesn't
+ // exist).
+ // We first check if the sub-folder already exist:
+ TreeItem * folder = this->childByLabel(relativePath[0]);
+ if ( folder == NULL ) {
+ // The folder does not exist. It must be created before going any
+ // further. By convention we choose the folder name as
+ // identifier.
+ QString folderNameId = relativePath[0];
+ QVector<QVariant> folderColumnValues;
+ folderColumnValues << relativePath[0] << "No value";
+ folder = new TreeItem(folderNameId, folderColumnValues, this);
+ this->appendChild(folder);
+ }
+
+ // We create the relative path of the next iteration (delete the
+ // first folder path).
+ QStringList nextRelativePath;
+ for (int i = 1; i < relativePath.size(); ++i)
+ nextRelativePath << relativePath[i];
+
+ folder->appendChild(nameId, columnValues, nextRelativePath);
+}
+
+/*!
+ * This appends the specified child to this item. This item is the
+ * direct parent of the specified child.
+ */
+void TreeItem::appendChild(TreeItem *item)
+{
+ TreeModel * model = this->associatedModel();
+
+ int position = this->childCount();
+ model->beginInsertRows(this->modelIndex(), position, position);
+ _childItems.append(item);
+ _childItemsMapById[item->nameId()] = item;
+ _childItemsMapByLabel[item->data(0).toString()] = item;
+ model->endInsertRows();
+}
+
+/*!
+ * The child() function returns the child that corresponds to the
+ * specified row number in the item's list of child items.
+ */
+TreeItem *TreeItem::child(int row)
+{
+ return _childItems.value(row);
+}
+
+TreeItem *TreeItem::childById(const QString &nameId)
+{
+ QMap <QString, TreeItem*>::iterator it;
+ it = _childItemsMapById.find ( nameId );
+
+ if ( it != _childItemsMapById.end() ) {
+ return it.value();
+ }
+ return NULL;
+}
+
+TreeItem *TreeItem::childByLabel(const QString &label)
+{
+ QMap <QString, TreeItem*>::iterator it;
+ it = _childItemsMapByLabel.find ( label );
+
+ if ( it != _childItemsMapByLabel.end() ) {
+ return it.value();
+ }
+ return NULL;
+}
+
+
+
+int TreeItem::childCount() const
+{
+ return _childItems.count();
+}
+
+/*!
+ * The rowIndex() function reports the item's location within its
+ * parent's list of items.
+ */
+int TreeItem::rowIndex() const
+{
+ if (_parentItem)
+ return _parentItem->_childItems.indexOf(const_cast<TreeItem*>(this));
+
+ return 0;
+}
+
+int TreeItem::columnCount() const
+{
+ return _itemData.count();
+}
+
+QVariant TreeItem::data(int column) const
+{
+ return _itemData.value(column);
+}
+
+TreeItem *TreeItem::parent()
+{
+ return _parentItem;
+}
+
+bool TreeItem::setData(int column, const QVariant &value)
+{
+ if (column < 0 || column >= _itemData.size())
+ return false;
+
+ _itemData[column] = value;
+ return true;
+}
+
+QModelIndex TreeItem::modelIndex(int column)
+{
+ TreeModel * model = this->associatedModel();
+ if (_parentItem && (_parentItem != model->getRootItem()))
+ return model->index(rowIndex(),
+ column,
+ _parentItem->modelIndex());
+ else
+ return model->index(rowIndex(),
+ column,
+ QModelIndex());
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef TREEITEM_H
+#define TREEITEM_H
+
+#include "TreeData.hxx"
+
+#include <QList>
+#include <QVariant>
+#include <QVector>
+#include <QModelIndex>
+
+#include "DataObject.hxx"
+#include "TreeModel.hxx"
+
+class TREEDATA_EXPORT TreeItem
+{
+ public:
+ TreeItem(const QString &nameId, const QVector<QVariant> &columnValues, TreeItem *parent = 0);
+ ~TreeItem();
+
+ QString nameId();
+ void associateToModel(TreeModel * model);
+ TreeModel * associatedModel();
+ QModelIndex modelIndex(int column=0);
+ TreeItem *parent();
+
+ void appendChild(TreeItem * child);
+ void appendChild(DataObject * dataObject,
+ const QStringList &relativePath=QStringList());
+ void appendChild(const QString &nameId,
+ const QVector<QVariant> &columnValues,
+ const QStringList &relativePath=QStringList());
+
+
+
+ TreeItem *child(int row);
+ TreeItem *childById(const QString &nameId);
+ TreeItem *childByLabel(const QString &label);
+ int childCount() const;
+ int columnCount() const;
+ int rowIndex() const;
+ QVariant data(int column) const;
+ bool setData(int column, const QVariant &value);
+
+
+ private:
+ void initialize(const QString &nameId,
+ const QVector<QVariant> &columnValues,
+ TreeItem *parent);
+
+ QList<TreeItem*> _childItems;
+ QMap <QString, TreeItem *> _childItemsMapById;
+ QMap <QString, TreeItem *> _childItemsMapByLabel;
+
+ QString _itemNameId;
+ QVector<QVariant> _itemData;
+ TreeItem * _parentItem;
+ TreeModel * _associatedModel;
+
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include <QtGui>
+
+#include "TreeItem.hxx"
+#include "TreeModel.hxx"
+
+TreeModel::TreeModel(const QStringList &headers, QObject *parent)
+ : QAbstractItemModel(parent)
+{
+ QVector<QVariant> rootData;
+ foreach (QString header, headers)
+ rootData << header;
+
+ // _MEM_ We have to specify a string identifier for each item so
+ // that it could be easily retrieved by its parent. In the case of
+ // the root item, the value of the identifier doesn't matter => we
+ // choose an arbitrary value
+ //QString rootNameId = "rootItem";
+ _rootItem = new TreeItem("rootItem", rootData);
+ _rootItem->associateToModel(this);
+}
+
+TreeModel::~TreeModel()
+{
+ delete _rootItem;
+}
+
+TreeItem * TreeModel::getRootItem() {
+ return _rootItem;
+}
+
+//
+// =================================================================
+// This part of the implementation is the standard interface required
+// for providing an operational TreeModel. These methods are used by
+// the TreeView for display purpose. We just have to implement how we
+// want the items to be displayed in the view.
+// =================================================================
+//
+int TreeModel::columnCount(const QModelIndex & /* parent */) const
+{
+ return _rootItem->columnCount();
+}
+
+/*!
+ * This function is used by the tree model to inform the tree view of
+ * what data used for rendering of the item in the different possible
+ * role (edition, ...).
+ */
+QVariant TreeModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (role != Qt::DisplayRole && role != Qt::EditRole)
+ return QVariant();
+
+ TreeItem *item = getItem(index);
+
+ return item->data(index.column());
+}
+
+Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+
+ return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+/*!
+ * This retrieves the item asociated to the specified index.
+ */
+TreeItem *TreeModel::getItem(const QModelIndex &index) const
+{
+ // The item associated to an index can be retrieved using the
+ // internalPointer() function on the index object.
+ if (index.isValid()) {
+ TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
+ if (item) return item;
+ }
+ return _rootItem;
+}
+
+QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+ return _rootItem->data(section);
+
+ return QVariant();
+}
+
+/*!
+ * This retrieves the index of the item located at (row,column) place
+ * relative to the parent specified by its index.
+ */
+QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (parent.isValid() && parent.column() != 0)
+ return QModelIndex();
+
+ TreeItem *parentItem = getItem(parent);
+
+ TreeItem *childItem = parentItem->child(row);
+ if (childItem)
+ return createIndex(row, column, childItem);
+ else
+ return QModelIndex();
+}
+
+QModelIndex TreeModel::parent(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ TreeItem *childItem = getItem(index);
+ TreeItem *parentItem = childItem->parent();
+
+ if (parentItem == _rootItem)
+ return QModelIndex();
+
+ return createIndex(parentItem->rowIndex(), 0, parentItem);
+}
+
+int TreeModel::rowCount(const QModelIndex &parent) const
+{
+ TreeItem *parentItem = getItem(parent);
+
+ return parentItem->childCount();
+}
+
+bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
+ int role)
+{
+ if (role != Qt::EditRole)
+ return false;
+
+ TreeItem *item = getItem(index);
+ bool result = item->setData(index.column(), value);
+
+ if (result)
+ emit dataChanged(index, index);
+
+ return result;
+}
+
+bool TreeModel::setHeaderData(int section, Qt::Orientation orientation,
+ const QVariant &value, int role)
+{
+ if (role != Qt::EditRole || orientation != Qt::Horizontal)
+ return false;
+
+ bool result = _rootItem->setData(section, value);
+
+ if (result)
+ emit headerDataChanged(orientation, section, section);
+
+ return result;
+}
+
+
+//
+// =================================================================
+// This part is a specific behavior to get a TreeModel that can
+// organize itself the tree hierarchy using data provided in a
+// filesystem-like format:
+//
+// data="a/b/c" ==> creation/filling of the hierarchy a->b->c
+// The "folder" categories are unique whereas the leaves may exists
+// in multiple instances.
+// =================================================================
+//
+
+/*
+ * The addData functions run a recurcive filling of the tree model, starting
+ * form the rootItem and descending in the tree using the recurcive
+ * function TreeItem::addData.
+ */
+
+bool TreeModel::addData(DataObject * dataObject) {
+ QStringList path = QString(dataObject->getPath().c_str()).split(DataObject::pathsep.c_str());
+ return addData(dataObject, path);
+}
+bool TreeModel::addData(DataObject * dataObject, const QStringList &path) {
+ TreeItem * rootItem = this->getItem();
+ rootItem->appendChild(dataObject, path);
+ return true;
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef TREEMODEL_H
+#define TREEMODEL_H
+
+#include "TreeData.hxx"
+
+#include <QAbstractItemModel>
+#include <QModelIndex>
+#include <QVariant>
+#include <QStringList>
+
+#include "DataObject.hxx"
+
+class TreeItem;
+class TreeView;
+
+class TREEDATA_EXPORT TreeModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+ // IMPORTANT NOTE:
+ // In this implementation of QAbstractItemModel, a tree item is
+ // associated to the tree model it belongs to (it can request its
+ // model throw a pointer to this model). Then we declare the
+ // TreeItem as a friend class so that it can request the protected
+ // methods (for example beginInsertRows and endInsertRows, required
+ // to manage correctly the addition of an item in the model. An
+ // item can append a child to itself, so it needs to inform the
+ // model when it begins and when it ends).
+ friend class TreeItem;
+ friend class TreeView;
+
+public:
+ TreeModel(const QStringList &headers, QObject *parent = 0);
+ ~TreeModel();
+
+ //
+ // =================================================================
+ // This part of the specification is the standard interface required
+ // for providing an operational TreeModel. These methods are used by
+ // the TreeView for display purpose. We just have to implement how
+ // we want the items to be displayed in the view.
+ // =================================================================
+ //
+ // MEM: note that these methods are not intended to be used
+ // directly. That's the job of the viewer to know how to use
+ // them. We just have to give the implementation for customizing the
+ // appearance of the tree. The implementation generally requests the
+ // items'data to set the appearance features.
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ //
+ // =================================================================
+ // This part is a specific behavior to get a TreeModel that can
+ // organize itself the tree hierarchy using data provided in a
+ // filesystem-like format:
+ //
+ // data="a/b/c" ==> creation/filling of the hierarchy a->b->c
+ // The "folder" categories are unique whereas the leaves may exists
+ // in multiple instances.
+ // =================================================================
+ //
+ bool addData(DataObject * dataObject);
+ bool addData(DataObject * dataObject, const QStringList &path);
+
+ // TODO: We should implement the delete and the update fucntions
+
+ // This part contains helper functions for general purposes
+ TreeItem * getRootItem();
+
+private:
+ TreeItem *getItem(const QModelIndex &index = QModelIndex()) const;
+ TreeItem * _rootItem;
+};
+
+#endif // TREEMODEL_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "TreeObserver.hxx"
+#include "QtHelper.hxx"
+
+TreeObserver::TreeObserver() : QObject() {
+}
+
+/*!
+ * This declares the TreeView to be observed by this tree events
+ * listener.
+ */
+void TreeObserver::observe(TreeView * treeView) {
+ // We just connect the signals emitted from the treeview to
+ // corresponding slots of this observer.
+ connect(treeView, SIGNAL(itemListToProcess(QStringList,int)),
+ this, SLOT(processItemList(QStringList,int)));
+}
+
+/*!
+ * This slot should be implemented in a specialized version of
+ * TreeObserver to process the signal emitted from the TreeView. The
+ * parameters are:
+ * - itemNameIdList: the list of name identifiers of model objects
+ * associated to the selected qt items in the TreeView (ids for
+ * requesting directly the data model).
+ * - actionId: the identifier of the action selected in the popup menu
+ * that triggered this signal.
+ */
+void TreeObserver::processItemList(QStringList itemNameIdList, int actionId) {
+ LOG("TreeObserver::processItemList: signal received:\n"<<
+ "item list: "<<itemNameIdList<<"\n"<<
+ "action id: "<<actionId);
+}
+
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _TREEOBSERVER_
+#define _TREEOBSERVER_
+
+#include "TreeData.hxx"
+
+#include <QObject>
+#include "TreeView.hxx"
+
+class TREEDATA_EXPORT TreeObserver : public QObject {
+
+ Q_OBJECT
+
+public:
+ TreeObserver();
+ void observe(TreeView * treeView);
+
+public slots:
+ /* These slots should be implemented in a specialized version of
+ the TreeObserver to process signals emitted from the TreeView */
+ virtual void processItemList(QStringList itemNameIdList, int actionId);
+};
+
+#endif // _TREEOBSERVER_
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+// include Qt
+#include <QString>
+#include <QMenu>
+#include <QModelIndex>
+#include <QAbstractItemView>
+
+// include Xcad
+#include "TreeView.hxx"
+#include "TreeModel.hxx"
+#include "TreeItem.hxx"
+#include "QtHelper.hxx"
+
+TreeView::TreeView(QWidget * parent)
+ : QTreeView(parent)
+{
+ // We authorize the multiple selection of items
+ this->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+ _lastActionId = 0;
+
+ // Default actions for tests
+ int displayActionId = addAction(QObject::tr("Afficher"));
+ int editActionId = addAction(QObject::tr("Editer"));
+}
+
+TreeView::~TreeView() {
+}
+
+/*!
+ * This function defines a menu item to add in the popup menu
+ * associated to this TreeView, and return an integer that corresponds
+ * to the unique identifier of this action (identifier used in the
+ * signal emitted to notify observers that an action has been
+ * selected). Then the caller of this function has to take care of
+ * this return id (i.e. has to store it in its internal tables) to be
+ * able to process the notifications from this TreeView.
+ */
+int TreeView::addAction(QString label) {
+ QAction * action = new QAction(this);
+ int actionId = _lastActionId;
+ action->setObjectName(_idToName(actionId));
+ action->setText(label);
+ _listActions << action;
+ _lastActionId++;
+
+ return actionId;
+}
+
+/*!
+ * This function removes all actions previously defined for the popup
+ * menu of this TreeView.
+ */
+void TreeView::clearActions() {
+ _listActions.clear();
+}
+
+/*!
+ * You must use this function to create the name of an action object
+ * from its id.
+ */
+QString TreeView::_idToName(int actionId) {
+ return QString::number(actionId);
+}
+/*!
+ * You must use this function to create the id of an action object
+ * from its name (stored in objectName() attribute of the QAction).
+ */
+int TreeView::_nameToId(QString actionName) {
+ return actionName.toInt();
+}
+
+void TreeView::contextMenuEvent(QContextMenuEvent *event) {
+ if ( _listActions.size() == 0 ) {
+ // Just return there is no actions defined for this popup menu
+ return;
+ }
+
+ // _TODO_ display the QMenu only if the selected item is acceptable
+ QMenu menu(this);
+ for (int i = 0; i < _listActions.size(); ++i) {
+ menu.addAction(_listActions.at(i));
+ }
+ connect(&menu, SIGNAL(triggered(QAction*)),
+ this, SLOT(processMenuAction(QAction*)));
+
+ menu.exec(event->globalPos());
+}
+
+/*!
+ * This SLOT is connected on the signal emited by the menu when an
+ * action is selected.
+ */
+void TreeView::processMenuAction(QAction * actionSelected) {
+ LOG("processMenuAction: START");
+
+ // We first check than at least on item is selected
+ QModelIndexList indexList = this->selectionModel()->selectedRows(0);
+ if ( indexList.isEmpty() ) {
+ LOG("No item selected");
+ return;
+ }
+
+ // Then we can gather the list of model item ids associated the
+ // selection.
+ TreeModel *model = (TreeModel *)this->model();
+ QListIterator<QModelIndex> it(indexList);
+ QStringList nameIdList;
+ while (it.hasNext()) {
+ TreeItem * item = model->getItem(it.next());
+ nameIdList << item->nameId();
+ }
+
+ // Finally, one can emit a signal to observers specifying the list of
+ // id and the type of action (i.e. the action identifier)
+ int actionId = _nameToId(actionSelected->objectName());
+ LOG("TreeView::processMenuAction: signal emitted:\n"<<
+ "item list: "<<nameIdList<<"\n"<<
+ "action id: "<<actionId);
+ emit itemListToProcess(nameIdList, actionId);
+
+ LOG("processMenuAction: END");
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef TREEVIEW_H
+#define TREEVIEW_H
+
+#include "TreeData.hxx"
+
+#include <QTreeView>
+#include <QAction>
+#include <QContextMenuEvent>
+#include <QList>
+
+class TREEDATA_EXPORT TreeView : public QTreeView
+{
+ Q_OBJECT
+
+public:
+ TreeView(QWidget * parent = 0 );
+ ~TreeView();
+ int addAction(QString label);
+ void clearActions();
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event);
+
+private:
+ int _lastActionId;
+ QList<QAction*> _listActions;
+ QString _idToName(int actionId);
+ int _nameToId(QString actionName);
+
+ // ---
+
+private slots:
+ void processMenuAction(QAction * actionSelected);
+
+signals:
+ void itemListToProcess(QStringList itemNameIdList, int actionId);
+};
+
+#endif // TREEVIEW_H
+
--- /dev/null
+000000000
+000000000
+000000000
+000000000
+000010000
+000000000
+000000000
+000000000
+000000000
+
+00000000000
+00000000000
+00000000000
+00000000000
+00000110000
+00000110000
+00000000000
+00000000000
+00000000000
+00000000000
+00000000000
+
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000001100000
+0000001100000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+0000000000000
+
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000011000000
+000000011000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+000000000000000
+
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000001110000000
+00000001110000000
+00000001110000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+00000000000000000
+
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000011110000000
+0000000011110000000
+0000000011110000000
+0000000011110000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+0000000000000000000
+
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000111100000000
+000000000111100000000
+000000000111100000000
+000000000111100000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+000000000000000000000
+
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000001111000000000
+00000000001111000000000
+00000000001111000000000
+00000000001111000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+00000000000000000000000
+
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000111110000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+0000000000000000000000000
+
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000001111110000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+000000000000000000000000000
+
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000011111100000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+00000000000000000000000000000
+
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000111111000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+0000000000000000000000000000000
+
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000001111111000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
+00000000000000000000000000000000
--- /dev/null
+000010000
+000010000
+000010000
+000010000
+111111111
+000010000
+000010000
+000010000
+000010000
+
+00000100000
+00000100000
+00000100000
+00000100000
+00000100000
+11111111111
+00000100000
+00000100000
+00000100000
+00000100000
+00000100000
+
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+1111111111111
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+0000001000000
+
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+111111111111111
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+000000010000000
+
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+11111111111111111
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+1111111111111111111
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+111111111111111111111
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+11111111111111111111111
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+1111111111111111111111111
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+111111111111111111111111111
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+11111111111111111111111111111
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+1111111111111111111111111111111
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+11111111111111111111111111111111
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
--- /dev/null
+000010000
+000010000
+110010011
+001111100
+000010000
+001111100
+110010011
+000010000
+000010000
+
+00000100000
+00000100000
+10000100001
+01100100110
+00011111000
+00000100000
+00011111000
+01100100110
+10000100001
+00000100000
+00000100000
+
+0000001000000
+0000001000000
+0000001000000
+1100001000011
+0011001001100
+0000111110000
+0000001000000
+0000111110000
+0011001001100
+1100001000011
+0000001000000
+0000001000000
+0000001000000
+
+000000010000000
+000000010000000
+000000010000000
+100000010000001
+011000010000110
+000110010011000
+000001111100000
+000000010000000
+000001111100000
+000110010011000
+011000010000110
+100000010000001
+000000010000000
+000000010000000
+000000010000000
+
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+11000000100000011
+00110000100001100
+00001100100110000
+00000011111000000
+00000000100000000
+00000011111000000
+00001100100110000
+00110000100001100
+11000000100000011
+00000000100000000
+00000000100000000
+00000000100000000
+00000000100000000
+
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+1000000001000000001
+0110000001000000110
+0001100001000011000
+0000011001001100000
+0000000111110000000
+0000000001000000000
+0000000111110000000
+0000011001001100000
+0001100001000011000
+0110000001000000110
+1000000001000000001
+0000000001000000000
+0000000001000000000
+0000000001000000000
+0000000001000000000
+
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+110000000010000000011
+001100000010000001100
+000011000010000110000
+000000110010011000000
+000000001111100000000
+000000000010000000000
+000000001111100000000
+000000110010011000000
+000011000010000110000
+001100000010000001100
+110000000010000000011
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+000000000010000000000
+
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+10000000000100000000001
+01100000000100000000110
+00011000000100000011000
+00000110000100001100000
+00000001100100110000000
+00000000011111000000000
+00000000000100000000000
+00000000011111000000000
+00000001100100110000000
+00000110000100001100000
+00011000000100000011000
+01100000000100000000110
+10000000000100000000001
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+00000000000100000000000
+
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+1100000000001000000000011
+0011000000001000000001100
+0000110000001000000110000
+0000001100001000011000000
+0000000011001001100000000
+0000000000111110000000000
+0000000000001000000000000
+0000000000111110000000000
+0000000011001001100000000
+0000001100001000011000000
+0000110000001000000110000
+0011000000001000000001100
+1100000000001000000000011
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+0000000000001000000000000
+
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+100000000000010000000000001
+011000000000010000000000110
+000110000000010000000011000
+000001100000010000001100000
+000000011000010000110000000
+000000000110010011000000000
+000000000001111100000000000
+000000000000010000000000000
+000000000001111100000000000
+000000000110010011000000000
+000000011000010000110000000
+000001100000010000001100000
+000110000000010000000011000
+011000000000010000000000110
+100000000000010000000000001
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+000000000000010000000000000
+
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+11000000000000100000000000011
+00110000000000100000000001100
+00001100000000100000000110000
+00000011000000100000011000000
+00000000110000100001100000000
+00000000001100100110000000000
+00000000000011111000000000000
+00000000000000100000000000000
+00000000000011111000000000000
+00000000001100100110000000000
+00000000110000100001100000000
+00000011000000100000011000000
+00001100000000100000000110000
+00110000000000100000000001100
+11000000000000100000000000011
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+00000000000000100000000000000
+
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+1000000000000001000000000000001
+0110000000000001000000000000110
+0001100000000001000000000011000
+0000011000000001000000001100000
+0000000110000001000000110000000
+0000000001100001000011000000000
+0000000000011001001100000000000
+0000000000000111110000000000000
+0000000000000001000000000000000
+0000000000000111110000000000000
+0000000000011001001100000000000
+0000000001100001000011000000000
+0000000110000001000000110000000
+0000011000000001000000001100000
+0001100000000001000000000011000
+0110000000000001000000000000110
+1000000000000001000000000000001
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+0000000000000001000000000000000
+
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+10000000000000010000000000000010
+01100000000000010000000000001100
+00011000000000010000000000110000
+00000110000000010000000011000000
+00000001100000010000001100000000
+00000000011000010000110000000000
+00000000000110010011000000000000
+00000000000001111100000000000000
+00000000000001111100000000000000
+00000000000110010011000000000000
+00000000011000010000110000000000
+00000001100000010000001100000000
+00000110000000010000000011000000
+00011000000000010000000000110000
+01100000000000010000000000001100
+10000000000000010000000000000010
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
+00000000000000010000000000000000
--- /dev/null
+000111000
+011000110
+010000010
+100000001
+100000001
+100000001
+010000010
+011000110
+000111000
+
+00001110000
+00110001100
+01000000010
+01000000010
+10000000001
+10000000001
+10000000001
+01000000010
+01000000010
+00110001100
+00001110000
+
+0000111110000
+0001000001000
+0010000000100
+0100000000010
+0100000000010
+1000000000001
+1000000000001
+1000000000001
+0100000000010
+0100000000010
+0010000000100
+0001000001000
+0000111110000
+
+000001111100000
+000110000011000
+001000000000100
+010000000000010
+010000000000010
+100000000000001
+100000000000001
+100000000000001
+100000000000001
+100000000000001
+010000000000010
+010000000000010
+001000000000100
+000110000011000
+000001111100000
+
+00000011111000000
+00001100000110000
+00010000000001000
+00100000000000100
+01000000000000010
+01000000000000010
+10000000000000001
+10000000000000001
+10000000000000001
+10000000000000001
+10000000000000001
+01000000000000010
+01000000000000010
+00100000000000100
+00010000000001000
+00001100000110000
+00000011111000000
+
+0000000111110000000
+0000011000001100000
+0001100000000011000
+0010000000000000100
+0010000000000000100
+0100000000000000010
+0100000000000000010
+1000000000000000001
+1000000000000000001
+1000000000000000001
+1000000000000000001
+1000000000000000001
+0100000000000000010
+0100000000000000010
+0010000000000000100
+0010000000000000100
+0001100000000011000
+0000011000001100000
+0000000111110000000
+
+000000001111100000000
+000000110000011000000
+000011000000000110000
+000100000000000001000
+001000000000000000100
+001000000000000000100
+010000000000000000010
+010000000000000000010
+100000000000000000001
+100000000000000000001
+100000000000000000001
+100000000000000000001
+100000000000000000001
+010000000000000000010
+010000000000000000010
+001000000000000000100
+001000000000000000100
+000100000000000001000
+000011000000000110000
+000000110000011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100000111000000
+00000100000000000100000
+00011000000000000011000
+00010000000000000001000
+00100000000000000000100
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+10000000000000000000001
+10000000000000000000001
+10000000000000000000001
+10000000000000000000001
+10000000000000000000001
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+00100000000000000000100
+00010000000000000001000
+00011000000000000011000
+00000100000000000100000
+00000011100000111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111000001110000000
+0000011000000000001100000
+0000100000000000000010000
+0001000000000000000001000
+0010000000000000000000100
+0010000000000000000000100
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+1000000000000000000000001
+1000000000000000000000001
+1000000000000000000000001
+1000000000000000000000001
+1000000000000000000000001
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+0010000000000000000000100
+0010000000000000000000100
+0001000000000000000001000
+0000100000000000000010000
+0000011000000000001100000
+0000000111000001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110000011100000000
+000000110000000000011000000
+000001000000000000000100000
+000010000000000000000010000
+000100000000000000000001000
+001000000000000000000000100
+001000000000000000000000100
+010000000000000000000000010
+010000000000000000000000010
+010000000000000000000000010
+100000000000000000000000001
+100000000000000000000000001
+100000000000000000000000001
+100000000000000000000000001
+100000000000000000000000001
+010000000000000000000000010
+010000000000000000000000010
+010000000000000000000000010
+001000000000000000000000100
+001000000000000000000000100
+000100000000000000000001000
+000010000000000000000010000
+000001000000000000000100000
+000000110000000000011000000
+000000001110000011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100000111100000000
+00000001100000000000010000000
+00000010000000000000001100000
+00001100000000000000000010000
+00001000000000000000000001000
+00010000000000000000000001000
+00100000000000000000000000100
+00100000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+10000000000000000000000000001
+10000000000000000000000000001
+10000000000000000000000000001
+10000000000000000000000000001
+10000000000000000000000000001
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+00100000000000000000000000010
+00100000000000000000000000100
+00010000000000000000000001000
+00001000000000000000000001000
+00001100000000000000000110000
+00000010000000000000001000000
+00000001100000000000110000000
+00000000011100000111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111000001111000000000
+0000000010000000000000100000000
+0000001100000000000000011000000
+0000010000000000000000000100000
+0000100000000000000000000010000
+0001000000000000000000000001000
+0001000000000000000000000001000
+0010000000000000000000000000100
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+1000000000000000000000000000001
+1000000000000000000000000000001
+1000000000000000000000000000001
+1000000000000000000000000000001
+1000000000000000000000000000001
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0010000000000000000000000000100
+0001000000000000000000000001000
+0001000000000000000000000001000
+0000100000000000000000000010000
+0000010000000000000000000100000
+0000001100000000000000011000000
+0000000010000000000000100000000
+0000000001111000001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110000001110000000000
+00000000110000000000001100000000
+00000001000000000000000010000000
+00000110000000000000000001100000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00010000000000000000000000001000
+00100000000000000000000000000100
+00100000000000000000000000000100
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+10000000000000000000000000000001
+10000000000000000000000000000001
+10000000000000000000000000000001
+10000000000000000000000000000001
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+00100000000000000000000000000100
+00100000000000000000000000000100
+00010000000000000000000000001000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00000110000000000000000001100000
+00000001000000000000000010000000
+00000000110000000000001100000000
+00000000001110000001110000000000
+00000000000001111110000000000000
--- /dev/null
+100000001
+010000010
+001000100
+000101000
+000010000
+000101000
+001000100
+010000010
+100000001
+
+10000000001
+01000000010
+00100000100
+00010001000
+00001010000
+00000100000
+00001010000
+00010001000
+00100000100
+01000000010
+10000000001
+
+1000000000001
+0100000000010
+0010000000100
+0001000001000
+0000100010000
+0000010100000
+0000001000000
+0000010100000
+0000100010000
+0001000001000
+0010000000100
+0100000000010
+1000000000001
+
+100000000000001
+010000000000010
+001000000000100
+000100000001000
+000010000010000
+000001000100000
+000000101000000
+000000010000000
+000000101000000
+000001000100000
+000010000010000
+000100000001000
+001000000000100
+010000000000010
+100000000000001
+
+10000000000000001
+01000000000000010
+00100000000000100
+00010000000001000
+00001000000010000
+00000100000100000
+00000010001000000
+00000001010000000
+00000000100000000
+00000001010000000
+00000010001000000
+00000100000100000
+00001000000010000
+00010000000001000
+00100000000000100
+01000000000000010
+10000000000000001
+
+1000000000000000001
+0100000000000000010
+0010000000000000100
+0001000000000001000
+0000100000000010000
+0000010000000100000
+0000001000001000000
+0000000100010000000
+0000000010100000000
+0000000001000000000
+0000000010100000000
+0000000100010000000
+0000001000001000000
+0000010000000100000
+0000100000000010000
+0001000000000001000
+0010000000000000100
+0100000000000000010
+1000000000000000001
+
+100000000000000000001
+010000000000000000010
+001000000000000000100
+000100000000000001000
+000010000000000010000
+000001000000000100000
+000000100000001000000
+000000010000010000000
+000000001000100000000
+000000000101000000000
+000000000010000000000
+000000000101000000000
+000000001000100000000
+000000010000010000000
+000000100000001000000
+000001000000000100000
+000010000000000010000
+000100000000000001000
+001000000000000000100
+010000000000000000010
+100000000000000000001
+
+10000000000000000000001
+01000000000000000000010
+00100000000000000000100
+00010000000000000001000
+00001000000000000010000
+00000100000000000100000
+00000010000000001000000
+00000001000000010000000
+00000000100000100000000
+00000000010001000000000
+00000000001010000000000
+00000000000100000000000
+00000000001010000000000
+00000000010001000000000
+00000000100000100000000
+00000001000000010000000
+00000010000000001000000
+00000100000000000100000
+00001000000000000010000
+00010000000000000001000
+00100000000000000000100
+01000000000000000000010
+10000000000000000000001
+
+1000000000000000000000001
+0100000000000000000000010
+0010000000000000000000100
+0001000000000000000001000
+0000100000000000000010000
+0000010000000000000100000
+0000001000000000001000000
+0000000100000000010000000
+0000000010000000100000000
+0000000001000001000000000
+0000000000100010000000000
+0000000000010100000000000
+0000000000001000000000000
+0000000000010100000000000
+0000000000100010000000000
+0000000001000001000000000
+0000000010000000100000000
+0000000100000000010000000
+0000001000000000001000000
+0000010000000000000100000
+0000100000000000000010000
+0001000000000000000001000
+0010000000000000000000100
+0100000000000000000000010
+1000000000000000000000001
+
+100000000000000000000000001
+010000000000000000000000010
+001000000000000000000000100
+000100000000000000000001000
+000010000000000000000010000
+000001000000000000000100000
+000000100000000000001000000
+000000010000000000010000000
+000000001000000000100000000
+000000000100000001000000000
+000000000010000010000000000
+000000000001000100000000000
+000000000000101000000000000
+000000000000010000000000000
+000000000000101000000000000
+000000000001000100000000000
+000000000010000010000000000
+000000000100000001000000000
+000000001000000000100000000
+000000010000000000010000000
+000000100000000000001000000
+000001000000000000000100000
+000010000000000000000010000
+000100000000000000000001000
+001000000000000000000000100
+010000000000000000000000010
+100000000000000000000000001
+
+10000000000000000000000000001
+01000000000000000000000000010
+00100000000000000000000000100
+00010000000000000000000001000
+00001000000000000000000010000
+00000100000000000000000100000
+00000010000000000000001000000
+00000001000000000000010000000
+00000000100000000000100000000
+00000000010000000001000000000
+00000000001000000010000000000
+00000000000100000100000000000
+00000000000010001000000000000
+00000000000001010000000000000
+00000000000000100000000000000
+00000000000001010000000000000
+00000000000010001000000000000
+00000000000100000100000000000
+00000000001000000010000000000
+00000000010000000001000000000
+00000000100000000000100000000
+00000001000000000000010000000
+00000010000000000000001000000
+00000100000000000000000100000
+00001000000000000000000010000
+00010000000000000000000001000
+00100000000000000000000000100
+01000000000000000000000000010
+10000000000000000000000000001
+
+1000000000000000000000000000001
+0100000000000000000000000000010
+0010000000000000000000000000100
+0001000000000000000000000001000
+0000100000000000000000000010000
+0000010000000000000000000100000
+0000001000000000000000001000000
+0000000100000000000000010000000
+0000000010000000000000100000000
+0000000001000000000001000000000
+0000000000100000000010000000000
+0000000000010000000100000000000
+0000000000001000001000000000000
+0000000000000100010000000000000
+0000000000000010100000000000000
+0000000000000001000000000000000
+0000000000000010100000000000000
+0000000000000100010000000000000
+0000000000001000001000000000000
+0000000000010000000100000000000
+0000000000100000000010000000000
+0000000001000000000001000000000
+0000000010000000000000100000000
+0000000100000000000000010000000
+0000001000000000000000001000000
+0000010000000000000000000100000
+0000100000000000000000000010000
+0001000000000000000000000001000
+0010000000000000000000000000100
+0100000000000000000000000000010
+1000000000000000000000000000001
+
+10000000000000000000000000000001
+01000000000000000000000000000010
+00100000000000000000000000000100
+00010000000000000000000000001000
+00001000000000000000000000010000
+00000100000000000000000000100000
+00000010000000000000000001000000
+00000001000000000000000010000000
+00000000100000000000000100000000
+00000000010000000000001000000000
+00000000001000000000010000000000
+00000000000100000000100000000000
+00000000000010000001000000000000
+00000000000001000010000000000000
+00000000000000100100000000000000
+00000000000000011000000000000000
+00000000000000011000000000000000
+00000000000000100100000000000000
+00000000000001000010000000000000
+00000000000010000001000000000000
+00000000000100000000100000000000
+00000000001000000000010000000000
+00000000010000000000001000000000
+00000000100000000000000100000000
+00000001000000000000000010000000
+00000010000000000000000001000000
+00000100000000000000000000100000
+00001000000000000000000000010000
+00010000000000000000000000001000
+00100000000000000000000000000100
+01000000000000000000000000000010
+10000000000000000000000000000001
--- /dev/null
+000111000
+011000110
+010000010
+100000001
+100010001
+100000001
+010000010
+011000110
+000111000
+
+00001110000
+00110001100
+01000000010
+01000000010
+10000110001
+10000110001
+10000000001
+01000000010
+01000000010
+00110001100
+00001110000
+
+0000111110000
+0001000001000
+0010000000100
+0100000000010
+0100000000010
+1000001100001
+1000001100001
+1000000000001
+0100000000010
+0100000000010
+0010000000100
+0001000001000
+0000111110000
+
+000001111100000
+000110000011000
+001000000000100
+010000000000010
+010000000000010
+100000000000001
+100000011000001
+100000011000001
+100000000000001
+100000000000001
+010000000000010
+010000000000010
+001000000000100
+000110000011000
+000001111100000
+
+00000011111000000
+00001100000110000
+00010000000001000
+00100000000000100
+01000000000000010
+01000000000000010
+10000000000000001
+10000001110000001
+10000001110000001
+10000001110000001
+10000000000000001
+01000000000000010
+01000000000000010
+00100000000000100
+00010000000001000
+00001100000110000
+00000011111000000
+
+0000000111110000000
+0000011000001100000
+0001100000000011000
+0010000000000000100
+0010000000000000100
+0100000000000000010
+0100000000000000010
+1000000011110000001
+1000000011110000001
+1000000011110000001
+1000000011110000001
+1000000000000000001
+0100000000000000010
+0100000000000000010
+0010000000000000100
+0010000000000000100
+0001100000000011000
+0000011000001100000
+0000000111110000000
+
+000000001111100000000
+000000110000011000000
+000011000000000110000
+000100000000000001000
+001000000000000000100
+001000000000000000100
+010000000000000000010
+010000000000000000010
+100000000111100000001
+100000000111100000001
+100000000111100000001
+100000000111100000001
+100000000000000000001
+010000000000000000010
+010000000000000000010
+001000000000000000100
+001000000000000000100
+000100000000000001000
+000011000000000110000
+000000110000011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100000111000000
+00000100000000000100000
+00011000000000000011000
+00010000000000000001000
+00100000000000000000100
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+10000000001111000000001
+10000000001111000000001
+10000000001111000000001
+10000000001111000000001
+10000000000000000000001
+01000000000000000000010
+01000000000000000000010
+01000000000000000000010
+00100000000000000000100
+00010000000000000001000
+00011000000000000011000
+00000100000000000100000
+00000011100000111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111000001110000000
+0000011000000000001100000
+0000100000000000000010000
+0001000000000000000001000
+0010000000000000000000100
+0010000000000000000000100
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+1000000000111110000000001
+1000000000111110000000001
+1000000000111110000000001
+1000000000111110000000001
+1000000000111110000000001
+0100000000000000000000010
+0100000000000000000000010
+0100000000000000000000010
+0010000000000000000000100
+0010000000000000000000100
+0001000000000000000001000
+0000100000000000000010000
+0000011000000000001100000
+0000000111000001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110000011100000000
+000000110000000000011000000
+000001000000000000000100000
+000010000000000000000010000
+000100000000000000000001000
+001000000000000000000000100
+001000000000000000000000100
+010000000000000000000000010
+010000000000000000000000010
+010000000001111110000000010
+100000000001111110000000001
+100000000001111110000000001
+100000000001111110000000001
+100000000001111110000000001
+100000000001111110000000001
+010000000000000000000000010
+010000000000000000000000010
+010000000000000000000000010
+001000000000000000000000100
+001000000000000000000000100
+000100000000000000000001000
+000010000000000000000010000
+000001000000000000000100000
+000000110000000000011000000
+000000001110000011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100000111100000000
+00000001100000000000010000000
+00000010000000000000001100000
+00001100000000000000000010000
+00001000000000000000000001000
+00010000000000000000000001000
+00100000000000000000000000100
+00100000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000011111100000000010
+10000000000011111100000000001
+10000000000011111100000000001
+10000000000011111100000000001
+10000000000011111100000000001
+10000000000011111100000000001
+01000000000000000000000000010
+01000000000000000000000000010
+01000000000000000000000000010
+00100000000000000000000000010
+00100000000000000000000000100
+00010000000000000000000001000
+00001000000000000000000001000
+00001100000000000000000110000
+00000010000000000000001000000
+00000001100000000000110000000
+00000000011100000111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111000001111000000000
+0000000010000000000000100000000
+0000001100000000000000011000000
+0000010000000000000000000100000
+0000100000000000000000000010000
+0001000000000000000000000001000
+0001000000000000000000000001000
+0010000000000000000000000000100
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000111111000000000010
+1000000000000111111000000000001
+1000000000000111111000000000001
+1000000000000111111000000000001
+1000000000000111111000000000001
+1000000000000111111000000000001
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0100000000000000000000000000010
+0010000000000000000000000000100
+0001000000000000000000000001000
+0001000000000000000000000001000
+0000100000000000000000000010000
+0000010000000000000000000100000
+0000001100000000000000011000000
+0000000010000000000000100000000
+0000000001111000001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110000001110000000000
+00000000110000000000001100000000
+00000001000000000000000010000000
+00000110000000000000000001100000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00010000000000000000000000001000
+00100000000000000000000000000100
+00100000000000000000000000000100
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000001111111000000000010
+01000000000001111111000000000010
+10000000000001111111000000000001
+10000000000001111111000000000001
+10000000000001111111000000000001
+10000000000001111111000000000001
+01000000000001111111000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+01000000000000000000000000000010
+00100000000000000000000000000100
+00100000000000000000000000000100
+00010000000000000000000000001000
+00001000000000000000000000010000
+00001000000000000000000000010000
+00000110000000000000000001100000
+00000001000000000000000010000000
+00000000110000000000001100000000
+00000000001110000001110000000000
+00000000000001111110000000000000
--- /dev/null
+000111000
+011010110
+010010010
+100010001
+111111111
+100010001
+010010010
+011010110
+000111000
+
+00001110000
+00110101100
+01000100010
+01000100010
+10000100001
+11111111111
+10000100001
+01000100010
+01000100010
+00110101100
+00001110000
+
+0000111110000
+0001001001000
+0010001000100
+0100001000010
+0100001000010
+1000001000001
+1111111111111
+1000001000001
+0100001000010
+0100001000010
+0010001000100
+0001001001000
+0000111110000
+
+000001111100000
+000110010011000
+001000010000100
+010000010000010
+010000010000010
+100000010000001
+100000010000001
+111111111111111
+100000010000001
+100000010000001
+010000010000010
+010000010000010
+001000010000100
+000110010011000
+000001111100000
+
+00000011111000000
+00001100100110000
+00010000100001000
+00100000100000100
+01000000100000010
+01000000100000010
+10000000100000001
+10000000100000001
+11111111111111111
+10000000100000001
+10000000100000001
+01000000100000010
+01000000100000010
+00100000100000100
+00010000100001000
+00001100100110000
+00000011111000000
+
+0000000111110000000
+0000011001001100000
+0001100001000011000
+0010000001000000100
+0010000001000000100
+0100000001000000010
+0100000001000000010
+1000000001000000001
+1000000001000000001
+1111111111111111111
+1000000001000000001
+1000000001000000001
+0100000001000000010
+0100000001000000010
+0010000001000000100
+0010000001000000100
+0001100001000011000
+0000011001001100000
+0000000111110000000
+
+000000001111100000000
+000000110010011000000
+000011000010000110000
+000100000010000001000
+001000000010000000100
+001000000010000000100
+010000000010000000010
+010000000010000000010
+100000000010000000001
+100000000010000000001
+111111111111111111111
+100000000010000000001
+100000000010000000001
+010000000010000000010
+010000000010000000010
+001000000010000000100
+001000000010000000100
+000100000010000001000
+000011000010000110000
+000000110010011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100100111000000
+00000100000100000100000
+00011000000100000011000
+00010000000100000001000
+00100000000100000000100
+01000000000100000000010
+01000000000100000000010
+01000000000100000000010
+10000000000100000000001
+10000000000100000000001
+11111111111111111111111
+10000000000100000000001
+10000000000100000000001
+01000000000100000000010
+01000000000100000000010
+01000000000100000000010
+00100000000100000000100
+00010000000100000001000
+00011000000100000011000
+00000100000100000100000
+00000011100100111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111001001110000000
+0000011000001000001100000
+0000100000001000000010000
+0001000000001000000001000
+0010000000001000000000100
+0010000000001000000000100
+0100000000001000000000010
+0100000000001000000000010
+0100000000001000000000010
+1000000000001000000000001
+1000000000001000000000001
+1111111111111111111111111
+1000000000001000000000001
+1000000000001000000000001
+0100000000001000000000010
+0100000000001000000000010
+0100000000001000000000010
+0010000000001000000000100
+0010000000001000000000100
+0001000000001000000001000
+0000100000001000000010000
+0000011000001000001100000
+0000000111001001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110010011100000000
+000000110000010000011000000
+000001000000010000000100000
+000010000000010000000010000
+000100000000010000000001000
+001000000000010000000000100
+001000000000010000000000100
+010000000000010000000000010
+010000000000010000000000010
+010000000000010000000000010
+100000000000010000000000001
+100000000000010000000000001
+111111111111111111111111111
+100000000000010000000000001
+100000000000010000000000001
+010000000000010000000000010
+010000000000010000000000010
+010000000000010000000000010
+001000000000010000000000100
+001000000000010000000000100
+000100000000010000000001000
+000010000000010000000010000
+000001000000010000000100000
+000000110000010000011000000
+000000001110010011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100100111100000000
+00000001100000100000010000000
+00000010000000100000001100000
+00001100000000100000000010000
+00001000000000100000000001000
+00010000000000100000000001000
+00100000000000100000000000100
+00100000000000100000000000010
+01000000000000100000000000010
+01000000000000100000000000010
+01000000000000100000000000010
+10000000000000100000000000001
+10000000000000100000000000001
+11111111111111111111111111111
+10000000000000100000000000001
+10000000000000100000000000001
+01000000000000100000000000010
+01000000000000100000000000010
+01000000000000100000000000010
+00100000000000100000000000010
+00100000000000100000000000100
+00010000000000100000000001000
+00001000000000100000000001000
+00001100000000100000000110000
+00000010000000100000001000000
+00000001100000100000110000000
+00000000011100100111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111001001111000000000
+0000000010000001000000100000000
+0000001100000001000000011000000
+0000010000000001000000000100000
+0000100000000001000000000010000
+0001000000000001000000000001000
+0001000000000001000000000001000
+0010000000000001000000000000100
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+1000000000000001000000000000001
+1000000000000001000000000000001
+1111111111111111111111111111111
+1000000000000001000000000000001
+1000000000000001000000000000001
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+0100000000000001000000000000010
+0010000000000001000000000000100
+0001000000000001000000000001000
+0001000000000001000000000001000
+0000100000000001000000000010000
+0000010000000001000000000100000
+0000001100000001000000011000000
+0000000010000001000000100000000
+0000000001111001001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110010001110000000000
+00000000110000010000001100000000
+00000001000000010000000010000000
+00000110000000010000000001100000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00010000000000010000000000001000
+00100000000000010000000000000100
+00100000000000010000000000000100
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+10000000000000010000000000000001
+11111111111111111111111111111111
+10000000000000010000000000000001
+10000000000000010000000000000001
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+01000000000000010000000000000010
+00100000000000010000000000000100
+00100000000000010000000000000100
+00010000000000010000000000001000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00000110000000010000000001100000
+00000001000000010000000010000000
+00000000110000010000001100000000
+00000000001110010001110000000000
+00000000000001111110000000000000
--- /dev/null
+000111000
+011010110
+110010011
+101111101
+100010001
+101111101
+110010011
+011010110
+000111000
+
+00001110000
+00110101100
+11000100011
+01100100110
+10011111001
+10000100001
+10011111001
+01100100110
+11000100011
+00110101100
+00001110000
+
+0000111110000
+0001001001000
+0010001000100
+1100001000011
+0111001001110
+1000111110001
+1000001000001
+1000111110001
+0111001001110
+1100001000011
+0010001000100
+0001001001000
+0000111110000
+
+000001111100000
+000110010011000
+001000010000100
+110000010000011
+011000010000110
+100110010011001
+100001111100001
+100000010000001
+100001111100001
+100110010011001
+011000010000110
+110000010000011
+001000010000100
+000110010011000
+000001111100000
+
+00000011111000000
+00001100100110000
+00010000100001000
+00100000100000100
+11000000100000011
+01110000100001110
+10001100100110001
+10000011111000001
+10000000100000001
+10000011111000001
+10001100100110001
+01110000100001110
+11000000100000011
+00100000100000100
+00010000100001000
+00001100100110000
+00000011111000000
+
+0000000111110000000
+0000011001001100000
+0001100001000011000
+0010000001000000100
+1010000001000000101
+0110000001000000110
+0101100001000011010
+1000011001001100001
+1000000111110000001
+1000000001000000001
+1000000111110000001
+1000011001001100001
+0101100001000011010
+0110000001000000110
+1010000001000000101
+0010000001000000100
+0001100001000011000
+0000011001001100000
+0000000111110000000
+
+000000001111100000000
+000000110010011000000
+000011000010000110000
+000100000010000001000
+001000000010000000100
+111000000010000000111
+011100000010000001110
+010011000010000110010
+100000110010011000001
+100000001111100000001
+100000000010000000001
+100000001111100000001
+100000110010011000001
+010011000010000110010
+011100000010000001110
+111000000010000000111
+001000000010000000100
+000100000010000001000
+000011000010000110000
+000000110010011000000
+000000001111100000000
+
+00000000011111000000000
+00000011100100111000000
+00000100000100000100000
+00011000000100000011000
+00010000000100000001000
+10100000000100000000101
+01100000000100000000110
+01011000000100000011010
+01000110000100001100010
+10000001100100110000001
+10000000011111000000001
+10000000000100000000001
+10000000011111000000001
+10000001100100110000001
+01000110000100001100010
+01011000000100000011010
+01100000000100000000110
+10100000000100000000101
+00010000000100000001000
+00011000000100000011000
+00000100000100000100000
+00000011100100111000000
+00000000011111000000000
+
+0000000000111110000000000
+0000000111001001110000000
+0000011000001000001100000
+0000100000001000000010000
+0001000000001000000001000
+0010000000001000000000100
+1110000000001000000000111
+0111000000001000000001110
+0100110000001000000110010
+0100001100001000011000010
+1000000011001001100000001
+1000000000111110000000001
+1000000000001000000000001
+1000000000111110000000001
+1000000011001001100000001
+0100001100001000011000010
+0100110000001000000110010
+0111000000001000000001110
+1110000000001000000000111
+0010000000001000000000100
+0001000000001000000001000
+0000100000001000000010000
+0000011000001000001100000
+0000000111001001110000000
+0000000000111110000000000
+
+000000000001111100000000000
+000000001110010011100000000
+000000110000010000011000000
+000001000000010000000100000
+000010000000010000000010000
+000100000000010000000001000
+101000000000010000000000101
+011000000000010000000000110
+010110000000010000000011010
+010001100000010000001100010
+010000011000010000110000010
+100000000110010011000000001
+100000000001111100000000001
+100000000000010000000000001
+100000000001111100000000001
+100000000110010011000000001
+010000011000010000110000010
+010001100000010000001100010
+010110000000010000000011010
+011000000000010000000000110
+101000000000010000000000101
+000100000000010000000001000
+000010000000010000000010000
+000001000000010000000100000
+000000110000010000011000000
+000000001110010011100000000
+000000000001111100000000000
+
+00000000000011111000000000000
+00000000011100100111100000000
+00000001100000100000010000000
+00000010000000100000001100000
+00001100000000100000000010000
+00001000000000100000000001000
+00010000000000100000000001000
+11100000000000100000000000111
+00110000000000100000000001110
+01001100000000100000000110010
+01000011000000100000011000010
+01000000110000100001100000010
+10000000001100100110000000001
+10000000000011111000000000001
+10000000000000100000000000001
+10000000000011111000000000001
+10000000001100100110000000001
+01000000110000100001100000010
+01000011000000100000011000010
+01001100000000100000000110010
+00110000000000100000000001110
+11100000000000100000000000111
+00010000000000100000000001000
+00001000000000100000000001000
+00001100000000100000000110000
+00000010000000100000001000000
+00000001100000100000110000000
+00000000011100100111000000000
+00000000000011111000000000000
+
+0000000000000111110000000000000
+0000000001111001001111000000000
+0000000010000001000000100000000
+0000001100000001000000011000000
+0000010000000001000000000100000
+0000100000000001000000000010000
+0001000000000001000000000001000
+1001000000000001000000000001001
+0110000000000001000000000000110
+0101100000000001000000000011010
+0100011000000001000000001100010
+0100000110000001000000110000010
+0100000001100001000011000000010
+1000000000011001001100000000001
+1000000000000111110000000000001
+1000000000000001000000000000001
+1000000000000111110000000000001
+1000000000011001001100000000001
+0100000001100001000011000000010
+0100000110000001000000110000010
+0100011000000001000000001100010
+0101100000000001000000000011010
+0110000000000001000000000000110
+1001000000000001000000000001001
+0001000000000001000000000001000
+0000100000000001000000000010000
+0000010000000001000000000100000
+0000001100000001000000011000000
+0000000010000001000000100000000
+0000000001111001001111000000000
+0000000000000111110000000000000
+
+00000000000001111110000000000000
+00000000001110010001110000000000
+00000000110000010000001100000000
+00000001000000010000000010000000
+00000110000000010000000001100000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00010000000000010000000000001000
+10100000000000010000000000000110
+01100000000000010000000000001100
+01011000000000010000000000110010
+01000110000000010000000011000010
+01000001100000010000001100000010
+01000000011000010000110000000010
+10000000000110010011000000000001
+10000000000001111100000000000001
+10000000000001111100000000000001
+10000000000110010011000000000001
+01000000011000010000110000000010
+01000001100000010000001100000010
+01000110000000010000000011000010
+01011000000000010000000000110010
+01100000000000010000000000001100
+10100000000000010000000000000110
+00010000000000010000000000001000
+00001000000000010000000000010000
+00001000000000010000000000010000
+00000110000000010000000001100000
+00000001000000010000000010000000
+00000000110000010000001100000000
+00000000001110010001110000000000
+00000000000001111110000000000000
--- /dev/null
+100111001
+011000110
+011000110
+100101001
+100010001
+100101001
+011000110
+011000110
+100111001
+
+10001110001
+01110001110
+01100000110
+01010001010
+10001010001
+10000100001
+10001010001
+01010001010
+01100000110
+01110001110
+10001110001
+
+1000111110001
+0101000001010
+0010000000100
+0101000001010
+0100100010010
+1000010100001
+1000001000001
+1000010100001
+0100100010010
+0101000001010
+0010000000100
+0101000001010
+1000111110001
+
+100001111100001
+010110000011010
+001000000000100
+010100000001010
+010010000010010
+100001000100001
+100000101000001
+100000010000001
+100000101000001
+100001000100001
+010010000010010
+010100000001010
+001000000000100
+010110000011010
+100001111100001
+
+10000011111000001
+01001100000110010
+00110000000001100
+00110000000001100
+01001000000010010
+01000100000100010
+10000010001000001
+10000001010000001
+10000000100000001
+10000001010000001
+10000010001000001
+01000100000100010
+01001000000010010
+00110000000001100
+00110000000001100
+01001100000110010
+10000011111000001
+
+1000000111110000001
+0100011000001100010
+0011100000000011100
+0011000000000001100
+0010100000000010100
+0100010000000100010
+0100001000001000010
+1000000100010000001
+1000000010100000001
+1000000001000000001
+1000000010100000001
+1000000100010000001
+0100001000001000010
+0100010000000100010
+0010100000000010100
+0011000000000001100
+0011100000000011100
+0100011000001100010
+1000000111110000001
+
+100000001111100000001
+010000110000011000010
+001011000000000110100
+000100000000000001000
+001010000000000010100
+001001000000000100100
+010000100000001000010
+010000010000010000010
+100000001000100000001
+100000000101000000001
+100000000010000000001
+100000000101000000001
+100000001000100000001
+010000010000010000010
+010000100000001000010
+001001000000000100100
+001010000000000010100
+000100000000000001000
+001011000000000110100
+010000110000011000010
+100000001111100000001
+
+10000000011111000000001
+01000011100000111000010
+00100100000000000100100
+00011000000000000011000
+00011000000000000011000
+00100100000000000100100
+01000010000000001000010
+01000001000000010000010
+01000000100000100000010
+10000000010001000000001
+10000000001010000000001
+10000000000100000000001
+10000000001010000000001
+10000000010001000000001
+01000000100000100000010
+01000001000000010000010
+01000010000000001000010
+00100100000000000100100
+00011000000000000011000
+00011000000000000011000
+00100100000000000100100
+01000011100000111000010
+10000000011111000000001
+
+1000000000111110000000001
+0100000111000001110000010
+0010011000000000001100100
+0001100000000000000011000
+0001100000000000000011000
+0010010000000000000100100
+0010001000000000001000100
+0100000100000000010000010
+0100000010000000100000010
+0100000001000001000000010
+1000000000100010000000001
+1000000000010100000000001
+1000000000001000000000001
+1000000000010100000000001
+1000000000100010000000001
+0100000001000001000000010
+0100000010000000100000010
+0100000100000000010000010
+0010001000000000001000100
+0010010000000000000100100
+0001100000000000000011000
+0001100000000000000011000
+0010011000000000001100100
+0100000111000001110000010
+1000000000111110000000001
+
+100000000001111100000000001
+010000001110000011100000010
+001000110000000000011000100
+000101000000000000000101000
+000010000000000000000010000
+000101000000000000000101000
+001000100000000000001000100
+001000010000000000010000100
+010000001000000000100000010
+010000000100000001000000010
+010000000010000010000000010
+100000000001000100000000001
+100000000000101000000000001
+100000000000010000000000001
+100000000000101000000000001
+100000000001000100000000001
+010000000010000010000000010
+010000000100000001000000010
+010000001000000000100000010
+001000010000000000010000100
+001000100000000000001000100
+000101000000000000000101000
+000010000000000000000010000
+000101000000000000000101000
+001000110000000000011000100
+010000001110000011100000010
+100000000001111100000000001
+
+10000000000011111000000000001
+01000000011100000111100000010
+00100001100000000000010000100
+00010010000000000000001101000
+00001100000000000000000010000
+00001100000000000000000101000
+00010010000000000000001001000
+00100001000000000000010000100
+00100000100000000000100000010
+01000000010000000001000000010
+01000000001000000010000000010
+01000000000100000100000000010
+10000000000010001000000000001
+10000000000001010000000000001
+10000000000000100000000000001
+10000000000001010000000000001
+10000000000010001000000000001
+01000000000100000100000000010
+01000000001000000010000000010
+01000000010000000001000000010
+00100000100000000000100000010
+00100001000000000000010000100
+00010010000000000000001001000
+00001100000000000000000101000
+00001100000000000000000110000
+00010010000000000000001001000
+00100001100000000000110000100
+01000000011100000111000000010
+10000000000011111000000000001
+
+1000000000000111110000000000001
+0100000001111000001111000000010
+0010000010000000000000100000100
+0001001100000000000000011001000
+0000110000000000000000000110000
+0000110000000000000000000110000
+0001001000000000000000001001000
+0001000100000000000000010001000
+0010000010000000000000100000100
+0100000001000000000001000000010
+0100000000100000000010000000010
+0100000000010000000100000000010
+0100000000001000001000000000010
+1000000000000100010000000000001
+1000000000000010100000000000001
+1000000000000001000000000000001
+1000000000000010100000000000001
+1000000000000100010000000000001
+0100000000001000001000000000010
+0100000000010000000100000000010
+0100000000100000000010000000010
+0100000001000000000001000000010
+0010000010000000000000100000100
+0001000100000000000000010001000
+0001001000000000000000001001000
+0000110000000000000000000110000
+0000110000000000000000000110000
+0001001100000000000000011001000
+0010000010000000000000100000100
+0100000001111000001111000000010
+1000000000000111110000000000001
+
+10000000000001111110000000000001
+01000000001110000001110000000010
+00100000110000000000001100000100
+00010001000000000000000010001000
+00001110000000000000000001110000
+00001100000000000000000000110000
+00001010000000000000000001010000
+00010001000000000000000010001000
+00100000100000000000000100000100
+00100000010000000000001000000100
+01000000001000000000010000000010
+01000000000100000000100000000010
+01000000000010000001000000000010
+01000000000001000010000000000010
+10000000000000100100000000000001
+10000000000000011000000000000001
+10000000000000011000000000000001
+10000000000000100100000000000001
+01000000000001000010000000000010
+01000000000010000001000000000010
+01000000000100000000100000000010
+01000000001000000000010000000010
+00100000010000000000001000000100
+00100000100000000000000100000100
+00010001000000000000000010001000
+00001010000000000000000001010000
+00001100000000000000000000110000
+00001110000000000000000001110000
+00010001000000000000000010001000
+00100000110000000000001100000100
+01000000001110000001110000000010
+10000000000001111110000000000001
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+lib_LTLIBRARIES = libViewerTools.la
+
+salomeinclude_HEADERS= \
+ ViewerTools.h \
+ ViewerTools_CubeAxesDlgBase.h \
+ ViewerTools_DialogBase.h \
+ ViewerTools_FontWidgetBase.h
+
+dist_libViewerTools_la_SOURCES= \
+ ViewerTools_CubeAxesDlgBase.cxx \
+ ViewerTools_DialogBase.cxx \
+ ViewerTools_FontWidgetBase.cxx
+
+MOC_FILES= \
+ ViewerTools_CubeAxesDlgBase_moc.cxx \
+ ViewerTools_DialogBase_moc.cxx \
+ ViewerTools_FontWidgetBase_moc.cxx
+
+nodist_libViewerTools_la_SOURCES= $(MOC_FILES)
+
+nodist_salomeres_DATA = \
+ ViewerTools_msg_en.qm \
+ ViewerTools_msg_fr.qm
+
+libViewerTools_la_CPPFLAGS = \
+ $(QT_INCLUDES) \
+ -I$(srcdir)/../Qtx
+
+libViewerTools_la_LDFLAGS = \
+ $(QT_MT_LIBS)
+
+libViewerTools_la_LIBADD = ../Qtx/libqtx.la
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_H
+#define VIEWERTOOLS_H
+
+#ifdef WIN32
+# if defined VIEWERTOOLS_EXPORTS || defined ViewerTools_EXPORTS
+# define VIEWERTOOLS_EXPORT __declspec(dllexport)
+# else
+# define VIEWERTOOLS_EXPORT __declspec(dllimport)
+# endif
+#else
+# define VIEWERTOOLS_EXPORT
+#endif
+
+#if defined WIN32
+#pragma warning ( disable: 4251 )
+#pragma warning ( disable: 4786 )
+#endif
+
+#endif
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ViewerTools_CubeAxesDlgBase.h"
+
+#include "ViewerTools_FontWidgetBase.h"
+
+#include "QtxAction.h"
+#include "QtxIntSpinBox.h"
+
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QTabWidget>
+#include <QCheckBox>
+#include <QGroupBox>
+#include <QLineEdit>
+#include <QLabel>
+
+/*!
+ * Class : ViewerTools_AxisWidgetBase
+ * Description : Axis tab widget of the "Graduated axis" dialog box
+*/
+
+/*!
+ Constructor
+*/
+ViewerTools_AxisWidgetBase::ViewerTools_AxisWidgetBase (QWidget* theParent)
+: QFrame(theParent)
+{
+}
+
+/*!
+ Destructor
+*/
+ViewerTools_AxisWidgetBase::~ViewerTools_AxisWidgetBase()
+{
+}
+
+/*!
+ Initialize controls
+*/
+void ViewerTools_AxisWidgetBase::initialize()
+{
+ QList< QLabel* > aLabels;
+
+ // "Name" grp
+
+ myNameGrp = new QGroupBox(ViewerTools_CubeAxesDlgBase::tr("AXIS_NAME"), this);
+ myNameGrp->setCheckable( true );
+
+ QVBoxLayout* aVBox = new QVBoxLayout;
+
+ QHBoxLayout* aHBox = new QHBoxLayout;
+ aHBox->setSpacing(5);
+ QLabel* aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("NAME"));
+ aHBox->addWidget(aLabel);
+ myAxisName = new QLineEdit;
+ aHBox->addWidget(myAxisName);
+ aLabels.append(aLabel);
+ aVBox->addLayout(aHBox);
+
+ aHBox = new QHBoxLayout;
+ aHBox->setSpacing(5);
+ aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("FONT"));
+ aHBox->addWidget(aLabel);
+ myNameFont = createFontWidget(myNameGrp);
+ aHBox->addWidget(myNameFont);
+ aLabels.append(aLabel);
+ aVBox->addLayout(aHBox);
+
+ myNameGrp->setLayout(aVBox);
+
+ // "Labels" grp
+
+ myLabelsGrp = new QGroupBox(ViewerTools_CubeAxesDlgBase::tr("LABELS"), this);
+ myLabelsGrp->setCheckable( true );
+
+ aVBox = new QVBoxLayout;
+
+ aHBox = new QHBoxLayout;
+ aHBox->setSpacing(5);
+ aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("NUMBER"));
+ aHBox->addWidget(aLabel);
+ myLabelNumber = new QtxIntSpinBox(2,25,1,myLabelsGrp);
+ aHBox->addWidget(myLabelNumber);
+ aLabels.append(aLabel);
+ aVBox->addLayout(aHBox);
+
+ aHBox = new QHBoxLayout;
+ aHBox->setSpacing(5);
+ aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("OFFSET"));
+ aHBox->addWidget(aLabel);
+ myLabelOffset = new QtxIntSpinBox(0,100,1,myLabelsGrp);
+ aHBox->addWidget(myLabelOffset);
+ aLabels.append(aLabel);
+ aVBox->addLayout(aHBox);
+
+ aHBox = new QHBoxLayout;
+ aHBox->setSpacing(5);
+ aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("FONT"));
+ aHBox->addWidget(aLabel);
+ myLabelsFont = createFontWidget(myLabelsGrp);
+ aHBox->addWidget(myLabelsFont);
+ aLabels.append(aLabel);
+ aVBox->addLayout(aHBox);
+
+ myLabelsGrp->setLayout(aVBox);
+
+ // "Tick marks" grp
+
+ myTicksGrp = new QGroupBox(ViewerTools_CubeAxesDlgBase::tr("TICK_MARKS"), this);
+ myTicksGrp->setCheckable( true );
+
+ aVBox = new QVBoxLayout;
+
+ aHBox = new QHBoxLayout;
+ aHBox->setSpacing(5);
+ aLabel = new QLabel(ViewerTools_CubeAxesDlgBase::tr("LENGTH"));
+ aHBox->addWidget(aLabel);
+ myTickLength = new QtxIntSpinBox(0,100,1,myTicksGrp);
+ aHBox->addWidget(myTickLength);
+ aLabels.append(aLabel);
+ aVBox->addLayout(aHBox);
+
+ myTicksGrp->setLayout(aVBox);
+
+ // Layout
+
+ QVBoxLayout* aLay = new QVBoxLayout(this);
+ aLay->setMargin(5);
+ aLay->setSpacing(5);
+ aLay->addWidget(myNameGrp);
+ aLay->addWidget(myLabelsGrp);
+ aLay->addWidget(myTicksGrp);
+
+ // init
+ myNameGrp->setChecked( true );
+ myLabelsGrp->setChecked( true );
+ myTicksGrp->setChecked( true );
+
+ // Adjust label widths
+ QList< QLabel* >::iterator anIter;
+ int aMaxWidth = 0;
+ for (anIter = aLabels.begin(); anIter != aLabels.end(); anIter++)
+ aMaxWidth = qMax(aMaxWidth, (*anIter)->sizeHint().width());
+ for (anIter = aLabels.begin(); anIter != aLabels.end(); anIter++)
+ (*anIter)->setFixedWidth(aMaxWidth);
+}
+
+void ViewerTools_AxisWidgetBase::UseName(const bool toUse)
+{
+ myNameGrp->setChecked(toUse);
+}
+
+void ViewerTools_AxisWidgetBase::SetName(const QString& theName)
+{
+ myAxisName->setText(theName);
+}
+
+void ViewerTools_AxisWidgetBase::SetNameFont(const QColor& theColor,
+ const int theFont,
+ const bool theIsBold,
+ const bool theIsItalic,
+ const bool theIsShadow)
+{
+ myNameFont->SetData(theColor, theFont, theIsBold, theIsItalic, theIsShadow);
+}
+
+/*
+ Class : ViewerTools_CubeAxesDlgBase
+ Description : Dialog for specifying cube axes properties
+*/
+
+/*!
+ Constructor
+*/
+ViewerTools_CubeAxesDlgBase::ViewerTools_CubeAxesDlgBase(QtxAction* theAction,
+ QWidget* theParent,
+ const char* theName):
+ ViewerTools_DialogBase(theAction,
+ theParent,
+ theName)
+{
+ setWindowTitle(tr("CAPTION"));
+}
+
+/*!
+ Initialize controls
+*/
+void ViewerTools_CubeAxesDlgBase::initialize()
+{
+ QVBoxLayout* aLay = new QVBoxLayout(this);
+ aLay->setMargin(5);
+ aLay->setSpacing(5);
+ aLay->addWidget(createMainFrame(this));
+ aLay->addWidget(createButtonFrame(this));
+}
+
+/*!
+ Create frame containing dialog's input fields
+*/
+QWidget* ViewerTools_CubeAxesDlgBase::createMainFrame(QWidget* theParent)
+{
+ QFrame* aFrame = new QFrame(theParent);
+
+ myTabWg = new QTabWidget(aFrame);
+
+ myAxes[ 0 ] = createAxisWidget(myTabWg);
+ myAxes[ 1 ] = createAxisWidget(myTabWg);
+ myAxes[ 2 ] = createAxisWidget(myTabWg);
+
+ myTabWg->addTab(myAxes[ 0 ], tr("X_AXIS"));
+ myTabWg->addTab(myAxes[ 1 ], tr("Y_AXIS"));
+ myTabWg->addTab(myAxes[ 2 ], tr("Z_AXIS"));
+
+ myIsVisible = new QCheckBox(tr("IS_VISIBLE"), aFrame);
+
+ QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+ aLay->setMargin(0);
+ aLay->setSpacing(5);
+ aLay->addWidget(myTabWg);
+ aLay->addWidget(myIsVisible);
+
+ return aFrame;
+}
+
+/*!
+ Create frame containing buttons
+*/
+QWidget* ViewerTools_CubeAxesDlgBase::createButtonFrame(QWidget* theParent)
+{
+ QFrame* aFrame = new QFrame(theParent);
+ aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
+
+ myOkBtn = new QPushButton(tr("BUT_OK"), aFrame);
+ myApplyBtn = new QPushButton(tr("BUT_APPLY"), aFrame);
+ myCloseBtn = new QPushButton(tr("BUT_CLOSE"), aFrame);
+
+ QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ QHBoxLayout* aLay = new QHBoxLayout(aFrame);
+ aLay->setMargin(5);
+ aLay->setSpacing(5);
+
+ aLay->addWidget(myOkBtn);
+ aLay->addWidget(myApplyBtn);
+ aLay->addItem(aSpacer);
+ aLay->addWidget(myCloseBtn);
+
+ connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk()));
+ connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
+ connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
+
+ return aFrame;
+}
+
+/*!
+ Destructor
+*/
+ViewerTools_CubeAxesDlgBase::~ViewerTools_CubeAxesDlgBase()
+{
+}
+
+/*!
+ Update dialog fields, connect signals and slots, show dialog
+*/
+void ViewerTools_CubeAxesDlgBase::Update()
+{
+}
+
+/*!
+ Verify validity of entry data
+*/
+bool ViewerTools_CubeAxesDlgBase::isValid() const
+{
+ return true;
+}
+
+/*!
+ Verify validity of entry data
+*/
+bool ViewerTools_CubeAxesDlgBase::onApply()
+{
+ return true;
+}
+
+/*!
+ SLOT called when "Ok" button pressed.
+*/
+void ViewerTools_CubeAxesDlgBase::onOk()
+{
+ if (onApply())
+ onClose();
+}
+
+/*!
+ SLOT: called when "Close" button pressed. Close dialog
+*/
+void ViewerTools_CubeAxesDlgBase::onClose()
+{
+ reject();
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_CUBEAXESDLGBASE_H
+#define VIEWERTOOLS_CUBEAXESDLGBASE_H
+
+#include "ViewerTools_DialogBase.h"
+
+#include <QFrame>
+
+class QWidget;
+class QPushButton;
+class QTabWidget;
+class QCheckBox;
+class QGroupBox;
+class QLineEdit;
+
+class QtxAction;
+class QtxIntSpinBox;
+
+class ViewerTools_FontWidgetBase;
+
+/*!
+ * Class : ViewerTools_AxisWidgetBase
+ * Description : Axis tab widget of the "Graduated axis" dialog box
+*/
+class VIEWERTOOLS_EXPORT ViewerTools_AxisWidgetBase : public QFrame
+{
+public:
+ ViewerTools_AxisWidgetBase( QWidget* );
+ ~ViewerTools_AxisWidgetBase();
+
+ void UseName( const bool );
+ void SetName( const QString& );
+ void SetNameFont( const QColor&, const int, const bool, const bool, const bool );
+
+public:
+ virtual void initialize();
+
+protected:
+ virtual ViewerTools_FontWidgetBase* createFontWidget( QWidget* ) = 0;
+
+protected:
+ // name
+ QGroupBox* myNameGrp;
+ QLineEdit* myAxisName;
+ ViewerTools_FontWidgetBase* myNameFont;
+
+ // labels
+ QGroupBox* myLabelsGrp;
+ QtxIntSpinBox* myLabelNumber;
+ QtxIntSpinBox* myLabelOffset;
+ ViewerTools_FontWidgetBase* myLabelsFont;
+
+ // tick marks
+ QGroupBox* myTicksGrp;
+ QtxIntSpinBox* myTickLength;
+};
+
+/*!
+ * Class : ViewerTools_CubeAxesDlgBase
+ * Description : Dialog for specifying cube axes properties
+ */
+class VIEWERTOOLS_EXPORT ViewerTools_CubeAxesDlgBase : public ViewerTools_DialogBase
+{
+ Q_OBJECT
+
+public:
+ ViewerTools_CubeAxesDlgBase(QtxAction* theAction,
+ QWidget* theParent,
+ const char* theName);
+ virtual ~ViewerTools_CubeAxesDlgBase();
+
+ virtual void initialize();
+
+ virtual void Update();
+
+protected slots:
+ virtual void onOk();
+ virtual bool onApply();
+ virtual void onClose();
+
+protected:
+ virtual QWidget* createButtonFrame( QWidget* );
+ virtual QWidget* createMainFrame ( QWidget* );
+ virtual bool isValid() const;
+
+ virtual ViewerTools_AxisWidgetBase* createAxisWidget( QWidget* ) = 0;
+
+protected:
+ QTabWidget* myTabWg;
+ QCheckBox* myIsVisible;
+
+ QPushButton* myOkBtn;
+ QPushButton* myApplyBtn;
+ QPushButton* myCloseBtn;
+ ViewerTools_AxisWidgetBase* myAxes[ 3 ];
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ViewerTools_DialogBase.h"
+
+#include "QtxAction.h"
+
+/*!
+ Constructor
+*/
+ViewerTools_DialogBase
+::ViewerTools_DialogBase(QtxAction* theAction,
+ QWidget* theParent,
+ const char* theName,
+ bool theModal,
+ Qt::WindowFlags theWFalgs):
+ QDialog(theParent,
+ theWFalgs | Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
+ myAction(theAction)
+{
+ setObjectName(theName);
+ setModal(theModal);
+
+ connect(theParent, SIGNAL(Show( QShowEvent * )), this, SLOT(onParentShow()));
+ connect(theParent, SIGNAL(Hide( QHideEvent * )), this, SLOT(onParentHide()));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+ViewerTools_DialogBase
+::~ViewerTools_DialogBase()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void
+ViewerTools_DialogBase
+::onParentShow()
+{
+ if(myAction->isChecked())
+ show();
+ else
+ hide();
+}
+
+void
+ViewerTools_DialogBase
+::onParentHide()
+{
+ hide();
+}
+
+void
+ViewerTools_DialogBase
+::done( int r )
+{
+ myAction->setChecked( false );
+ QDialog::done( r );
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_DIALOGBASE_H
+#define VIEWERTOOLS_DIALOGBASE_H
+
+#include "ViewerTools.h"
+
+#include <QDialog>
+
+class QtxAction;
+
+class VIEWERTOOLS_EXPORT ViewerTools_DialogBase : public QDialog
+{
+ Q_OBJECT;
+
+public:
+ ViewerTools_DialogBase(QtxAction* theAction,
+ QWidget* theParent,
+ const char* theName = "",
+ bool theModal = FALSE,
+ Qt::WindowFlags theWFalgs = 0);
+
+ ~ViewerTools_DialogBase();
+
+protected slots:
+ void onParentShow();
+ void onParentHide();
+ virtual void done( int );
+
+protected:
+ QtxAction* myAction;
+};
+
+#endif // VIEWERTOOLS_DIALOGBASE_H
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ViewerTools_FontWidgetBase.h"
+
+#include <QToolButton>
+#include <QComboBox>
+#include <QColorDialog>
+#include <QCheckBox>
+#include <QHBoxLayout>
+
+/*!
+ * Class : ViewerTools_FontWidgetBase
+ * Description : Dialog for specifynig font
+ */
+
+/*!
+ Constructor
+*/
+ViewerTools_FontWidgetBase::ViewerTools_FontWidgetBase( QWidget* theParent )
+: QWidget( theParent )
+{
+}
+
+/*!
+ Destructor
+*/
+ViewerTools_FontWidgetBase::~ViewerTools_FontWidgetBase()
+{
+}
+
+void ViewerTools_FontWidgetBase::Initialize()
+{
+ myColorBtn = new QToolButton( this );
+ myColorBtn->setMinimumWidth( 20 );
+
+ myFamily = new QComboBox( this );
+ InitializeFamilies();
+
+ myBold = new QCheckBox( tr( "BOLD" ), this );
+ myItalic = new QCheckBox( tr( "ITALIC" ), this );
+ myShadow = new QCheckBox( tr( "SHADOW" ), this );
+
+ QHBoxLayout* aHBLayout = new QHBoxLayout;
+ aHBLayout->setMargin( 0 );
+ aHBLayout->setSpacing( 5 );
+ aHBLayout->addWidget(myColorBtn);
+ aHBLayout->addWidget(myFamily);
+ aHBLayout->addWidget(myBold);
+ aHBLayout->addWidget(myItalic);
+ aHBLayout->addWidget(myShadow);
+ aHBLayout->addStretch();
+ this->setLayout(aHBLayout);
+
+ connect( myColorBtn, SIGNAL( clicked() ), SLOT( onColor() ) );
+
+ if( myFamily->count() == 0 )
+ {
+ myFamily->hide();
+ myBold->hide();
+ myItalic->hide();
+ myShadow->hide();
+ }
+}
+
+void ViewerTools_FontWidgetBase::SetColor( const QColor& theColor )
+{
+ QPalette palette;
+ palette.setColor(myColorBtn->backgroundRole(), theColor);
+ myColorBtn->setPalette(palette);
+}
+
+QColor ViewerTools_FontWidgetBase::GetColor() const
+{
+ return myColorBtn->palette().color( myColorBtn->backgroundRole() );
+}
+
+void ViewerTools_FontWidgetBase::onColor()
+{
+ QColor aColor = QColorDialog::getColor( GetColor(), this );
+ if ( aColor.isValid() )
+ SetColor( aColor );
+}
+
+void ViewerTools_FontWidgetBase::SetData( const QColor& theColor,
+ const int theFamily,
+ const bool theBold,
+ const bool theItalic,
+ const bool theShadow )
+{
+ SetColor( theColor );
+
+ myBold->setChecked( theBold );
+ myItalic->setChecked( theItalic );
+ myShadow->setChecked( theShadow );
+}
+
+void ViewerTools_FontWidgetBase::GetData( QColor& theColor,
+ int& theFamily,
+ bool& theBold,
+ bool& theItalic,
+ bool& theShadow ) const
+{
+ theColor = GetColor();
+
+ theBold = myBold->isChecked();
+ theItalic = myItalic->isChecked();
+ theShadow = myShadow->isChecked();
+}
--- /dev/null
+// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VIEWERTOOLS_FONTWIDGETBASE_H
+#define VIEWERTOOLS_FONTWIDGETBASE_H
+
+#include "ViewerTools.h"
+
+#include <QWidget>
+
+class QToolButton;
+class QComboBox;
+class QCheckBox;
+class QColor;
+
+/*!
+ * Class : ViewerTools_FontWidgetBase
+ * Description : Dialog for specifying font
+ */
+class VIEWERTOOLS_EXPORT ViewerTools_FontWidgetBase : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ViewerTools_FontWidgetBase( QWidget* );
+ virtual ~ViewerTools_FontWidgetBase();
+
+ void SetColor( const QColor& );
+ QColor GetColor() const;
+
+ virtual void SetData( const QColor&, const int, const bool, const bool, const bool );
+
+ virtual void GetData( QColor&, int&, bool&, bool&, bool& ) const;
+
+public:
+ virtual void Initialize();
+
+protected:
+ virtual void InitializeFamilies() = 0;
+
+protected slots:
+ void onColor();
+
+protected:
+ QToolButton* myColorBtn;
+ QComboBox* myFamily;
+ QCheckBox* myBold;
+ QCheckBox* myItalic;
+ QCheckBox* myShadow;
+};
+
+#endif
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="en_US">
+<context>
+ <name>ViewerTools_CubeAxesDlgBase</name>
+ <message>
+ <source>X_AXIS</source>
+ <translation>X axis</translation>
+ </message>
+ <message>
+ <source>Y_AXIS</source>
+ <translation>Y axis</translation>
+ </message>
+ <message>
+ <source>Z_AXIS</source>
+ <translation>Z axis</translation>
+ </message>
+ <message>
+ <source>CAPTION</source>
+ <translation>Graduated axes</translation>
+ </message>
+ <message>
+ <source>IS_VISIBLE</source>
+ <translation>Is visible</translation>
+ </message>
+ <message>
+ <source>FONT</source>
+ <translation>Font</translation>
+ </message>
+ <message>
+ <source>NAME</source>
+ <translation>Name</translation>
+ </message>
+ <message>
+ <source>TICK_MARKS</source>
+ <translation>Tick marks</translation>
+ </message>
+ <message>
+ <source>LABELS</source>
+ <translation>Labels</translation>
+ </message>
+ <message>
+ <source>LENGTH</source>
+ <translation>Length</translation>
+ </message>
+ <message>
+ <source>NUMBER</source>
+ <translation>Number</translation>
+ </message>
+ <message>
+ <source>OFFSET</source>
+ <translation>Offset</translation>
+ </message>
+ <message>
+ <source>AXIS_NAME</source>
+ <translation>Axis name</translation>
+ </message>
+</context>
+<context>
+ <name>ViewerTools_FontWidgetBase</name>
+ <message>
+ <source>BOLD</source>
+ <translation>Bold</translation>
+ </message>
+ <message>
+ <source>ITALIC</source>
+ <translation>Italic</translation>
+ </message>
+ <message>
+ <source>SHADOW</source>
+ <translation>Shadow</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+ <name>ViewerTools_CubeAxesDlgBase</name>
+ <message>
+ <source>X_AXIS</source>
+ <translation>Axe X</translation>
+ </message>
+ <message>
+ <source>Y_AXIS</source>
+ <translation>Axe Y</translation>
+ </message>
+ <message>
+ <source>Z_AXIS</source>
+ <translation>Axe Z</translation>
+ </message>
+ <message>
+ <source>CAPTION</source>
+ <translation>Axes gradués</translation>
+ </message>
+ <message>
+ <source>IS_VISIBLE</source>
+ <translation>Visible</translation>
+ </message>
+ <message>
+ <source>FONT</source>
+ <translation>Couleur</translation>
+ </message>
+ <message>
+ <source>NAME</source>
+ <translation>Nom</translation>
+ </message>
+ <message>
+ <source>TICK_MARKS</source>
+ <translation>Marques de graduation</translation>
+ </message>
+ <message>
+ <source>LABELS</source>
+ <translation>Etiquettes</translation>
+ </message>
+ <message>
+ <source>LENGTH</source>
+ <translation>Longueur</translation>
+ </message>
+ <message>
+ <source>NUMBER</source>
+ <translation>Nombre</translation>
+ </message>
+ <message>
+ <source>OFFSET</source>
+ <translation>Décalage</translation>
+ </message>
+ <message>
+ <source>AXIS_NAME</source>
+ <translation>Nom de l'axe </translation>
+ </message>
+</context>
+<context>
+ <name>ViewerTools_FontWidgetBase</name>
+ <message>
+ <source>BOLD</source>
+ <translation>Gras</translation>
+ </message>
+ <message>
+ <source>ITALIC</source>
+ <translation>Italique</translation>
+ </message>
+ <message>
+ <source>SHADOW</source>
+ <translation>Ombré</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+SUBDIRS = vtkEDFOverloads dlgfactory
--- /dev/null
+#include "GenericDialog.hxx"
+
+GenericDialog::GenericDialog(QDialog *parent) : QDialog(parent)
+{
+ ui.setupUi(this); // A faire en premier
+
+ /*
+ Personnalisez vos widgets ici si nécessaire
+ Réalisez des connexions supplémentaires entre signaux et slots
+ */
+
+ // The slots accept() and reject() are already connected to the
+ // buttonbox (inherited features)
+}
+
+QFrame * GenericDialog::getPanel() {
+ return ui.centralPanel;
+}
+
+QDialogButtonBox * GenericDialog::getButtonBox() {
+ return ui.buttonBox;
+}
+
+
+#include <QDebug>
+void GenericDialog::accept() {
+ qDebug() << "accept() is not implemented yet";
+ QDialog::accept();
+}
--- /dev/null
+#ifndef _GenericDialog_HXX
+#define _GenericDialog_HXX
+
+#include <QtGui>
+#include "ui_GenericDialog.hxx"
+
+class GenericDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ GenericDialog(QDialog *parent = 0);
+
+ protected:
+ QFrame * getPanel();
+ QDialogButtonBox * getButtonBox();
+
+ protected slots:
+ void accept();
+ //void reject();
+
+ private:
+ Ui_GenericDialog ui; // instance of the class defined in ui_GenericDialog.h
+};
+
+
+#endif // _GenericDialog_HXX
--- /dev/null
+<ui version="4.0" >
+ <class>GenericDialog</class>
+ <widget class="QDialog" name="GenericDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="centralPanel" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>GenericDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>GenericDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Guillaume Boulant (EDF/R&D)
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# moc-files generation (using MOC)
+%_moc.cxx: %.hxx
+ $(MOC) $< -o $@
+
+# Qt form files generation (using UIC)
+ui_%.hxx: %.ui
+ $(UIC) -o $@ $<
+
+# Program targets
+bin_PROGRAMS = qtester gtester
+
+# QDialog uic files
+UIC_FILES_QDIALOG = \
+ ui_QDialogTest.hxx
+
+# QDialog moc files
+MOC_FILES_QDIALOG = \
+ QDialogTest_moc.cxx
+
+# GDialog uic files
+UIC_FILES_GDIALOG= \
+ ui_GenericDialog.hxx \
+ ui_GDialogTest.hxx
+
+# GDialog moc files
+MOC_FILES_GDIALOG= \
+ GenericDialog_moc.cxx \
+ GDialogTest_moc.cxx
+
+QDIALOG_TEMPLATES = __QDIALOG__.ui __QDIALOG__.hxx __QDIALOG__.cxx
+GDIALOG_TEMPLATES = __GDIALOG__.ui __GDIALOG__.hxx __GDIALOG__.cxx
+
+# generated sources
+BUILT_SOURCES = $(UIC_FILES_QDIALOG) $(UIC_FILES_GDIALOG)
+
+# extra distributed files
+EXTRA_DIST += $(QDIALOG_TEMPLATES) $(GDIALOG_TEMPLATES) GenericDialog.ui README.txt dlgfactory.py
+
+mostlyclean-local:
+ rm @builddir@/QDialogTest*
+ rm @builddir@/GDialogTest*
+ rm -f @builddir@/*_moc.cxx @builddir@/ui_*.hxx
+
+QDialogTest.hxx QDialogTest.cxx QDialogTest.ui: $(QDIALOG_TEMPLATES) dlgfactory.py
+ $(srcdir)/dlgfactory.py -s -n QDialogTest -t qdialog
+
+GDialogTest.hxx GDialogTest.cxx GDialogTest.ui : $(GDIALOG_TEMPLATES) dlgfactory.py
+ $(srcdir)/dlgfactory.py -s -n GDialogTest -t gdialog
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+QT_LIBS=@QT_LIBS@
+
+# QDialog tester
+qtester_SOURCES = \
+ qtester.cxx
+nodist_qtester_SOURCES = \
+ QDialogTest.cxx \
+ $(MOC_FILES_QDIALOG) \
+ $(UIC_FILES_QDIALOG)
+
+qtester_CPPFLAGS = \
+ $(QT_CXXFLAGS) \
+ -I.
+
+qtester_LDFLAGS = \
+ $(QT_LIBS)
+
+gtester_SOURCES = \
+ gtester.cxx \
+ GenericDialog.hxx \
+ GenericDialog.cxx
+nodist_gtester_SOURCES = \
+ GDialogTest.cxx \
+ $(MOC_FILES_GDIALOG) \
+ $(UIC_FILES_GDIALOG)
+
+gtester_CPPFLAGS = \
+ $(QT_CXXFLAGS) \
+ -I@srcdir@ \
+ -I.
+
+gtester_LDFLAGS = \
+ $(QT_LIBS)
--- /dev/null
+This package provides a simple tool to generates the bootstrap files
+of a standard Qt dialog. Nothing original neither very smart, but just
+help to initiate all this stuff the good way.
+
+See the header of the script dlgfactory.py for details.
+
+Some use cases (basic unit test) are given in the files qtester.cxx
+and gtester.cxx. The build procedure (when you type make) create test
+classes called QDialogTest and GDialogTest and used respectively in
+qtester and gtester.
+
+(gboulant - 26 oct. 2011)
--- /dev/null
+#include "__CLASSNAME__.hxx"
+
+__CLASSNAME__::__CLASSNAME__(QDialog *parent) : GenericDialog(parent)
+{
+ ui.setupUi(this->getPanel());
+}
--- /dev/null
+#ifndef ___CLASSNAME___HXX
+#define ___CLASSNAME___HXX
+
+#include <QtGui>
+#include "ui___CLASSNAME__.hxx"
+#include "GenericDialog.hxx"
+
+class __CLASSNAME__ : public GenericDialog
+{
+ Q_OBJECT
+
+ public:
+ __CLASSNAME__(QDialog *parent = 0);
+
+ private:
+ Ui___CLASSNAME__ ui; // instance of the class defined in ui___CLASSNAME__.hxx
+};
+
+
+#endif // ___CLASSNAME___HXX
--- /dev/null
+<ui version="4.0" >
+ <class>__CLASSNAME__</class>
+ <widget class="QWidget" name="__CLASSNAME__" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Pression :</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Température :</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="lineEdit" />
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit_2" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>121</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+#include "__CLASSNAME__.hxx"
+
+__CLASSNAME__::__CLASSNAME__(QDialog *parent) : QDialog(parent)
+{
+ ui.setupUi(this); // A faire en premier
+
+ /*
+ Personnalisez vos widgets ici si nécessaire
+ Réalisez des connexions supplémentaires entre signaux et slots
+ */
+
+ // The slots accept() and reject() are already connected to the
+ // buttonbox (inherited features)
+}
+
+#include <QDebug>
+void __CLASSNAME__::accept() {
+ qDebug() << "accept() is not implemented yet";
+ QDialog::accept();
+}
--- /dev/null
+#ifndef ___CLASSNAME___HXX
+#define ___CLASSNAME___HXX
+
+#include <QtGui>
+#include "ui___CLASSNAME__.hxx"
+
+class __CLASSNAME__ : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ __CLASSNAME__(QDialog *parent = 0);
+
+ protected slots:
+ void accept();
+ //void reject();
+
+ private:
+ Ui___CLASSNAME__ ui; // instance of the class defined in ui___CLASSNAME__.hxx
+};
+
+
+#endif // ___CLASSNAME___HXX
--- /dev/null
+<ui version="4.0" >
+ <class>__CLASSNAME__</class>
+ <widget class="QDialog" name="__CLASSNAME__" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>30</x>
+ <y>240</y>
+ <width>341</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>__CLASSNAME__</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>__CLASSNAME__</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+#!/usr/bin/env python
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import sys, os
+
+__descr_str = ""
+__descr_str += "This script generates a set of files to initiate a dialog Qt window "
+__descr_str += "(i.e. MyDialog.ui, MyDialog.hxx and MyDialog.cxx files). "
+__descr_str += "The dialog window can be a self-consistent class (i.e. depends only "
+__descr_str += "on Qt classes) or a class that inherits class GenericDialog "
+__descr_str += "which implementation is provided in this package and "
+__descr_str += "which design is defined by the GenericDialog.ui file (editable using "
+__descr_str += "the Qt designer). "
+__descr_str += "The -t option let you choose between the two possibilities (specify "
+__descr_str += "\"-t qdialog\" for the first case, \"-t gdialog\" otherwise)."
+
+__msg_str = """
+#
+# ---------------------------------------------------------
+# Generation rules to create moc files from QObject headers
+# and form source files from ui files
+# ---------------------------------------------------------
+
+%_moc.cxx: %.hxx
+ $(MOC) $< -o $@
+
+ui_%.hxx: %.ui
+ $(UIC) -o $@ $<
+
+
+# ---------------------------------------------------------
+# Declaration of form files generated by UIC and MOC files
+# as BUILT_SOURCES to be used in the building process.
+# ---------------------------------------------------------
+#
+UIC_FILES = \
+ ui___CLASSNAME__.hxx
+#
+MOC_FILES = \
+ __CLASSNAME___moc.cxx
+
+BUILT_SOURCES = $(UIC_FILES)
+
+#
+# ---------------------------------------------------------
+# Declaration of sources files to the building process
+# ---------------------------------------------------------
+# MOC files and UIC files should be added to the list of undistributed
+# source files with something like (where <MyLibrary> should be
+# replaced by the name of the product declared by the directive
+# lib_LTLIBRARIES):
+#
+nodist_<MyLibrary>_la_SOURCES += $(MOC_FILES) $(UIC_FILES)
+
+dist_<MyLibrary>_la_SOURCES += __CLASSNAME__.cxx
+salomeinclude_HEADERS += __CLASSNAME__.hxx
+
+<MyLibrary>_la_CPPFLAGS = \\
+ $(QT_CXXFLAGS)
+
+<MyLibrary>_la_LDFLAGS = \\
+ $(QT_LIBS)
+"""
+
+if __name__ == "__main__":
+ from optparse import OptionParser
+ import shutil, fileinput
+
+ tool_path = os.path.dirname( os.path.abspath( sys.argv[0] ) )
+
+ parser = OptionParser( description = __descr_str )
+ parser.add_option( "-n", action="store", default="TestDialog", dest="className", metavar="className",
+ help="specify the name of the class (default is TestDialog)" )
+ parser.add_option( "-t", action="store", default="qdialog", dest="classType",
+ choices=["qdialog", "gdialog"], metavar="classType",
+ help="specify the type of the class (default is qdialog)" )
+ parser.add_option( "-v", "--verbose", action="store_true", default=True, dest="verbose",
+ help="verbose mode" )
+ parser.add_option( "-s", "--silent", action="store_false", dest="verbose",
+ help="silent mode" )
+
+ (options, args) = parser.parse_args()
+ className = options.className
+ classType = options.classType
+
+ for ext in [".cxx", ".hxx", ".ui"]:
+ file_dest = className + ext
+ if classType == "qdialog":
+ file_src = os.path.join( tool_path, "__QDIALOG__" + ext )
+ pass
+ else:
+ file_src = os.path.join( tool_path, "__GDIALOG__" + ext )
+ pass
+ shutil.copyfile( file_src, file_dest )
+ finput = fileinput.FileInput( file_dest, inplace=1 )
+ for line in finput:
+ line = line[:-1]
+ line = line.replace( "__CLASSNAME__", className )
+ print line
+ pass
+
+ if options.verbose:
+ print "Note that the following directives should be present in your Makefile.am (or something like that): \n"
+ print __msg_str.replace( "__CLASSNAME__", className )
+ pass
+ pass
+
--- /dev/null
+#!/bin/sh
+# Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+#
+# ==================================================================
+#_debut_usage
+#
+# USAGE:
+#
+# dlgfactory.sh -n className [-t classType]
+#
+#
+# DESCRIPTION:
+#
+# This script generates a set of files to initiate a dialog qt window
+# (i.e. MyDialog.ui, MyDialog.hxx and MyDialog.cxx files).
+#
+# The dialog window can be a self-consistent class (i.e. depends only
+# on Qt classes) or a classe that inherits from the class
+# GenericDialog whose implementation is provided in this package and
+# whose design is defined by the GenericDialog.ui file (editable using
+# the qt designer).
+#
+# The -t option let you choose between the two possibilities (specify
+# "-t qdialog" for the first case, "-t gdialog" otherwise).
+#
+# OPTION:
+# -n : specify the name of the class (default is TestDialog)
+#
+# -t : specify the type of the class (default is qdialog)
+#
+#_fin_usage
+# ==================================================================
+#
+
+thisScript=$(which $0)
+TOOLDIRNAME=$(dirname $0)
+
+displayUsage()
+{
+ cat $thisScript | sed -e '/^#_debut_usage/,/^#_fin_usage/!d' \
+ -e '/^#_debut_usage/d' \
+ -e '/^#_fin_usage/d' \
+ -e 's/^#//g'
+}
+
+#
+# Read the options on the command line
+#
+className=TestDialog
+classType=dialog
+if [ $# -eq 0 ]; then
+ displayUsage
+ exit 1
+else
+ while [ $# -ne 0 ]; do
+ case $1 in
+ -n)
+ shift; className=$1; shift ;;
+ -t)
+ shift; classType=$1; shift ;;
+ *)
+ displayUsage;;
+ esac
+ done
+fi
+
+if [ "$classType" = "qdialog" ]; then
+ sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__QDIALOG__.ui > $className.ui
+ sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__QDIALOG__.hxx > $className.hxx
+ sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__QDIALOG__.cxx > $className.cxx
+else
+ sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__GDIALOG__.ui > $className.ui
+ sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__GDIALOG__.hxx > $className.hxx
+ sed s/__CLASSNAME__/$className/g $TOOLDIRNAME/__GDIALOG__.cxx > $className.cxx
+fi
+
+displayMessage()
+{
+ cat $thisScript | sed -e '/^#_debut_message/,/^#_fin_message/!d' \
+ -e '/^#_debut_message/d' \
+ -e '/^#_fin_message/d' \
+ -e 's/^#//g' \
+ -e "s/__CLASSNAME__/$className/g"
+}
+
+#_debut_message
+##
+## ---------------------------------------------------------
+## Generation rules to create moc files from QObject headers
+## and form source files from ui files
+## ---------------------------------------------------------
+##
+#%_moc.cxx: %.hxx
+# $(MOC) $< -o $@
+#
+#ui_%.hxx: %.ui
+# $(UIC) -o $@ $<
+#
+##
+## ---------------------------------------------------------
+## Declaration of form files generated by UIC and MOC files
+## as BUILT_SOURCES to be used in the building process.
+## ---------------------------------------------------------
+##
+#UIC_FILES = \
+# ui___CLASSNAME__.hxx
+##
+#MOC_FILES = \
+# __CLASSNAME___moc.cxx
+#
+#BUILT_SOURCES = $(UIC_FILES)
+#
+##
+## ---------------------------------------------------------
+## Declaration of sources files to the building process
+## ---------------------------------------------------------
+## MOC files and UIC files should be added to the list of undistributed
+## source files with something like (where <MyLibrary> should be
+## replaced by the name of the product declared by the directive
+## lib_LTLIBRARIES):
+##
+#nodist_<MyLibrary>_la_SOURCES += $(MOC_FILES) $(UIC_FILES)
+#
+#dist_<MyLibrary>_la_SOURCES += __CLASSNAME__.cxx
+#salomeinclude_HEADERS += __CLASSNAME__.hxx
+#
+#<MyLibrary>_la_CPPFLAGS = \
+# $(QT_CXXFLAGS)
+#
+#<MyLibrary>_la_LDFLAGS = \
+# $(QT_LIBS)
+
+#_fin_message
+
+echo "Note that the following directives should be present in your Makefile.am (or something like that):"
+echo ""
+displayMessage
+
--- /dev/null
+// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// This program can be used for unit test of dialog box.
+// You just have to include the interface file (*.h) and
+// use the dialog class as illustrated in the functions TEST_*.
+// (gboulant - 12/10/2010)
+//
+#include <QApplication>
+#include <QtGui>
+#include "GDialogTest.hxx"
+
+void TEST_show() {
+ GDialogTest * dialog = new GDialogTest();
+ dialog->show();
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ TEST_show();
+ return app.exec();
+}
--- /dev/null
+// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// This program can be used for unit test of dialog box.
+// You just have to include the interface file (*.h) and
+// use the dialog class as illustrated in the functions TEST_*.
+// (gboulant - 12/10/2010)
+//
+#include <QApplication>
+#include <QtGui>
+#include "QDialogTest.hxx"
+
+void TEST_show() {
+ QDialogTest * dialog = new QDialogTest();
+ dialog->show();
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ TEST_show();
+ return app.exec();
+}
--- /dev/null
+# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+libparaview_LTLIBRARIES = libvtkEDFOverloads.la
+lib_LTLIBRARIES = libvtkTools.la
+
+salomeinclude_HEADERS = vtkEDFCutter.h \
+ vtkEDFFactory.h \
+ vtkEDFOverloadsDefines.h
+
+dist_libvtkEDFOverloads_la_SOURCES = vtkEDFFactory.cxx
+dist_libvtkTools_la_SOURCES = vtkEDFCutter.cxx
+
+libvtkEDFOverloads_la_CPPFLAGS = $(VTK_INCLUDES)
+libvtkTools_la_CPPFLAGS = $(VTK_INCLUDES)
+
+libvtkEDFOverloads_la_LDFLAGS = $(VTK_LIBS)
+libvtkEDFOverloads_la_LIBADD = libvtkTools.la
+libvtkTools_la_LDFLAGS = $(VTK_LIBS)
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkEDFCutter.h"
+
+#include "vtkInformationVector.h"
+#include "vtkInformation.h"
+#include "vtkSmartPointer.h"
+#include "vtkGenericCell.h"
+#include "vtkPolyData.h"
+#include "vtkObjectFactory.h"
+#include "vtkIdTypeArray.h"
+#include "vtkCellData.h"
+#include "vtkCellArray.h"
+#include "vtkIdList.h"
+
+#include <list>
+#include <set>
+#include <map>
+#include <deque>
+
+class vtkEDFEdge
+{
+public :
+ vtkIdType v0;
+ vtkIdType v1;
+
+ vtkEDFEdge(vtkIdType a, vtkIdType b) : v0(a), v1(b){}
+ vtkEDFEdge(){}
+};
+
+bool operator == (const vtkEDFEdge& e0, const vtkEDFEdge& e1)
+{
+ return (e0.v0 == e1.v0 && e0.v1 == e1.v1) ||
+ (e0.v1 == e1.v0 && e0.v0 == e1.v1);
+}
+
+bool operator != (const vtkEDFEdge& e0, const vtkEDFEdge& e1)
+{
+ return !(e0==e1);
+}
+
+bool operator < (const vtkEDFEdge& e0, const vtkEDFEdge& e1)
+{
+ vtkEDFEdge the_e0;
+ vtkEDFEdge the_e1;
+ if(e0.v0 < e0.v1)
+ {
+ the_e0.v0 = e0.v0;
+ the_e0.v1 = e0.v1;
+ }
+ else
+ {
+ the_e0.v0 = e0.v1;
+ the_e0.v1 = e0.v0;
+ }
+ if(e1.v0 < e1.v1)
+ {
+ the_e1.v0 = e1.v0;
+ the_e1.v1 = e1.v1;
+ }
+ else
+ {
+ the_e1.v0 = e1.v1;
+ the_e1.v1 = e1.v0;
+ }
+
+ if(the_e0.v0 == the_e1.v0)
+ return (the_e0.v1 < the_e1.v1);
+
+ return the_e0.v0 < the_e1.v0;
+}
+
+vtkStandardNewMacro(vtkEDFCutter);
+vtkCxxRevisionMacro(vtkEDFCutter, "0.0");
+
+vtkEDFCutter::vtkEDFCutter()
+{
+ this->OriginalCellIdsName = NULL;
+}
+
+vtkEDFCutter::~vtkEDFCutter()
+{
+ this->SetOriginalCellIdsName(NULL);
+}
+
+int vtkEDFCutter::RequestData(vtkInformation * request,
+ vtkInformationVector ** inVector,
+ vtkInformationVector * outVector)
+{
+ // get the info objects
+ vtkInformation *inInfo = inVector[0]->GetInformationObject(0);
+ vtkInformation *outInfo = outVector->GetInformationObject(0);
+
+ // get the input and output
+ vtkDataSet *input = vtkDataSet::SafeDownCast(
+ inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+ vtkSmartPointer<vtkIdTypeArray> cellIdArray =
+ vtkSmartPointer<vtkIdTypeArray>::New();
+ cellIdArray->SetName(this->GetOriginalCellIdsName());
+ cellIdArray->SetNumberOfComponents(1);
+ cellIdArray->SetNumberOfTuples(input->GetNumberOfCells());
+ for(vtkIdType id=0; id < cellIdArray->GetNumberOfTuples(); id++)
+ {
+ cellIdArray->SetTuple1(id, id);
+ }
+ input->GetCellData()->AddArray(cellIdArray);
+
+ int ret = this->Superclass::RequestData(request, inVector, outVector);
+
+ if(ret == 0)
+ return 0;
+
+ vtkPolyData *output = vtkPolyData::SafeDownCast(
+ outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+ vtkSmartPointer<vtkPolyData> tmpOutput;
+ tmpOutput.TakeReference(output->NewInstance());
+
+ this->AssembleOutputTriangles(output, tmpOutput);
+
+ output->ShallowCopy(tmpOutput);
+
+ return ret;
+}
+
+
+void vtkEDFCutter::AssembleOutputTriangles(vtkPolyData* inpd,
+ vtkPolyData* outpd)
+{
+ outpd->ShallowCopy(inpd);
+
+ vtkIdTypeArray* originalCellIds = vtkIdTypeArray::SafeDownCast(
+ inpd->GetCellData()->GetArray(this->GetOriginalCellIdsName()));
+
+ if(originalCellIds == NULL)
+ {
+ return;
+ }
+
+ outpd->GetCellData()->Initialize();
+ outpd->GetCellData()->CopyAllocate(inpd->GetCellData());
+
+ vtkSmartPointer<vtkCellArray> verts = vtkSmartPointer<vtkCellArray>::New();
+ vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
+ vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
+ vtkSmartPointer<vtkCellArray> strips = vtkSmartPointer<vtkCellArray>::New();
+ outpd->SetVerts(verts);
+ outpd->SetLines(lines);
+ outpd->SetPolys(polys);
+ outpd->SetStrips(strips);
+
+ for(vtkIdType cellId=0; cellId<inpd->GetNumberOfCells(); cellId++)
+ {
+ unsigned char type = inpd->GetCellType(cellId);
+ if(type != VTK_TRIANGLE)
+ {
+ vtkIdType npts;
+ vtkIdType* pts = NULL;
+ inpd->GetCellPoints(cellId, npts, pts);
+ vtkIdType newCellId =
+ outpd->InsertNextCell(type, npts, pts);
+ outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+ }
+ else
+ {
+ vtkIdType cellIdEnd = cellId+1;
+ vtkIdType originalCellId = originalCellIds->GetValue(cellId);
+ while(cellIdEnd < inpd->GetNumberOfCells() &&
+ inpd->GetCellType(cellIdEnd) == VTK_TRIANGLE &&
+ originalCellIds->GetValue(cellIdEnd) == originalCellId)
+ {
+ cellIdEnd++;
+ }
+
+ // all triangles from cellId to cellIdEnd come from the same
+ // original cell.
+
+ // A batch is composed of triangles which are connected by the edges.
+ std::map<vtkIdType, std::set<vtkIdType> > connectedTriangles;
+ for(vtkIdType firstCell = cellId; firstCell < cellIdEnd-1; firstCell++)
+ {
+ vtkIdType npts;
+ vtkIdType* pts = NULL;
+ inpd->GetCellPoints(firstCell, npts, pts);
+ vtkEDFEdge fe0 = vtkEDFEdge(pts[0], pts[1]);
+ vtkEDFEdge fe1 = vtkEDFEdge(pts[1], pts[2]);
+ vtkEDFEdge fe2 = vtkEDFEdge(pts[2], pts[0]);
+ for(vtkIdType secondCell = firstCell+1; secondCell < cellIdEnd; secondCell++)
+ {
+ vtkIdType snpts;
+ vtkIdType* spts = NULL;
+ inpd->GetCellPoints(secondCell, snpts, spts);
+ vtkEDFEdge se0 = vtkEDFEdge(spts[0], spts[1]);
+ vtkEDFEdge se1 = vtkEDFEdge(spts[1], spts[2]);
+ vtkEDFEdge se2 = vtkEDFEdge(spts[2], spts[0]);
+
+ if(fe0 == se0 || fe0 == se1 || fe0 == se2 ||
+ fe1 == se0 || fe1 == se1 || fe1 == se2 ||
+ fe2 == se0 || fe2 == se1 || fe2 == se2)
+ {
+ connectedTriangles[firstCell].insert(secondCell);
+ connectedTriangles[secondCell].insert(firstCell);
+ }
+ }
+ }
+
+ std::set<vtkIdType> visitedCell;
+ for(vtkIdType id=cellId; id<cellIdEnd; id++)
+ {
+ if(visitedCell.find(id) != visitedCell.end())
+ continue;
+
+ // if this cell has not yet been visited, I create a batch of all
+ // cells connected to this one
+
+ visitedCell.insert(id);
+ std::set<vtkIdType> batch;
+ std::list<vtkIdType> cellList;
+ cellList.push_back(id);
+ while(cellList.size() > 0)
+ {
+ vtkIdType currentId = *(cellList.begin());
+ batch.insert(currentId);
+ cellList.pop_front();
+ if(connectedTriangles.find(currentId) != connectedTriangles.end())
+ {
+ const std::set<vtkIdType>& adj = connectedTriangles[currentId];
+ std::set<vtkIdType>::const_iterator it = adj.begin();
+ while(it != adj.end())
+ {
+ vtkIdType other = *it;
+ if(visitedCell.find(other) == visitedCell.end())
+ {
+ cellList.push_back(other);
+ visitedCell.insert(other);
+ }
+ it++;
+ }
+ }
+ }
+
+
+
+ // then I add this batch to the output,
+ // creating a unique cell for the whole batch.
+
+ if(batch.size() == 1)
+ {
+ vtkIdType tid = *(batch.begin());
+ vtkIdType npts;
+ vtkIdType* pts = NULL;
+ inpd->GetCellPoints(tid, npts, pts);
+ vtkIdType newCellId =
+ outpd->InsertNextCell(VTK_TRIANGLE, npts, pts);
+ outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+ }
+ else if(batch.size() == 2)
+ { // two triangles connected together --> create a VTK_QUAD
+ vtkIdType fid = *(batch.begin());
+ vtkIdType sid = *(batch.rbegin());
+ vtkIdType fnpts;
+ vtkIdType* fpts = NULL;
+ inpd->GetCellPoints(fid, fnpts, fpts);
+ vtkIdType snpts;
+ vtkIdType* spts = NULL;
+ inpd->GetCellPoints(sid, snpts, spts);
+
+ int findex = 0;
+ vtkIdType fv = fpts[findex];
+ while(((fv == spts[0]) ||
+ (fv == spts[1]) ||
+ (fv == spts[2])) && findex < 3)
+ {
+ findex++;
+ fv = fpts[findex];
+ }
+ if(findex == 3)
+ {// this is a degenerate case : one of the triangles use
+ // only 2 vertices
+ findex = 0;
+ }
+ int sindex = 0;
+ vtkIdType sv = spts[sindex];
+ while(((sv == fpts[0]) ||
+ (sv == fpts[1]) ||
+ (sv == fpts[2])) && sindex < 3)
+ {
+ sindex++;
+ sv = spts[sindex];
+ }
+ if(sindex == 3)
+ {// this is a degenerate case : one of the triangles use
+ // only 2 vertices
+ sindex = 0;
+ }
+
+ vtkIdType pts[4];
+ pts[0] = fpts[findex];
+ pts[1] = fpts[(findex+1)%3];
+ pts[2] = spts[sindex];
+ pts[3] = fpts[(findex+2)%3];
+
+ vtkIdType newCellId = outpd->InsertNextCell(VTK_QUAD, 4, pts);
+ outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+ }
+ else
+ {
+ std::deque<vtkEDFEdge> contour;
+
+ std::list<vtkIdType> toVisit;
+ std::set<vtkIdType> visited;
+
+ toVisit.push_back(*(batch.begin()));
+
+ std::set<vtkIdType> triedAgain;
+
+ while(toVisit.size() > 0)
+ {
+ vtkIdType currentId = *(toVisit.begin());
+ toVisit.pop_front();
+ if(visited.find(currentId) != visited.end())
+ continue;
+
+ visited.insert(currentId);
+ const std::set<vtkIdType>& adj = connectedTriangles[currentId];
+ std::set<vtkIdType>::const_iterator it = adj.begin();
+ while(it != adj.end())
+ {
+ vtkIdType adjid = *it;
+ it++;
+ if(visited.find(adjid) != visited.end())
+ continue;
+
+ toVisit.push_back(adjid);
+ }
+
+ vtkIdType npts;
+ vtkIdType* pts = NULL;
+ inpd->GetCellPoints(currentId, npts, pts);
+ vtkEDFEdge edge[3] = {vtkEDFEdge(pts[0], pts[1]),
+ vtkEDFEdge(pts[1], pts[2]),
+ vtkEDFEdge(pts[2], pts[0])};
+
+ // special case : initialization of the contour
+ if(contour.size() == 0)
+ {
+ contour.push_back(edge[0]);
+ contour.push_back(edge[1]);
+ contour.push_back(edge[2]);
+ continue;
+ }
+
+ // Find which edge of the contour
+ // is connected to the current triangle
+ int orient = 0;
+ std::deque<vtkEDFEdge>::iterator contourit = contour.begin();
+ bool found = false;
+ while(contourit != contour.end())
+ {
+ vtkEDFEdge& e = *contourit;
+ for(orient = 0; orient<3; orient++)
+ {
+ if(e == edge[orient])
+ {
+ found = true;
+ break;
+ }
+ }
+ if(found)
+ break;
+
+ contourit++;
+ }
+ if(contourit == contour.end())
+ {// this triangle is not connected to the current contour.
+ // put it back in the queue for later processing
+ if(triedAgain.find(currentId) == triedAgain.end())
+ {
+ triedAgain.insert(currentId);
+ toVisit.push_back(currentId);
+ visited.erase(currentId);
+ continue;
+ }
+ else
+ {
+ vtkDebugMacro( << "triangle " << currentId
+ << "could not be added to the contour of the current batch");
+ continue;
+ }
+ }
+ // if I reach this point, I will add the triangle to the contour
+ // --> the contour will be modified and I can try again
+ // to add the previously rejected triangles
+ triedAgain.clear();
+
+ // Now, merge the edges of the current triangle with
+ // the contour
+ vtkEDFEdge& tbeforeedge = edge[(orient+1)%3];
+ vtkEDFEdge& tafteredge = edge[(orient+2)%3];
+
+ std::deque<vtkEDFEdge>::iterator beforeit;
+ if(contourit == contour.begin())
+ beforeit = contour.end()-1;
+ else
+ beforeit = contourit - 1;
+ vtkEDFEdge& beforeedge = *beforeit;
+
+ std::deque<vtkEDFEdge>::iterator afterit;
+ if(contourit == contour.end()-1)
+ afterit = contour.begin();
+ else
+ afterit = contourit + 1;
+ vtkEDFEdge& afteredge = *afterit;
+
+ if(beforeedge == tbeforeedge)
+ {
+ if(afteredge == tafteredge)
+ {// in this case, I am adding a triangle that is fully inside
+ // the contour. I need to remove the three edges from the
+ // contour.
+ if(contour.size() == 3)
+ {
+ contour.clear();
+ }
+ else
+ {
+ std::deque<vtkEDFEdge>::iterator lastit;
+ if(afterit == contour.end()-1)
+ lastit = contour.begin();
+ else
+ lastit = afterit + 1;
+
+ if(lastit < beforeit)
+ {
+ contour.erase(beforeit, contour.end());
+ contour.erase(contour.begin(), lastit);
+ }
+ else
+ {
+ contour.erase(beforeit, lastit);
+ }
+ }
+ }
+ else
+ {// the edge before is the glued, remove the two adjacent edges
+ // and add the edge after
+ if(beforeit == contour.end()-1)
+ {
+ contour.erase(beforeit, contour.end());
+ contour.erase(contour.begin(), contour.begin()+1);
+ contour.push_back(tafteredge);
+ }
+ else
+ {
+ int index = beforeit - contour.begin();
+ contour.erase(beforeit, contourit+1);
+ contour.insert(contour.begin()+index, tafteredge);
+ }
+ }
+ }
+ else if(afteredge == tafteredge)
+ {// the edge after is glued, removed the two glued edges and add
+ // the edge new edge
+ if(contourit == contour.end() -1)
+ {
+ contour.erase(contour.end() - 1);
+ contour.erase(contour.begin());
+ contour.push_back(tbeforeedge);
+ }
+ else
+ {
+ int index = contourit - contour.begin();
+ contour.erase(contourit, afterit+1);
+ contour.insert(contour.begin()+index, tbeforeedge);
+ }
+ }
+ else
+ {
+ int index = contourit - contour.begin();
+ contour.erase(contourit);
+ contour.insert(contour.begin()+index, tbeforeedge);
+ contour.insert(contour.begin()+index+1, tafteredge);
+ }
+ }
+ vtkSmartPointer<vtkIdList> ids = vtkSmartPointer<vtkIdList>::New();
+ std::deque<vtkEDFEdge>::iterator cit = contour.begin();
+ while(cit != contour.end())
+ {
+ vtkEDFEdge& e = *cit;
+ cit++;
+ ids->InsertNextId(e.v0);
+ }
+
+ vtkIdType newCellId = outpd->InsertNextCell(VTK_POLYGON, ids);
+ outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId);
+ }
+ }
+ cellId = cellIdEnd - 1;
+ }
+ }
+}
+
+void vtkEDFCutter::PrintSelf(ostream& os, vtkIndent indent)
+{
+ this->Superclass::PrintSelf(os, indent);
+}
+
+
--- /dev/null
+// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkEDFCutter_h__
+#define __vtkEDFCutter_h__
+
+#include "vtkEDFOverloadsDefines.h"
+#include "vtkCutter.h"
+
+class VTKTOOLS_EXPORT vtkEDFCutter : public vtkCutter
+{
+public :
+ static vtkEDFCutter* New();
+ vtkTypeRevisionMacro(vtkEDFCutter, vtkCutter);
+ void PrintSelf(ostream& os, vtkIndent indent);
+
+ // Description:
+ // these ivars
+ // control the name given to the field in which the ids are written into. If
+ // set to NULL, then vtkOriginalCellIds or vtkOriginalPointIds (the default)
+ // is used, respectively.
+ vtkSetStringMacro(OriginalCellIdsName);
+ virtual const char *GetOriginalCellIdsName() {
+ return ( this->OriginalCellIdsName
+ ? this->OriginalCellIdsName : "vtkOriginalCellIds");
+ }
+
+protected :
+ virtual int RequestData(vtkInformation *,
+ vtkInformationVector **,
+ vtkInformationVector *);
+
+ virtual void AssembleOutputTriangles(vtkPolyData* inpd,
+ vtkPolyData* outpd);
+
+ char* OriginalCellIdsName;
+
+ vtkEDFCutter();
+ ~vtkEDFCutter();
+
+private:
+ vtkEDFCutter(const vtkEDFCutter&); // Not implemented.
+ void operator=(const vtkEDFCutter&); // Not implemented.
+};
+
+#endif //__vtkEDFCutter_h__
--- /dev/null
+// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkEDFFactory.h"
+#include "vtkVersion.h"
+#include "vtkEDFCutter.h"
+
+vtkStandardNewMacro(vtkEDFFactory);
+
+VTK_CREATE_CREATE_FUNCTION(vtkEDFCutter);
+
+vtkEDFFactory::vtkEDFFactory()
+{
+ this->RegisterOverride("vtkCutter",
+ "vtkEDFCutter",
+ "MergeTriangles",
+ 1,
+ vtkObjectFactoryCreatevtkEDFCutter);
+}
+
+const char* vtkEDFFactory::GetVTKSourceVersion()
+{
+ return VTK_SOURCE_VERSION;
+}
+
+const char* vtkEDFFactory::GetDescription()
+{
+ return "VTK EDF Factory";
+}
+
+VTK_FACTORY_INTERFACE_IMPLEMENT(vtkEDFFactory);
--- /dev/null
+// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkEDFFactory_h
+#define __vtkEDFFactory_h
+
+#include "vtkEDFOverloadsDefines.h"
+#include "vtkObjectFactory.h"
+
+class VTKEDF_OVERLOADS_EXPORT vtkEDFFactory : public vtkObjectFactory
+{
+public:
+// Methods from vtkObject
+ vtkTypeMacro(vtkEDFFactory,vtkObjectFactory);
+ static vtkEDFFactory *New();
+
+ virtual const char* GetVTKSourceVersion();
+ virtual const char* GetDescription();
+protected:
+ vtkEDFFactory();
+private:
+ vtkEDFFactory(const vtkEDFFactory&); // Not implemented.
+ void operator=(const vtkEDFFactory&); // Not implemented.
+};
+
+extern "C" VTK_EXPORT vtkObjectFactory* vtkLoad();
+#endif
--- /dev/null
+// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef VTKEDF_OVERLOADS_DEFINES_H
+#define VTKEDF_OVERLOADS_DEFINES_H
+
+#if defined WIN32
+# if defined VTKEDF_OVERLOADS_EXPORTS || defined vtkEDFOverloads_EXPORTS
+# define VTKEDF_OVERLOADS_EXPORT __declspec( dllexport )
+# else
+# define VTKEDF_OVERLOADS_EXPORT __declspec( dllimport )
+# endif
+
+# if defined VTKTOOLS_EXPORTS || defined vtkTools_EXPORTS
+# define VTKTOOLS_EXPORT __declspec( dllexport )
+# else
+# define VTKTOOLS_EXPORT __declspec( dllimport )
+# endif
+
+#else
+# define VTKEDF_OVERLOADS_EXPORT
+# define VTKTOOLS_EXPORT
+#endif //WIN32
+
+#endif //VTKEDF_OVERLOADS_DEFINES_H