From 160698311c8deb02d7eb674f3a94f88d7199a877 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 9 Aug 2012 12:49:01 +0000 Subject: [PATCH] Merge from V6_main_20120808 08Aug12 --- Makefile.am | 23 +- build_cmake | 27 + build_cmake.bat | 20 + build_configure | 26 +- clean_configure | 33 + configure.ac | 40 +- doc/Makefile.am | 85 ++ doc/_static/basic.css | 433 ++++++++++ doc/_static/default.css | 210 +++++ doc/advanced.rst | 52 ++ doc/conf.py.in | 185 +++++ doc/images/jobmanager_job_focus.png | Bin 0 -> 34068 bytes doc/images/jobmanager_job_workflow_1.png | Bin 0 -> 24693 bytes doc/images/jobmanager_job_workflow_2.png | Bin 0 -> 20395 bytes doc/images/jobmanager_job_workflow_3.png | Bin 0 -> 21901 bytes doc/images/jobmanager_job_workflow_4.png | Bin 0 -> 28511 bytes doc/images/jobmanager_job_workflow_5.png | Bin 0 -> 21324 bytes doc/images/jobmanager_job_workflow_6.png | Bin 0 -> 11177 bytes doc/images/jobmanager_load_save_buttons.png | Bin 0 -> 43789 bytes doc/images/jobmanager_main_buttons.png | Bin 0 -> 35060 bytes doc/images/jobmanager_overview.png | Bin 0 -> 101581 bytes doc/images/jobmanager_overview_part.png | Bin 0 -> 142356 bytes doc/images/jobmanager_resource_1.png | Bin 0 -> 12170 bytes doc/images/jobmanager_resource_2.png | Bin 0 -> 36341 bytes doc/index.rst | 21 + doc/intro.rst | 50 ++ doc/job.rst | 99 +++ doc/jobmanager_gui.rst | 146 ++++ doc/resource.rst | 167 ++++ idl/JOBMANAGER_IDL.idl | 30 + idl/Makefile.am | 47 ++ m4/ac_cxx_option.m4 | 27 +- m4/ac_linker_options.m4 | 27 +- m4/acx_pthread.m4 | 224 ++++++ m4/check_boost.m4 | 176 ++++ m4/check_omniorb.m4 | 36 +- m4/check_salome.m4 | 26 +- m4/check_sphinx.m4 | 26 +- m4/enable_pthreads.m4 | 21 + m4/i2_check_qt4.m4 | 125 +-- m4/production.m4 | 27 +- src/Makefile.am | 26 +- src/bases/BL_Exception.cxx | 26 +- src/bases/BL_Exception.hxx | 38 +- src/bases/BL_Traces.hxx | 26 +- src/bases/Makefile.am | 26 +- src/bases/make_begin.am | 27 +- src/engine/BL_Engine.hxx | 32 + src/engine/BL_Job.cxx | 228 +++++- src/engine/BL_Job.hxx | 86 +- src/engine/BL_JobsManager.cxx | 466 ++++++++--- src/engine/BL_JobsManager.hxx | 91 ++- src/engine/BL_Observer.hxx | 41 + src/engine/BL_SALOMEServices.cxx | 561 +++++++++++-- src/engine/BL_SALOMEServices.hxx | 78 +- src/engine/Makefile.am | 37 + src/genericgui/BL_Buttons.cxx | 133 ++- src/genericgui/BL_Buttons.hxx | 43 +- src/genericgui/BL_CreateJobWizard.cxx | 754 ++++++++++++++---- src/genericgui/BL_CreateJobWizard.hxx | 216 +++-- src/genericgui/BL_GenericGui.cxx | 489 +++++++++--- src/genericgui/BL_GenericGui.hxx | 66 +- src/genericgui/BL_GenericGuiDefines.hxx | 32 + src/genericgui/BL_JobTab.cxx | 194 +++-- src/genericgui/BL_JobTab.hxx | 52 +- src/genericgui/BL_JobsManager_QT.cxx | 314 ++++++-- src/genericgui/BL_JobsManager_QT.hxx | 61 +- src/genericgui/BL_JobsTable.cxx | 109 ++- src/genericgui/BL_JobsTable.hxx | 40 +- src/genericgui/BL_MachineCatalog.cxx | 66 -- src/genericgui/BL_MachineCatalog.hxx | 54 -- src/genericgui/BL_MainButtons.cxx | 0 src/genericgui/BL_MainButtons.hxx | 0 src/genericgui/BL_QModelManager.cxx | 84 +- src/genericgui/BL_QModelManager.hxx | 31 +- src/genericgui/BL_Summary.cxx | 26 +- src/genericgui/BL_Summary.hxx | 26 +- src/genericgui/JM_EditSalomeResource.cxx | 391 +++++++++ src/genericgui/JM_EditSalomeResource.hxx | 80 ++ src/genericgui/JM_ResourceCatalog.cxx | 171 ++++ src/genericgui/JM_ResourceCatalog.hxx | 68 ++ src/genericgui/JM_SalomeResource.cxx | 189 +++++ src/genericgui/JM_SalomeResource.hxx | 69 ++ src/genericgui/Makefile.am | 44 +- src/salomegui/BL_SalomeGui.cxx | 101 ++- src/salomegui/BL_SalomeGui.hxx | 41 +- src/salomegui/JOBMANAGER_version.h.in | 34 + src/salomegui/Makefile.am | 40 +- .../{SalomeApp.xml => SalomeApp.xml.in} | 10 +- src/standalone/Makefile.am | 22 + src/standalone/main.cxx | 19 + src/standalone/start_jobmanager.sh.in | 26 +- src/wrappers/BL_MainWindows_Qt.cxx | 32 +- src/wrappers/BL_MainWindows_Qt.hxx | 44 +- src/wrappers/BL_MainWindows_SALOME.cxx | 96 ++- src/wrappers/BL_MainWindows_SALOME.hxx | 61 +- src/wrappers/BL_MainWindows_Wrap.hxx | 32 +- src/wrappers/Makefile.am | 31 +- 98 files changed, 7069 insertions(+), 1520 deletions(-) create mode 100755 build_cmake create mode 100644 build_cmake.bat create mode 100755 clean_configure create mode 100644 doc/Makefile.am create mode 100644 doc/_static/basic.css create mode 100644 doc/_static/default.css create mode 100644 doc/advanced.rst create mode 100644 doc/conf.py.in create mode 100644 doc/images/jobmanager_job_focus.png create mode 100644 doc/images/jobmanager_job_workflow_1.png create mode 100644 doc/images/jobmanager_job_workflow_2.png create mode 100644 doc/images/jobmanager_job_workflow_3.png create mode 100644 doc/images/jobmanager_job_workflow_4.png create mode 100644 doc/images/jobmanager_job_workflow_5.png create mode 100644 doc/images/jobmanager_job_workflow_6.png create mode 100644 doc/images/jobmanager_load_save_buttons.png create mode 100644 doc/images/jobmanager_main_buttons.png create mode 100644 doc/images/jobmanager_overview.png create mode 100644 doc/images/jobmanager_overview_part.png create mode 100644 doc/images/jobmanager_resource_1.png create mode 100644 doc/images/jobmanager_resource_2.png create mode 100644 doc/index.rst create mode 100644 doc/intro.rst create mode 100644 doc/job.rst create mode 100644 doc/jobmanager_gui.rst create mode 100644 doc/resource.rst create mode 100644 idl/JOBMANAGER_IDL.idl create mode 100644 idl/Makefile.am create mode 100644 m4/acx_pthread.m4 create mode 100644 m4/check_boost.m4 create mode 100644 m4/enable_pthreads.m4 create mode 100755 src/engine/BL_Engine.hxx create mode 100644 src/engine/BL_Observer.hxx create mode 100644 src/engine/Makefile.am create mode 100755 src/genericgui/BL_GenericGuiDefines.hxx delete mode 100644 src/genericgui/BL_MachineCatalog.cxx delete mode 100644 src/genericgui/BL_MachineCatalog.hxx delete mode 100644 src/genericgui/BL_MainButtons.cxx delete mode 100644 src/genericgui/BL_MainButtons.hxx create mode 100644 src/genericgui/JM_EditSalomeResource.cxx create mode 100644 src/genericgui/JM_EditSalomeResource.hxx create mode 100644 src/genericgui/JM_ResourceCatalog.cxx create mode 100644 src/genericgui/JM_ResourceCatalog.hxx create mode 100644 src/genericgui/JM_SalomeResource.cxx create mode 100644 src/genericgui/JM_SalomeResource.hxx create mode 100644 src/salomegui/JOBMANAGER_version.h.in rename src/salomegui/resources/{SalomeApp.xml => SalomeApp.xml.in} (69%) diff --git a/Makefile.am b/Makefile.am index f8238b2..77eedc3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,24 @@ +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src +SUBDIRS = idl src doc + +EXTRA_DIST = build_configure clean_configure diff --git a/build_cmake b/build_cmake new file mode 100755 index 0000000..a81bdd4 --- /dev/null +++ b/build_cmake @@ -0,0 +1,27 @@ +#!/bin/sh +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +CURRENT_DIR=`pwd` +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} +python $KERNEL_ROOT_DIR/salome_adm/cmake_files/am2cmake.py --jobmanager +status=$? +cd ${CURRENT_DIR} +exit $status diff --git a/build_cmake.bat b/build_cmake.bat new file mode 100644 index 0000000..b669ddb --- /dev/null +++ b/build_cmake.bat @@ -0,0 +1,20 @@ +@REM Copyright (C) 2009-2012 CEA/DEN, EDF R&D +@REM +@REM This library is free software; you can redistribute it and/or +@REM modify it under the terms of the GNU Lesser General Public +@REM License as published by the Free Software Foundation; either +@REM version 2.1 of the License. +@REM +@REM This library is distributed in the hope that it will be useful, +@REM but WITHOUT ANY WARRANTY; without even the implied warranty of +@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@REM Lesser General Public License for more details. +@REM +@REM You should have received a copy of the GNU Lesser General Public +@REM License along with this library; if not, write to the Free Software +@REM Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +@REM +@REM See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +@REM + +%PYTHONBIN% %KERNEL_ROOT_DIR%\salome_adm\cmake_files\am2cmake.py --jobmanager diff --git a/build_configure b/build_configure index e3987c4..0f0908e 100755 --- a/build_configure +++ b/build_configure @@ -1,21 +1,21 @@ #! /bin/sh -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # ORIG_DIR=`pwd` diff --git a/clean_configure b/clean_configure new file mode 100755 index 0000000..02e09a0 --- /dev/null +++ b/clean_configure @@ -0,0 +1,33 @@ +#! /bin/sh +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# --- +# File : clean_configure +# Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) +# --- +# +rm -rf autom4te.cache aclocal.m4 configure config.guess config.sub build_configure.log install-sh ltmain.sh missing depcomp +rm -rf jobmanager_config.h.in INSTALL +find . -name "*~" -print -exec rm {} \; +find . -name "*.pyc" -print -exec rm {} \; + +# ... + +find . -name Makefile.in | xargs rm -f diff --git a/configure.ac b/configure.ac index da46773..c3640f9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,27 +1,28 @@ -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -- # Author : André RIBES (EDF) # -- # ----------------------------------------------------------------------------- # -AC_INIT([JOBMANAGER project], [0.1], [andre.ribes@edf.fr], [JobManager-Module]) +AC_INIT([JOBMANAGER project], [6.5.0], [andre.ribes@edf.fr], [JobManager-Module]) AM_INIT_AUTOMAKE([tar-pax]) AC_CONFIG_HEADER(jobmanager_config.h) @@ -29,7 +30,9 @@ AC_CONFIG_HEADER(jobmanager_config.h) MODULE_NAME=jobmanager AC_SUBST(MODULE_NAME) -XVERSION=0x001 +SHORT_VERSION=`echo $VERSION | awk -F. '{printf("%d.%d",$1,$2)}'` +AC_SUBST(SHORT_VERSION) +XVERSION=`echo $VERSION | awk -F. '{printf("0x%02x%02x%02x",$1,$2,$3)}'` AC_SUBST(XVERSION) RELEASE=$VERSION @@ -76,6 +79,7 @@ AM_PROG_LIBTOOL AC_CHECK_LIB(dl,dlopen) I2_CHECK_QT4 AC_CHECK_OMNIORB +CHECK_BOOST # Optional products CHECK_SPHINX @@ -98,6 +102,7 @@ echo echo "Mandatory products:" echo " Qt4 (graphic interface) : $qt_ok" echo " OmniOrb (CORBA) ........ : $omniORB_ok" +echo " Boost ........ : $boost_ok" echo " SALOME KERNEL .......... : $Kernel_ok" echo " SALOME GUI ............. : $SalomeGUI_ok" echo @@ -122,6 +127,7 @@ fi AC_OUTPUT([ \ Makefile \ + idl/Makefile \ src/Makefile \ src/bases/Makefile \ src/engine/Makefile \ @@ -130,4 +136,8 @@ AC_OUTPUT([ \ src/standalone/Makefile \ src/standalone/start_jobmanager.sh \ src/salomegui/Makefile \ + src/salomegui/JOBMANAGER_version.h \ + src/salomegui/resources/SalomeApp.xml \ + doc/Makefile \ + doc/conf.py \ ]) diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..ab44650 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,85 @@ +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/src/bases/make_begin.am + +.PHONY : latex + +if SPHINX_IS_OK + +jobmanagerdoc_DATA=html/index.html +html/index.html:$(RSTFILES) + make htm +endif + +#EXTRA_DIST= html htmldev _static +EXTRA_DIST= html html/index.html _static images + +jobmanagerdocdir=$(docdir)/gui/JOBMANAGER + +SPHINXOPTS = +SOURCEDIR = $(srcdir) +SPHINXBUILD = sphinx-build +PAPEROPT_a4 = -D latex_paper_size=a4 +ALLSPHINXOPTS = -d doctrees $(PAPEROPT_a4) $(SPHINXOPTS) $(SOURCEDIR) + +htm: + mkdir -p html doctrees + $(SPHINXBUILD) -c $(top_builddir)/doc -b html $(ALLSPHINXOPTS) html + @echo + @echo "Build finished. The HTML pages are in html." + +latex: + mkdir -p latex doctrees + $(SPHINXBUILD) -c $(top_builddir)/doc -b latex $(ALLSPHINXOPTS) latex + @echo + @echo "Build finished; the LaTeX files are in latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +html: + mkdir -p $@ + +#htmldev: +# mkdir -p $@ + +RSTFILES= \ +index.rst \ +intro.rst \ +resource.rst \ +job.rst \ +jobmanager_gui.rst \ +advanced.rst + + +EXTRA_DIST+= $(RSTFILES) + +install-data-local: + $(INSTALL) -d $(DESTDIR)$(jobmanagerdocdir) + if test -d "html"; then b=; else b="$(srcdir)/"; fi; \ + cp -rf $$b"html"/* $(DESTDIR)$(jobmanagerdocdir) ; \ + if test -f $$b"latex"/jobmanager.pdf; then cp -f $$b"latex"/jobmanager.pdf $(DESTDIR)$(jobmanagerdocdir) ; fi; + +uninstall-local: + chmod -R +w $(DESTDIR)$(jobmanagerdocdir) + rm -rf $(DESTDIR)$(jobmanagerdocdir)/* + +clean-local: + -rm -rf html latex doctrees + if test -d "html"; then rm -rf html ; fi diff --git a/doc/_static/basic.css b/doc/_static/basic.css new file mode 100644 index 0000000..aeb1381 --- /dev/null +++ b/doc/_static/basic.css @@ -0,0 +1,433 @@ +/** + * Sphinx stylesheet -- basic theme + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0 solid #dce; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 2px 5px 2px 5px; + border-left: 0; + background-color: #eef; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +table.docutils th { + border-top: 1px solid #cac; + background-color: #ede; +} + +th { + text-align: left; + padding-right: 5px; +} + +th.head { + text-align: center; +} + +/* -- other body styles ----------------------------------------------------- */ + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlight { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +p.deprecated { + background-color: #ffe4e4; + border: 1px solid #f66; + padding: 7px +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa +} + +.impl-detail { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; + border: 1px solid #ccc; +} + +.impl-detail .compound-first { + margin-top: 0; +} + +.impl-detail .compound-last { + margin-bottom: 0; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} diff --git a/doc/_static/default.css b/doc/_static/default.css new file mode 100644 index 0000000..c999f67 --- /dev/null +++ b/doc/_static/default.css @@ -0,0 +1,210 @@ +/** + * Sphinx stylesheet -- default theme + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} \ No newline at end of file diff --git a/doc/advanced.rst b/doc/advanced.rst new file mode 100644 index 0000000..6f87c16 --- /dev/null +++ b/doc/advanced.rst @@ -0,0 +1,52 @@ +Advanced part +============= + +This chapter is a melting pot of information about what the JOBMANAGER do. + +Logs files +++++++++++ + +Whatever the type of job, the JOBMANAGER provides many files for logging +what happens during the job. These files are located in the work directory +of the job in a directory named **logs**. + +For **command** type of job, one log file is created. This file contains the normal +and error output of the job. The file name contains the type of job and the date, e.g. +**command_Thu_Sep_30_15_04_51_2010.log**. + +For **SALOME** type of job, two log files are created. The common file contains the +normal and error output of the SALOME services. The file name is like this: +**salome_Wed_Feb_10_13_54_00_2010.log**. The other file depends of the type of SALOME jobs: + +- For **Python** type of job, the file contains all the output of the scripts. The file name is + like this: **python_Wed_Feb_10_13_54_00_2010.log**. +- For **YACS** type of job, the file contains all the output of the schema. The file name is + like this: **yacs_Wed_Feb_10_13_54_00_2010.log**. + +For jobs that are launched in a batch resource like PBS or LSF, two more files are provided +that contains the normal and error output messages of the PBS or LSF job. These files are like this: +**error.log.runCommand_test_command_Wed_Sep__8_17_02_44_2010** and +**output.log.runCommand_test_command_Wed_Sep__8_17_02_44_2010** + +How the JOBMANAGER launch the job ++++++++++++++++++++++++++++++++++ + +For each type of job, the JOBMANAGER creates a shell that permits to launch in the resource +the job file. It's in this file that the environment file is used. For a command job, +the file name is like this: **runCommand_test_command_Wed_Sep__8_16_59_08_2010.sh**. + +If a job has to be launched in a resource with a batch manager like PBS or LSF an another +file is created that contains batch directives. For a command job, the file name is like +this: **runCommand_test_command_Wed_Sep__8_16_59_08_2010_Batch.sh**. + + +Current limitations ++++++++++++++++++++ + +Currently, for SALOME type of jobs, the scope of the environment file is +restricted to the main SALOME session. Distributed containers launched in remote +computers are not in the scope of the environment file. If you want to give an environment file to all +your containers, use a SALOME application and copy this environment file into the **env.d** +directory. + +Currently, logs files do not contain remote containers outputs. diff --git a/doc/conf.py.in b/doc/conf.py.in new file mode 100644 index 0000000..053e397 --- /dev/null +++ b/doc/conf.py.in @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# +# jobmanager documentation build configuration file, created by +# sphinx-quickstart on Fri Aug 29 09:57:25 2008. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed automatically). +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If your extensions are in another directory, add it here. If the directory +# is relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +#sys.path.append(os.path.abspath('.')) + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'jobmanager' +copyright = '2010-2011 CEA/DEN, EDF R&D, A. Ribes' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '@SHORT_VERSION@' +# The full version, including alpha/beta/rc tags. +release = '@VERSION@' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directory, that shouldn't be searched +# for source files. +exclude_trees = ['.build','ref','images','CVS'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# Options for HTML output +# ----------------------- + +# The theme to use for HTML and HTML Help pages. Major themes that come with +# Sphinx are currently 'default' and 'sphinxdoc'. +html_theme = 'default' + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +html_use_modindex = False + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, the reST sources are included in the HTML build as _sources/. +#html_copy_source = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'jobmanagerdoc' + + +# Options for LaTeX output +# ------------------------ + +# The paper size ('letter' or 'a4'). +latex_paper_size = 'a4' + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, document class [howto/manual]). +latex_documents = [ + ('index', 'jobmanager.tex', 'Jobmanager User Documentation', 'A. Ribes', 'manual') +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +latex_use_modindex = False diff --git a/doc/images/jobmanager_job_focus.png b/doc/images/jobmanager_job_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..5d583d5a3a816160c4d63ae8c599cc5869fae17b GIT binary patch literal 34068 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 SX-NHNI<0G@lX=qS?*9Q**Mju` literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_job_workflow_2.png b/doc/images/jobmanager_job_workflow_2.png new file mode 100644 index 0000000000000000000000000000000000000000..529c2faa91591a762c7c892f7de378a836edaa1e GIT binary patch literal 20395 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 literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_job_workflow_4.png b/doc/images/jobmanager_job_workflow_4.png new file mode 100644 index 0000000000000000000000000000000000000000..6e2e147819ef54a0f83c2fde2c9d68f2af77a81e GIT binary patch literal 28511 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�|K34h{~armp%$0N)!TUPQGAPfXww2BL^zAloCR3V;fXjE?>bmPAnU zd3Q7l?m7`JKka)W9uQUMTp$?Q|Bq+rD zuqV^-4dlRIAoD|k=(esD-rO)eH)oNTbv35Q7${5A9VvmTJ)QsP6+#@g49s;ZC<0a^ zeG?Lz=>i*&pU5jH;1|c(;r^0dlp>w$$wthJfa0G?qvtW&WnMr@h5v+x0je=`Lt;xlg1Mld}r|G%8$HN3=;fVLoAFC z4xY6}y_3FqM1a`wkb2niluGntpX{lrsX2qiY_2EH)ke2@pO)7!j}}IZA~+0d=;{Ux zR=5UEKy??yA+M{ds@hA3;3=xah>=-YS%F?b;Y}~xn$tY$#*R;;KRvS#glRLXTkGp} zA!w&+Fd?3{9VoP_{gAGu0j8U(M}2P}yvxW8S!*~eJzD*PK*V_%sBD*SJpD<@3sj^L zw2xfMJ;C&l3cW2W5!>;flESP#x%uem0PH7^-yK5y4~oVKW&RLaC31Y(d)j326?QP0 zxuTqVRPD*Z#U=aujB77@@Kvp?QlQt1OAn+wX=#JkUu?POzib9uQMS~YiW&A=HHMVwU;FPijwDjaQXYvx72BaKrr^M4g@S%Ljl zd9bMmVe?3OYJ3es8Cw~>4Te@wPlf^(8Cc&64je+v#QOXc2PgOAp+gUyy!=9~q7AWr z_DIC`0*c`860okDgJ49-_OnovBt?! zc8C(LO|}ROC_u)F@&>RJ5^k{c;cNw|3A)=$FSxH<2XWB>-~nh`8NxAImOk+-JSyO+XlcltA+?_PBj7WNy1yz zfdWSIkg0$agby?>&joc~y1TK1ANN@jZ~Qa7hUK&ty_r}*i170+~^-y$vI`dpUgFz=Yo%3 z6UpC~=H^$cmaZOZe|(b;LUn^SG_%~brc10#_HW8m#PHG7meZ2^v6tFNTovj0ybjkFA`=txYU>n=kU8Z;xN?@RA{5+vX!_CQb) zb`@S^LvHs%yg4Nw>J$GJ7NlU=9ogst(Sc6(BzZrM0|{0<4f{>+_m1($VU_u8f8_#! zDVh3l)r9D{AVR14aE*xwsVPvROa)I$8gF1tN6Hj%IN1Ie>IG27!9R(ks5#-r;5)OD zlqM3QaS_UB?xjZHd*8!LJMXP@I_+Ztru$dfm^o+S!)bL)Ow}Uho=p)GuD2Rz1MfuR zSu9M~Kq>7X_Ue>Gn>sX*rQ)Or~RDw4|`g*-ng&7kFNAwr)|b`7Fz8&u#fI5#m(Gs z&bndnP&-@LAk~m(G43ed^wgUjPb0(M28O9p6(XcP1JAunb9t=Q4O}<$zSUZb+BMN8 z4HSm5qkI~v&N<9j8L^A<4^%D|7cA&@`sVJC%@w`(bHzSYjoC==?RQq0==fWyl^~*m zHEr?K6i!GvpjVj8bu{#$?o=(%Oel3|nk{=p-{ezLs9JITeDx7QdHUH8S?^N{;Qe-} NySLTkvt^C{{U7|LUb6rI literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_job_workflow_5.png b/doc/images/jobmanager_job_workflow_5.png new file mode 100644 index 0000000000000000000000000000000000000000..bac2e8755f1e59901cc213e61d85b8263129d954 GIT binary patch literal 21324 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 literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_job_workflow_6.png b/doc/images/jobmanager_job_workflow_6.png new file mode 100644 index 0000000000000000000000000000000000000000..b013fe7e49cc721169b42f3726375e98befcf514 GIT binary patch literal 11177 zcmZX4cU%+M_jW9+V!?t6Qe8n%5s)HHimp^?N|h2psgWuWdV*yYk+yW{N(mj55+p!k z0~7?L3!#WKsaZ-WDdfE~@w>a9_xA^g$;_Q|&v{OHo;%^!4Yd#K<=u-wAP(s2Xc!|9 z+t$EO)1F=6lP9r-hrvG_UOJXO2n44A_z~Uqc4*KMd?@X!dDBia=^gvv7 zyY1uSc+$b~q?4n^tgpADkMhYIz7js@JGZ^O+)(znp{op4tF6Gz+|bRYC~y(ts<-29 zU&oWzJnx*eKn30QcG&TADIS41iO|)!Vj7UXFdQ6WO3h#`tt-in9eH^F&=C*bQ_uJ6 zG%$S|B&Zdp=d-^@(QXz$e9^b>_xs#Mhe~YDopMDtm>#M==vpILM!vhyH>i#F&wFOG z^NQr@aGk#n-8}qw=ch00>$@|SzD#_PNIA4jrG}_X#isZWYgRI3S3a)?x2KQ$&U7{M z*iR@%^Eb!N5jsh++7sxLhn`vrlFlF6qajo_caCSjsLfQ(NS!3s@&eB)a#7-vWy6SH z(3~z_U_>pvB<8#izgTKhd3k*xvOh8RdHslE9B;!Kj!KM{(u<3fmJWZ_d{BYdA;dWmhv3&Qas;$?BHORIrUN~!g?{qKOD)Gh^3+152D*`?5F4_D5ghRF zO#4AUO{CP%)sv61uypEeMi2?pAyvN4TvJ=OrnFIpN#iS*qH~@+dE%1#$+@*0xs(;Z z;e85oC~$E&Yx{%CtEy2(d;|IQS!NXHk93tzKM~qcAeoPZ499oVRkkX5&x&D3mlxB* zKYE6ZIxArtY_Sw?&n!`zO>=T`!Qw`Tc6QYWQ#>QgKdpX})*D;kLBd9is_E|C^~ihs zgZne1q)<5%M*C!T9N4$3BqB*!q+^96qa?AFV&9YwjOH z^lkMBUsvt+%QFcTF(_iRNi<6#mFZ^LjFHeI%!k)1mSqc@%ZCfQ^69r6tjq~?V^MN~ zZrzc|C|3TUC(@+VC_%KlM+la;L~S}rfr4c7tIQ88djwwWt?0{4{JH%G_i5(vs| z8JE_*?AD|ABM_I#3Gwkcb_8Kg1j5VLhhO`OF0Z1O-Iw=$>Cci=6^>C9wfjx$N7vqX z;8;3&>m3#$wF9Zo*2zyC9P>xiJZ-Ti=88ibiq;hsr@FhsR_UX?THDr7i$X5s zdYg2IR^DleQBTVX{AqFFiXn<@LXiqHEjK_=;k&`hZcr$e*-L|W2j z58WgzxX$7ON!)mMvZ$DtShK_2zU>G^Ri@nqo|I=sp*--10m9tq^>aa_fsbM_&3%@Gb>KyfY25*hww$%QVsE9VPDwQ z*tdfE;vY1*k-5_LW!FhqrtiLw_hfmw=9{Ry*nJT^0BJbtt?4W2=UchlDKi|*wLc} z+1bXeNfHr~>h$?aGn*k>*S?b8!D`nu8=~~ss`k9FmQ6Ox-q=&*a`}2s+EpS?t`AIoqA@FK2M_(AQ6~IjO^o zZdE4`UaMf?WSsulc#&arzlfQsY0;ZEB&RQLY;8lC)oL5xA30$<6y$z-*%?jORM|I0 zCW%N`Rox6;UrZEX{@@PNenny~xJsk6qX>U&Zf+7LlfsoZCw||%bGudDn!PHur+cv0 z$623tHH@>cXx2pHR{hPDskSJ|P$qR0XO<+?k2bq`v%uOTrQr9gyY%AvO0CQDGlQ%y zUc4AJ`wd@ewePq}k%Tq=V?w3(_Tj=%r{D4W<7)$<0UY2_3gCq%S+~t!m>L{5-adAfylRLVI7`j~O z)`wJ?JpJx`mPU@Y?FskGtSu(>lkmafD&IJ*7@{$2Nl5SX*;G+8ODw1bI75lUr# zyDXNaqCsD$SYR*>YMTyM^+R`V-xei^$y;7t2Bu#vDlLtYTp>@9J?e&QSc~;5oYV!f z7%nPyc^ksLpU;zVtFf_>@b~+DRW6-UBDx)_H5yqV%es}M@tg;$8Ci9`eSJl*UR{6u z_%V&KB0xlqgtB&Mmc{wK=MdA0YiV`X>dy-Jaak$4SWl`!Ls&c76pM}dsde<|(T`Oh z=qi?$SpMdysm+aXYNzKd#TDh7);3;3sxgsdE#{rd9J zlLMD*$#^r@w$$poE_*KC^{?|=ki*a#0A7MtJDa;koIF_q{x&2n_ecsiC{L?Re5C%z z+_w&4m|OJL%4O!FV)Vl>Pu*0)t5N16+TgiYWm8n$4I@=*WF*I2QE^$9Plv?P(E=CC zP&)ZIX8O|UR1ikH%-`{S7(A=qKYHn`c2sQ^2(w#V2daJ?8!sg!N<(1%q>^l)4 z7Cq&o=)0rDhOHI#Q1Th0li%+yPw1XIcdl!7M!oaF4(i#OfpV4_eO~t1v15%@(gX54 z5Q9$)Gn8jCgE>16m0Q;sKH7b-uVLM=yTnqx7l16)3_rd7Vqtj}v(Gxz`0CY1k`2Cp zW@2f&pl6zyn~T;r{;-c>+Njeyse}c*bwYA7Hxk=+(Z1Su#u!SIsgBS$Hy+&zWgft= z=pU*Bma<)F4vvle0<{)@kH@ILTpDlIyyV%IdNF8ipi$aAQs2{abgLFT;KV5QX03Ok zsQw$vFiwH4{45W%TemX#n{QmX^1!^*Y9Tn7RN1a<5?AFlmV(RuoCt?%#$u@_MOGB7Pr3Ze&Y{wPB8-1b?XV z7!GPnrJCp(=Nr}rF_yB#rOM+oL$@@UTkD?kwP-4pKH*Cl8TMTqs{Z_#U*cBKjHWx; zymUG%^h#Dp#mnln9f-@qnwrhx3JMlkSX$xQ0$B)|nKgP96tF>3D5WG0lnMfX6p(J4gKFZG)$T?J9R?UvxYx$v(0*aBCJXF_0 z%__w)2A^9?;iCl4xdbx>RmC&kasn`O@85NB_ZnVt_^%ZGe6zttx&1Ql==}piMSj%`#ec^&WX5*cwwmYM;%9r**N*5<9 zG9xI7N*7%T;$#_^c`Uo@<;7|ilf!?XZ$Lqyb)Z6=D`We{(uY=5Vw`5ynM zL`turG`vs1L)$6PxK!`BPW@(FGR4+#V&xEPzbSdHzqNE~Wi7Bf zPw0yH_Mp+2okddcnB z#4{u?*4C*t8nJNa)Z>E~gBj;A1d1lkF|SU_G03Gri5^#D#GqYD8#Nn|OTlt>pOx*V z$rR?Cb##!$h@y-qQM3Lid{yR|1f{wXbL?XG;zAVb+Kf?G=M4i%F|>zmVAmqmPgYCn$(Sg7vL?&vSETq)g) z*FM7Bk7yeQC3fdp&s|s7oQ|;lCyro7hTe83FtqhvxrRf}*pG0(5y5ZInk_D0eY@kJ z%csA7Z)s~YYmOGU81T2m52#Gz;oepyr@A}d&Z@l8L)qj z{jv6>rGuWdPvdVN>>$jQ)%BEGE1(w!&BmK!`nQ;LOm|RnU}L_n@BGDhY)5WX_(t`3 zgcR{Q3RQUR+O?k7_S)5+qqk024B1?13v={c1*w zlzP^Ou!Ba$F~*7hA~dC8ypyq!C_Pa+g;Im~tL1dE&7BJ6J6TFTIC+nuGrGL8PLUui z)vo=LQ72@zy2d&`N1l)kSrJqTcy)s|T<2d59PQXJIXOAl5bUqtP+eVJR9SVI*Y$LaAq-5}9qD9;k z>KdkPW*t{09ZOZiM$7EdxH%1xsMN>a_`3Xeu@<~Fy9e;fhSVZ)y3thq`L3V>%M`8 zhS8oU!n<}qdY9nNv2**`)+M|wpbeAUUfCz(iVoJd{_*nqAj;%F57nc0Y73>Tbf}Li zMsrn;+~cqG8hbCAnBo%XLuZE#M>oUKB@nqX-V-|Uy;*f&kk`oa947Rx*MgBhdlfX7 zvvX9Ou4y!w|8K7bYHDhJsVZOZw9%gB-VJ>0hQIgo>&u|^VSg&{|4-)nXn%d+iimC# z4MfeMv38q~GqF@;858q=xeIF-_g4qlr_Ezx8Kk+Hn;GAqXQBT30;NF&-slQ&V zziy4tnOts_QXtG070a~00p#{)a=UahKUbwkN2aP1ZFR=!>x(Nmz&mh&1We_|8_EFJ zW(|PRMBj>%YynFASqX`YszIw4YHMqqK0ZC{G)zFFYEVoXb*f8G>SBg6S_b+yFE0;A zB&v;ZPrQ4yyN%08<@VN+5UUed-v(xJpD)tQ&%2G(hxJor8cS}zeqWOjKA6>31?D_x zO`OkkJL)$-`_vK2%=z{4WWRw5N2m9Ha!mcnWq3hJNeQwImz(<$#Hcr9b21t1vvYY0 zXHZj`vS#*AA@~B4(j&dNjL?!xUlFyBga*mP#6;9gS6*DMo@A|tCvnrsYI7Una_b3M zCw(V{2jS|1S;@)yN$Hg^Of z)Q_c~R6-5zH+BCV;8RPI&?N-I1*w4s{p;OlAh)q^(o_@|L?9yGl(j;ieS6O%oE%&N z`rd9WXx%3T(7JCp_JhZ9$X|R#qRkec?FQuyr|T%R0On8m4ucJ9c_?6R#=Si~4%Ie@ zw>1%SguU{o?QyLAB74nydwb7GNc3iHt%`v^XTHdG^bGrtmc|NeYt4PudZCw}?zVeQ zUq4OWpqxl6YFC<0H}}+&-*gX?An!tG3pd}BIXE91OKUL`pHwtl9V3)cR^qtyjwD_5 zo4=V6yjUCbBV4Sf+SP&ytmyr4P@Vt4ytc9Ht~5a7GcaodrRJ`-l`vhU9qhlRCVrrR^5 z7p&fRy`)j+xZNXcm9S*48@9IP99*IWddZTrU3n3rhUo<~8twV&L3PHfy?gie6q<-d z@hKRBR;zQm1>(vN$#nto7(JsvTaDJw0@HsH!g1Cdk$0T~yG5M8!bsQZX!SG;F z<1t)i_wHftrb%zg-8u$dI3DZAuWh8xta|qBSx*`AQby2hp;bc=`aO2nea||l43%WV z>qb-)0zf+wN+m#VcuON9=Yas2Q{O6Crw=j(kp29-ckh}S8)sKkR6MVzkXS_XGMhp# z#q?L{4vQof)_s(SOjGde!x^Miq36t1|9-ne8a0AhN0uV%%mJt&1^}XdBq_P1ZD~QT zX9Qr_rSaJ@t6J|ourk!chkZI!Icms8fq}I^FUSY=tFWTNn2dMVOI0_^NO7|;p>Ils zZbodahq5eeLzW(E#R!&$bBT%0J0mvmK1d7NQcS3u%xgfEgg=K=O$k@7jaN^NqlMDY zbNwks@*#KR-G=PsJqBIm-A5d@@ROcSdX2}0&)&8KxN>4_EaChqBT!~ffe}dFy2c}_ z%qU6W&L|Nhs;;gsYJ^6k^;3OYmT)t}bu|N3D3eucQxu;;mKx?xm&ZuG5-kV_065Q4 z;@LT!zA4iM)vb;3HZU4xm;29uyA8s6XZfS2e?7zkL2zkhE3H{Y?E!^&ajc~>vmQt< z&zB#)vwKh5_MN=gXYF~>K=5@wZ(+Xdu~9I00d+W8UYHI3pIVOEQCXfga<5aDb2#|e1Q03-3 zyXy}wUj`b1blAz<9x`)tI;+{uqJD!>IP13Pm)G6VEEw#z8tCCs#>>mw1(YnJJCIoY z@_)#xHZAt%XdeXQhn^62<93&Czl~26&<8lpEG)$NIpTTw|#B(bcZ z;5sPY_FVz}7G`FJFJ8RRBo6^S1Vfw22i@xWnWJ&iqGJic6*3IYV7cn{DGv)}FplbE zjVl_EmTi=;sG8Xcfyr_ta9W_Zzu&dL44EqH9BrsHnedZVhOD~_CQs?W+1c5imsfYA ze}26J6;S~ns<>DRTuF&OG(nY?_JT1M4dk)Y=cT&k>DBAN z>AfGrxvCvoj|1hv1vK8M!Gx9r3PUe0QR+3n{ac;%7N}s=Es#*h=@m{dIziU6wi;;%lxtC#r&vbpjzENNr2Z?D620iNcM+ZfJ zSv(R<=?$FD$d8aD=zw-dSR~BJ1+D(9!i(Jj1xk4)H-2@Pg0%o*kunHR9L~thxoF{9 zFJ)#`7I6{-qTi16A9fTBo_}2>+W;yvVYx-T`u6yfge$}M_^ESbN&#!ZTan)!3|3%t za#i>ZabHwiT)dUR6FedFdS)jT?=3)s67|)qSJi2tQB^8N=h&I#|A z{UQSK{pXSWyC!#Sf6(Uv80M$#hM7G z#GA_p5QyVr5H&jw);R%lF>EtvN1BR(Kp2NQ)>G*DUdzCo;~cvlMZz*NpmQaF=efOu z=-lz&Ux8M37$$Ou`_b%0B+u@H7HNW(dIR4)X0-&h!#dcU^mP91pi|<#kjZfW1OyRo zv=TP`iF|u@TGfGvp4|7Q4p7eHW6(Zt{uw`wK)l+c@L(I*AHO~5!7_{?V7=bN#KZ+? zGX^}6^&D&mz+MB^i}&+%4=w-+-103GvV4!pzeXH}sp->k#dMY3z!#CyjA&@9fBPsv z-q^Df_JB2yJ^Np;Qi#}oU^7$5Cwhv}!r99IxbHpmSp@8-Brkq#j|)6*3m^*j&)+@= zTECtb6tpC^r`Tk7LjX7+={pbf8~&Wbet$D$<8N#mp<(0K+yRI1Fyye~@M;kk?tuLt z`6cTA#$5pUBzpYQ#ilAhaM9%?*deDQr6C-+jVW@%>vBNc`usaf$OBIf!w-i&`viKD zCVRq>g`B+8xe*E|>`9sZ{gB(>TmP_wCLcDo;8h;NvD^Ou+By74O*jUJ;i=|N=n-se za5Ue8rzTMtJ$wFh{nJ@s%*O*ex0enB{Qq?t4lFyor{E!qEdsFp!^TvkG`z~=UvV>l zS3aT-nS26r(Jz;dL5}^OyKErC;oEk?gPII`6YOAi3`4-W0c`?4B-ta@0Wt-4vsPiY3!grOapVK z9UFt}Tdw}=Uf9z|ns{KOuz}4EKN~y1GSgiUltp81Kc8;C0fd=H=>H88c5&A~ zvHp)Ka5UIJg)5$Bq_lUGbm=gtwtt;wL-gPLXPYTn zY=pt7C&JGu3%UC^ydJ1w({LOGFv}Rv&ClU^; z1YA^)!+$%nITw4UY>dDm`ETgiTVT7vOC2hYAK;Jzg0>E1tY1;FF+To}-+w4Z4}qg~ zcDFqOTYUunKEf*!svuquc)=?FC#}+<4#j4HY~Qne^{2GfJ8(>Ct3r?H^8os(%ad>} z(Q92}Zv_KE_6*|f6#4t6FR6LLoy6%!Tm@7u@A1PyU>DP!Fj$_zKz{e1vh+h< z$N&6r8$!i5Hhs+o9n>z%ks{%`AX=s5oaKY3c++HjRvp(wW?MBLg8ZLH4>%@Q`*96M z-v00eHB+p|RhBQ+t!?XMR78wyek$;aKZ`Q|QmQhH=%&>4{DZ&$4m&Zm(SfVBP6sgq z6#yp3$5%2`!Gd3tCBg~=-g<`+!L?rmX%&-jGktZ!_Qn6M1_Q#)FMU#9A3od;m@R*& zGC9Z=ua$MWtB)=tP}(~>=5_NO&@lv-o^9hl@zQG!^I&bU_YzG-OiVjJ-TT>8TUvhn zu8f4l<(O4`wFYKH?b)}jO+V^luQgeHG}G_I49>lc`A$4-A%MP6bJ2g%#(kv95<^?< z%t<}{k@UNh4Xy5(cuqSi(3 zGp1_NK3R8wE4s?0;;Tv<)HNK61;Bv+vPCp`#&&Dc))%mA7eIM~=3h7aQq3%!^B7Zi zqqgLmJ~@8m{3d>MZ}lhp-XgP91tdy+0h)ocL;Zw8mO%|hrRg!VZU#nk8(d#l$H+hwP3w9mg&CSok4%W#q2Xl;M`MruA~xh?cA{sVXk0KC!$8Nba!OH*kkB$&eAy}52%=Dab*sZ4#9QN z8n#<=q^;t`hV@$+;7H3GX#wP!UdHB1_eirb)x84q_xE>?AVxu?4^!^Gy}u0{y^*T` z8BCzKGtV9yoBo>XqFUt1GU+I;#qY z@F$!CyhtGIDh~U08(0xTYLldF%Ycdvj{7Y;sr!zf{|aa$6&zX40Ue_koKo>6g400H z8Eti1tW#TR9-qgXmj*j?G%yJ+wIbkHly zw3<-5Lg~%drxv^`8j#xAQtFJqKjgA(aD!lLx?pR7E%v8gbX~0*Wg0>%FQixinUB3S zK`;#^wKho;XVwk+$(|%|0vd$c_ zQWk`D2N^YOQM2MwQWnW&NDNvi# zkkKpKbcUZZAG!D>icdtBN~Hz?5e{tIjk%mmN)Rcvs=gNUB~)XszZ?<_MLyq4cNqYj z5WGlX^q!Du%}6if!93n|P%u4l0mvV-Pgie*sE*KduL!HM17-s_p!Z?tGpYpHBkGkdDT7Ym8blAfMi?}O4!Jf3;6Us zfjT`g@e^nheeboowUQGJ&-GT-<|oyMk}*R#7f<< z<*55$l`as-fO=qjwcz*v!M{0*FJD^-W6D}lXXVgnL7?u;h;@g?t*Ipy8O1F;f|LrU z_UDB~Mdt)m0p%W*8;qpiO7gHCvOjaL@cMS09KP2qpgYGCw0vFH z_~fDMy1L0~qMlhLKoOXI!sqc7IwSf?vlbo6e!P!+wn)4@PFjmg z%rLT0oPTdI(00H}DzT#a&tE*bdLUKt-kk_H&s?Igr3V9#tK16yK+OM~7f&5<&MGV@ z(D8BV_*{@KeA*h#sTx=S8T(tz`Rkx|?%lV~el6aVelr`NTX}FKU_45u>F3mvLNOk1 z4vrmCFWmm4rNTN@TB}`GEW=@BYlW;`?~Raf9SCkU?I9IZr*%3F-J=U|P=XC?ot_ZC zWIAAGreil_KzDy->53tCFhZS0k*s&i2cxg+Rfv%>DFrcucSaqaz3KMesO7V(?W1i+ zuJt?W_SZB@t+~}G-4Lp7B!2Fxxy@(I^+4bi&p*A-`~BDjlcoD@8zIgIF)5&5wn{ev zmS`vYPcQWby)@}Ry;QGd`+xuYmh)y=h*O}e!aH7evu)-Po_=m0Exn}hJ7B!-Mw?%} z7a=as9@S6rb8^A-5+0<%P*B_S{MQ%*(q&#>uCcn)?nRvqELPL zc=zTc_`u?phJ$4YQDZ?bLDG^QC9O;U-BJh~D8-MKGc+6noF5ris}swQP+!^x$4##5 z@u8AyLhCmfc<=%vmbsYR?y0`qH)bGYxmYve8OXpMV_8P++4U%j)|n>RJKYE_a@WPX ze_kVLY>t!XkD>e(`PYWknVDi%+*wU^YFKkwHFw5VyiWGO4a)MT6^GVHX^yPmm5=2S zjH-b;$qa39J@UAv<_z# F{|_G1SqcCE literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_load_save_buttons.png b/doc/images/jobmanager_load_save_buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..a08924fe3e5044a84227e43b87e4115b22676c91 GIT binary patch literal 43789 zcma&NbwE^Y*FB6PsbHZrs32X^jkI)kgLHR?fFNDc-92*M2&;Jw{yedj z73PD34B>5oCy2UY!UAv)kKbucxlv#biq$t2TR1p$3Gg6!(mFSz4|XEiiAV?{&7k0; zV^ZzGnzF$zY&$_^JAO-ZbA1atIDQ*_9XtK+9~_PCj6Mj9NJuOFK*xlG`v4~*z$@=G zvzzSbBtKEz>bW5J z7enyLmhXbA*i)3P-ru$hgi-MW#8Ka6c{N%N5@{JWb}L{rrm?m|eKW3<)~`27;PXVM zg%S9twP0TakGK!c8rs<|nDiIlHJ%(cDjqco+2<(aSk7UgqxMW1W8NLT@vJD$U&h`;9)S@buUxBsTVAl) z>Aurny>D;Tn5FO3py?p)v~qGp4QVr$bpvCo;DpydoT{>R^s zZ5*`8fn)?)6fxZgl`i%Hl(EI^6v>lKQWV@YdE~d_0_)KVQ$MQ0(q9JbUvV zmOZ9y{^NQljfGEvMb#BzI$JV0HKwe$#Wt>FT9hg@re^5{af2*~?Tj5f80m9j&KMQ% zW{qcf5B<2$zrp&NO+DV^fosz^TIhl@X3B$@WO~;;G)!ghjA+`!4TE#uYTmA7KHy^F zQoB6j+go98LVVXayc0d9*tp=XPRp}#y?>_Uc>UAu&fXnnH&RLe5K+>S04-S^>Em%g z+eHtPnzmG%c1+}NGs)e})T`ncjwbYx#r^GaTQ$@Fpt`3`EoNz}p+?d#Lz0;Rsb802 zCS;a_b3a^aacC-oawP!L52mL4uvp{^9I*VZpXal`#KAD$g~e{+$vF&FyG+uOB4J*7&wawB)+4 zpieSH0a2<6x1mJwbAPIDvv zn+egotuyP+fka);>EZH~6m)s{^%Z_Go0T69Mq{H%6}!0X+QpS%>Pjj+XHB$shj0m} z3|?gC-~~PWI%kjF&SJj6h07fM)u!F5O;;OcoZvTa(Y1r?m-S?sI6bXVt?G)UNML1-cDhlV)T{E`h8W@^#>XPU0Pwlntb`?mIVO3Zdm z$!OCOdKxM7Tqnol=`{AT zkQR^083zSsvz~j^MK?PQVQ8gGRrJjHgozD@VfWvHn~pk}uoU+`S1z81)D4_^PJ8E2 zPNjoXdkvBdh@2a4U#Pu%=;;PmdRZ#RP!;p4>GX%;BipUWgCr;f9^U8w4COOkBRV`m zEO>Ek`uHIkG<^}#|1+kSnYu4tK5ZDKiuu2~5Tw<3B**n6tU+?FVx5fUGQHkB7Sp9yb*#b}VX=5pgDAZij<~5MhFN@m$H|Qe~>ujSbt~DQlVr zGhdFuo(QEc<}=UX#1k0fe?D)qN}a8-WPvMIt2ygaQc&1$JaK?DIlL$xtc?_4cL%`lBh$V+sSq zN;sH5e*6%RKenW4z9fXB(rongd~ikW?Ch+9gijXF>QWR2ZSQJCQ=10m`?-`1p{F>o z#1q>n{@0MDf5c)iV7!=TX?xisb$20(&2~%?8Tn?q*&T`JwshRxZFA(K-R{(nMNh54 z?FrNEB+oQ&+Yao)^!1)@Hd}*;@bK0%SeQOE$8M&|w13`lF`#W_W(U$RxpSkWMP2Ya zEZw`PVZYwz<{-7l8{vRnuZwEG#q-lkuG0?%1;^l$>!4hRtu2?!{)F?3?rX4W^KOc@ zU~F47DXufZ^+DIfM2q_9q$CDzsPlS->%}<*wAN`eT_hOK`Q2L*ajFWaI4UZt^ZE3K zsm8|?o7=LQHtCjM6A6$D82Z@+|34R+ZhaVB8o5cq`|AD!QEbLji4{vWk6T}kaH~JR z3a85SNb%V#4fp4idi(oVx(Q<^#KJ!CtE^`7GL6Tvva(`%DHhAJS}lFxaM)dKzPbO| zw$xay(NJv%ZhkU{qYfj^)@UXNK8J%gjOJjIP00mQuPYdFX|HCn&7_Ln^Zsd9NJE5a z34TYTvtG^LU=zU%T&<0{B2DK>@a*)?Qen_O*wbPaIwK{p&rXAQO+lH!TyoW-hD z1;huLVGFrxHINrLjB%62aw?_T1h~v*tJgc-*XI7)yF|#|oVCv%gX7@>yRQ2&Mm#0> z`1!X+(z)P7L;~PW4;Ei~H8yg#+$!1Y++Cw_KHSO^IDe-y1PcP!@-!?fuR2N>jxCJNp;E;zpg({RR=wqdyGWXN?O z?o0A>8rIZbzmVa;xpw!<<$yYbeHJjhL+sjBNwf6QHbxqeG{_^aVg z%m*LOyPZ_dyHhzTHHRm>yu9i*y;gjDd>|$sY_)8+vSaD=y39(>UMfteO>RMR142SR zljN|)$Ez?}5}Mc>2wHP zlz~}Hk$oa)ZwzjQ@j@e8TU(pOhMuIPWVUGmbP#p~QiTS0L4ga?3k3z^`FbX}oylUy zolW){v*}?xHXGlQVZvYY7KXzqO}FQ>ffOf@V)uWGpRb<~^X@C(t_;0y^nGLjEykpm ze>k>1@2=10Z2I@$g0ZZziGT} zT&@k|6+qguhXYaE(B-G_WiO29{!iSOOl;Oe&Kgaz*n9b0)Z@k+cGp=m2XPW2Fp70B z2o(jzCo-~MG1O7Ui_J|+DL3bPxgZmqZb4^ro47BRi1zC?Xl!h3oK`}d$pZiCuO#eJ z4hjELxqK@EK9RigMQmSlEeQ0x_`!N(siPAy`v9%6B!nx0tM58(^7ZqhGmWv;+o&>y zjpj;O8VtDw%v!cY-QIe;tl{HHzrV_3H6h3oCwWWT%o?4S_YDsnX|~$jaD8B!EU-OK zM(IhZ)iS0t4b4Ae|$Co z{ZD`*qoXh9=ibA!Cg+23m(6aTU}gz3EvUG-Iq+;{f(7eNmuFiv84Sb?a$U^zW(aC2 z_ML3yrmlfE(*@bqtxv7d3FRfv?JER?pHwR4S&9yM5Q~4O6xi^cSw5~{jBZ&guF)j@ z`0)o!%QLFZc5!JXY%$mU#z8#c6z<{vLhh`Od`Gny%3CQJe_O8Wh_0`+&)ZLvoJTW9*ty%OCG%_NC=C;Vwa{1M$2HBka+)T9T zbUs!3{Q2|GpU)rq1K&~BJ>2`3PMhgs{B!>wuc!sid^YDb4o)9Lqk)`^EL9hukWh+` zkMrv4YImV2cjzk2qy}+qD1FmZGT=n!)wAVYIk|65w=ktww+B2fZ!Z+?@Os3+?qPbw zUWSMdJ+(x)Dp<4nXhId~Ha={7Uct}GZ+Sx&o z=$Rt@51ir*1Ammo*@dE>)H@!m+b&6CASg+HclRMmq^KXuuNdoLCmTO+L0WT=-~L=v z4TI(0<75s|OiHax1nhUCNgY{7+07J`YlgH8Hp%VR&9@X3Lc6LY%ujf5&-04(%x|OA>4au4tIIiHx3=+Dtj^Xc@Wwg4@XFIlj3Q}c$GP9 zG1LX$OtHch){&t?!-rzt0lua~QWONBZOlaUJ^1-20&84nhwZMPJlCw#Blb2lA*l*m3R)@( z)A?n6OZkp+5*Ltut_*VXm8*d@oSTA#E;-!)e_hsg?(qaqNmr@492W!gYONd1{0eS` zCF2B^Eo5fJZ1Sw`9M73~F*d=5>Yiw3N4+3w29XRWMCb(~JfcsVyEv3_*MS4wAHM&< z(^0ZPv)+#UzoERhwAN5Gb~W1CI0x=pe(`?QL>Z(ye~+hQvbbZ*?YA-PzYpfq$g3q+ zROqIV)yQ%%XE`dMC@IMJv7<`h>272nKzy3*C~-a6xzKzJA>UrmVtaSOjNL!!Hf|^3 z68PW4zQoduXPeUBD6f7j2s=|{n=-L+QizQ$(Ko^nw6?rfzmuF-h|Q!R&1#A8y=O(F z^e7qPuBxgjY2@0IRdc>=m)QUDB!5Sgai`cl?ftxsI0F z7)oY4XgpD_GI^&~ZT95x$QM|2Uf`=wk~vB83;z7Z%v3!jDn7oqD+HI#Zu6D1v$Mx+ zmhHw69Dqqxljp$!0qNk`J|_hPL38v;d`iktI=?@w%_=g;XCA$qW7*GrkY1kmH5A-w zs#kxLk}|y5pZ9pmP++6EegZ&bU!g*Gd zXKU`XQ(U85ZH7(gcKBoX1g7DL58lw=_VUO+W>mTQxLflcodQj8IEBmk?hFP{&PzDO z!syl2@1b~X-o4+SYVXZd&Dp~=019Z&xn|9@}c2%Qr<0gL6r0By@HpMPlb)>JkwCK|q9N4m^}T4qPOH3exH zlc{13*{+g1*aX&*XET!^bJfw9=yOP5DT)lo3 z^L>T$26wfECQ7ThoS|qcE(VfVlf)MDk#X)n?dkz{rA0Y;i>;b;Ca7>>8Hi+y}7ymJ&C*HAkm?W$(`#b z0s?mlH3gOST|%_)GX$IYxWY2kVh}TL-^R8&Z)gc<>b!OhGbsPel{_#I#k%WoQ57LG zxH(shR5tjDjEZ7;-nk^|)!QGLdK`g)Vr)@LJ)mGuH!~#@Xw2wUOiL@gQ&9MV^@1Be zJZ0?)baFkEWUGCJ!kIg${!-t|oIBY=3Ale1x4&qes&%Tj+mp1D$0Dt;anc*I^HaAX zfCJmesFkG`BPb3BbG!!Yy`nJqIB^o)zi*5d)8S>7)3d4%`tIFbry89ZWMpLG1`TTN z12e)?Q-^aT5`P7Trh{p>x{g_PBaNt5on=cw3GG)**_}!lN{4sF=GqqBb!eC+c!wWO zBPuF-c@?WwyITHQK)5?RIdRx;@8;WLY3OYu!=+0xkDC?YY>nC9c3$|>**%Nd1|mXJ z)ss=!Ra)zZz`!7iY-?6L@vC8s_f*PXb#y+)s@tHHG+v{or>EOnj8AMSsjBw5zujLs z8Rj7+CieA|yv>C%(Qx@Z^?}QkLq8mwCmeXsP&4m=Yr8(6GZO@D92!hvNSw83L96H# z|N7O7<6zrtG}{)FTkDd|e71V+@@OTiN<{CVx#>@LcZDg8MkoZYGp1N=n+dDdOj=g9 z{qACMxP2J&DV@#uxBCmv2bg(K!jS8F)%T+}1kR_g&-bmjuMaz3+Cm3eCRA$*OX?Dy zBWkohm(yxBVl3BPLme<+pj3pUDII7|?KyBi+}e8F?I|&8oS0bh{@@)*;YtLV#rE$X z6n4AKR$R+wUKm8<&gAVxbj_EY>;eb%#O9T0NUHNWw!vVMAQ+EKp%C54U6l!;7G`J(86dgtEI2p_Xpjer>%l>d+=O@R%@um&}!|+*e+9L@NC_7lG(N(cxETsNNQKHNk?nr>d>z3G}fJrj6|<27iIIc~DDnvWMleaG{O z@2M3l-qbF0O{N5tiB>qJpn!~Qzx+GMH}2i&H27a4i;|vpX*k+fxqwTZAiXsod4+m% z!kQet%$*XY)Y_(p&3Uxs)UtcD*v^-s_qJBA9o{G~V*V!V)tmBAZuc7}HY6BCO-x&w z%zUQWa5jbL_5_lMjDqeUs(GmFc7X?rPM4u-LN=-SA@C0W#yw^iMoK^?L z0zyLC%<-nbb(rI2$a5{WK;JIsU zFqEKD;-~RWE=Qc)^uz3^eKLndOGmE7Pr;whkPsU1k?jMT>sLZKHs=dj!np3SbaZs! zR@c{$dp&t{?)=W8-{Th#y??mu=232TV>323b~_nlQKov|e6!DCQMdLUP`H?YZ2OBC zbb2%FdEfDvt{e3k>LIo_<~0oZeHbaO`)n;>%G!f^NAEgh=7)wWWMDut%=5sxVu7P% zIv*JoB_biAzcrSv?sn8!q*@nPrq^9=vPMB79@h$*p|7f{I3gk<+?ci+;0$=~Pl=Y7 zmj_aq5|1u|4X;Z2|DCTn9;;G|M*}N0TAq4)^;K|l&fUqJXXA35Cj$&23!1kP?%m0b zR%dyI*jz4*ffA&r3tAWA6#B6NwYb{iUt%8_QO3DM>2Q3{xeGtQc$9)6bXY|4N z;2YUCte)7^#+P1$7KK^4^E%xoRl1Bgyh!uXkf?$J3yrzZ@sPxCri<8#@cS*6oW*i- ztR;(!Mw3M<(cGoM!7p^>X2abn3M1WMX5-J1&_3jN!_zY`ylr)FEG-Q$o^>qWzlg5f z8UMMPhvV!Olc5&R zRyxf7`87&eoO@z@kkVASGZ%E*uKV8o3R|PWPWS7BN8I2#&RV62DL-fk6${@*_4@K6 ztTm91B5}z}>t~{(pyb;XrKNd+kVoy~GvaD-+?|RjX}%7utYoa=y*bz{(m7C87vl35hz%)h1#VOOOHD9eK7Aco`BRqc}9uw15uHTQv=|tDycwjJB zYYj-no+bBH^!u|l zVUM2&V5yKLEmN<<8k5VZ5u{ugE!Qr7yoP^M%#ni8Dvd>hE z$U(iUwi;hyXP-YaOKz-=(5JKAoD(j2r^h}mHJC?~9~4#o_R655Y>YhsQ9)4QoviF^ zq;pPqfa792n4ff3t#EO3qZ6qb-MGLCC#O63+ncHGV;luqlG-bf~M4?cg0AJ~*p zdP=9gi40Ea%i8h{7O3bTPpo^;c53S`wep%RI{xkq;?9-|g8DG znYysZy)okH4u6fsJRR1H-T8)CJ?z}gnM~TwY{khEtuU1dl;S*PEGoq`qGu)({ zv9Ym=zjFmGz1^5bZ73cTQ(jc0^(Gn*!&Bqq6C281?;_Y zg#jAKJGlVvV!VG}ZZXfU>3MgC800oEFp#C+AEU|KH!yH|(`cx9(DJ}7mn-?mAAP2x z3O0u3)N#m|*B$p!Iv@9vPFEVgML|I!CLwtPC>0kMcAncqcm{)kyz>1|pFYjCz{A6r z&F*>B1Z?-s#-05w#P|2}n=CkR^0=VV1DGG2`NBBn@@{{VQv8(jN=8WySMqqb%-NZZ)WI zZi3dGe;%=)Z(2`>>;SBPe0(e|@!sYniNS#1+Xn>|wcVgX!G^Qm173MRXn;HB>&YB^ zTh&oP$MRRG{Be-zRILsd?LZdwKVE=%QmG{?J3g4bYNZixTMGPlJRYHjPz~j)e%WgC zS;<6Zb7W-XwAxxMK_+Q+lg}-sSW#@@@2S<^z&In*;DUzH%;}|4mvh$+Mm~`Q4<&QB z3bGXx1m+k6?qNvSOEwW-c=~FUIr-bK0AgaY5wXw=uTh|`N|RHN>+cM~e>Y$FlP{M$ zCzg?K!ZqnuB-zO`AM|vrrujYOR_suw( z4@AY~?#b|oeKJU$QDYR@lhviql#KwH4R}v>F4uEnMylW7Ukr}>>VW0*pVo!cKp;DM zy1I>Kl@F~Rk6`V>dAQN#bhoYh;SLM%>7bjbb-ZobU8rb~ycQG^94pb{A#mT78RB_x zW7N=FYW=}^yh-%fZy)|TRGrA2-Dj%&pD89Q$8((fpZV3%#*Y*b5MUhcu`cDBCsLhb zs&2K6uupdqgs8R3eQ*tgCFKTh=}!$ z3Zd(NRGa^#zM%_Z37C};I^27YTY??M61b(PiwyY&kv4)!VaEG^k=%Ggk!M2fKiMr>VK91Qhfa zpj)-Ry|lI&PRemM!?Q-A?in8Z-aUkGw>^&1&=CsRnlf|nxH2YRbUV^&*)coKqfC~A zzLS*{-=R*N4iF=1CA4odLFVeDVvm%>^ zdIky>t?lg?HHf~DM>J}XfGvQN;PSZUN66n4qZ#?eX>+0OsMzwPk`P2c>KtS z^y3r|i=jHop9O+u?VbbHi&$9)hF0|Z^&ksmIb)e@ZfOy%+! z%Qg$wZKN2@M^L;x?yl2!*a5I1{q)IOr^9ao#GzbbUVdYU0xi=Sk>_>j#sxTLv_;Dk z)X4w5?P-MYPL`Ij2w>Q<75CCfrYE+R*;zK$*f_5@Gx6$xIy{vEtFqNac4 zRIS-5eJ1nC0c~N1v!D01qE~#jlJW1~6*y_m9E%;+6L#mn#5!f<0?a{YV6zh z&syz?G@V<~+dIT7)9+aAu!p0euHGIVC`RgDCHR%7Dh@$8`onzw6=bg#t;{Rho{BsYfIiDChb(HdlD>WC@4clL805>hXx=?RNU{) zH7C1XMZ3=8prG(HIClFzUeJF=L_}!XA4D2f&0w)w!EMc+!?8LxC}Q9_ASK9jXv68B z1#KGF7>FIb_T_m6c$)8qu$D!3JoE+E1Fi+n2lp5njqBX%=@c&4+Vup}saoqy#t;8f z`GL~o(kN__;McLd1mIz&Ye}wAar& z|FGBJWsTmy4(v5Lr3lJkO-{15ww_{gy8mf>+x*v%2K)Tw^~Fwi47C~-o!v9TV^n9G zF(;w0`p9PY8_+Y6N+z|Y$2Bo`Vc+v$LNf%P=fX?N^z`-V&W6tWc2^UBB#$R-z6tc* zlpdR@?8?D4f;K<@tcYtkl=N{*T~R2^NP@O6$@g=%VyNMIc%pSHwzOfHcA4^A;;@qi z>xvbta;f$cc)!qAUHYy=;a;6HVGgdYR?$7Xyg~pLTCI)!ZD=X}NC9M4%)2qZ8^M)o6`S(T{PVVfSUA z^?MV(Q)qj~s;sW74=qpaLm-njsVK7@_5g|4cUm`Hs^y3BI9%>Ze|AHTEql!`*rH3q zqS9^fv{?pdNKbc1edZe+ZRt-i8fq-pmVPvyZn1=q{4&4_HYh3Ite2FrCJ$P;3a909 zCiGh1avjOBH}&@Rf$L$9?l2^zIUE~S$dOG<2Hqpv%U14B>T(0o$5JP8>jDHkL(4v{ zQ{~3^9M$GIdHVDs0VqZ$a1G}K+Oz8+3NfRYq>?GigD?Yz)%GX*7OmT= z{R}(u=(Eh0R5gO%84-P^`_bzVvTq%i-I}#d*$gTIPOi^BlaO>_%j9z;cS0nL3zAgh z>?!&;j&c$Lm7{NSCRfxax(V-wCX6$grjNs<{rsp*HTtGrIrR1nTtcU&F&`BV%f;s3 zF~5&_9!_|~J)FwLv)}*2JLDm~%a!9fOC@D39c~FR($mx39H~Zgzd8NH&W_VCKNO#Y z2mBl3$wD$1j>IX30x4qE8DzJWt7?;wt9f^I1$l?Psjin|F|}dtchmj~+pn>)dHo&C z0Wp(q7)Ai%t_(EC3m)bq*rdscBWB7K=YexC2mM8-_|jgQM;)CXHOb0$ZT zhDPrwy`T8?^yXssF9>#O+7eYwNhOu2$VgVJ!&j8C9QZ|Sxl*qQaV0!-Q2JwOFA9Sd zWUQ~9I$i9SRs6Qimi7Ia&A)vUw_*=`f+78muArdElmyw6k-maHd-1w$&v9-DJT#5J zzWe9;Uu}o(G!=jr8SZp%w6|mjWcYyKKw|b8HhyW|kK8l~qnVIrNw^5zU0u3#SaZ0U zd4bz&bYkM70!(>XBpfVBk0uftZuG=KA^E9jkFD45354wI7=a@23;|(z1P`<{-p`S) zEq%Pa;4(5YzKM(5ZKM}a0JoYtU0MkTNa{(mb#cGreCG{FD~lQdUj?wAf(>_9XZL8G zoN#*w-~1J5#Moie!N!UkE@Gmh$2RNrW~$Z)K7g#eOwOG)1MTtesVQYXKK@6tU1lC# zN$`pOEam2?lHs@E*Z*E9*eK|%TFBff0lrIviaH*^u{6x@-)|=DSKUUNzQvAxJ5cp8 zn1j7^H;I=i4W}`z;S-_8B0jqR&5G%X^zeMLf*|#xTh4B+VZ6E|D-1G>KDf-i?vS;- zS8FTvoObr}OqEJd2AM@}ek_gtT7IpNUgsG#7mJ;>Ir_>>Pj@<-xn<4lC|-iAOT~u$ zJ98sOoG;iCSiy+mBvCgjfJ;~4j^$LES1DEmG+K6c_WrefubrUtQwv<&7l^?^nH*Xb z)8e`CTzx=P{Eo)>Pjz^_zH}E(e0xZkA!BlX*@n%xt-$>`kvghmQ<$;g-(%xR8vmqO z>s$)Zu+whn3374b2hc1kb{a2R_!CHSF-q8S%y1^Vzk>qqW*k)xo}S84j+=hr4hAqhRRlg5^ZuP+<07OaySfwn1(=5K77opKt`VbSFwURZ0n)ZztL zV6*R|nR43ONzK#r=Vb6#WbhBI$rmb1()Kwtoi{>s>)hD%H6*(NH`EEGgfk#Jd4YjB zF~U5clsY=ky^cun;F?$CiN)v2{6@*HO!>EeYqLDSU_=_fKrSaV7Jm9fj}fasDO#J6 zY|Q$Vc7T3&gpYT~{+}b+>6IVR9JG(=JM)2~! z$o*L&p#DV7K08@ot;GhtewH2qL?%N)2qz`V|DgA$d8mL6*wnwVqO89-mGLn-yh?S& zcTT%6Br;FK^SnX(3MjRCwMnJ3*F#)D8*SH*)tF3k*0gFvP@av#Ca0OVwrLi*ZsEYP)T^^Yc}Qp&JCK^)4**zdeEk4 zk2PTCc{0O5QQ&OPkLB#HS^T+e}}cT zZaouLxkJC;abpf=(R^ia@ddc12MuhwrBZ$50vw7jy~gG`p7{xQ<@jWzks;b?kaBQD zW$kDFlKj?b#?0bmH@(4Qp+DOOjgv=4q1R)^&KnX4%+Rjj0Mc7$`i_7<4)#gdkguO_ zZL*U6a=c;6M}P%i6A6vvN)b}Me-2WEOa^y>Dg1v_SBKq0XBrBMN4jnd(CZ|YM2_?J zu{Sq!b+)*i4++<3toUI-FD;-*fRrw$MV}$1E9he2t0BF``Ti%pBcCDLj4iIepb6o{ z4gp{8`yce$$@(~Ycg*oIhW) z?H_WX6j)?d?Jt}Xwv_08?@kVspuq2H*OHUDmbr$obNhvOh8sKP!uPbx*Kx#}Se}GF zmi0ftz`X)2nX@eaTl7x1HERckB7@Lly^mKNxEVC0)|YPFGid!KTT*>TX3CKCBO>Q&8*G8G@A zsVR_CS4Ga`5COZVh3=jmMkhKe9NN65mp9rAk`c4CXK9qnUPnp4H4<;Gdl?)i@k_09 zro13nys$5M4!Zny*HvHM;-yXU*={ZVPb_-Fy>o1!Ie`ypFvfdd0Ua&VZhLz1MRmYgivEQz@_;|O6 zf8;lcn)CyGZA}Pph4c$E7`!#5`@%pUY|LQz3X@P+R#uj}Ps1K}#13t+yWdtu<~7KA zFL0TIfiL2Xf`W*cn5i_AOOEKZi@xe0;(SPFLIjL1D2?BWx(Ct@$X`2JBQ{XGT(s@Sfw zISz24yusvCmS$B8WjDe${WRVkWT~tB2@wA$Y8pY=+vo9daXppB(AxX!ou<%-Q>fG& z@KRPqo)~84^mIEey2k$fs~Z>?cnSOCdG(I`N;n|6e0J}OtQ0=G~SA4udE#44|_d4{44w`Q33$YiVpaL8$S=qH=(i{f!ygH^EJfB|8U4jSnm|_E7w;V4jP}g zPFd^qYi$p_7Znv#M=A6aso}`1DR9{z;+7NObE695JSPt0I(|ix82|+P7EM~&`kYLx zr)^p3c_h+kLoI=?{fm7!4VM4>`Qxo?mBN4}BmXwgL;xjVJ$6{r;9)@{t7_*P$Oy%^ zlJyWhMlxk_M0r7-{kVkOo_!wKU(B{9tw%BsLl8UjYF}*QCN+w-UjGJPRB7kJpKT0W8OQrQ%nK!;B4% zdn9CJd5RC>>BLD;*RBftZk@4fw&XBi!7@{+3ivx5HbzAIV{>k3_x=i*=WIse_Hfc} zYciX6uV{-sKAx>;p~YvaR{2vq5g7$;H{48>IZ|K*!Td~x;RCRdaS9YF7H=Dx%y%_6 zZDG8R286-4{@>?u;=Iw60<^re3qd9?zS^&5yjzp8F(G_HJ(Gbbpi9dYY_cWLaWjJ> zApDVqReo<}|jnNqm|5hXzJ*#v)w19$)-4`+5I1$5dG_Bmu9dS0y;AE<2J+F_j z#q)ppYCbt_JGNoC->9Y}2+B{fI2@?J*l4~SW4dF}0$x8H`LliZPn2PYhp%R`s#YSp z?*|#AxI};hxykhcauZbeG_dVOeMkRQ9+{9d+SDF1hCgE9Yag~(3QRgRF#t>qn zxtxQo(;sQQr3CK5?)%dysUP)H-9sQ_a#AHdCP~LBl`5Ne3tG!WXv(+JhqpH8y z90DTWoJ{EJ*RLN1!9U#`nUYKzCxs!dEL;x&k|c*IN~{@GLv`@q8IZK5RvS-_xigxAsI3#WS0$ z*3q<@mNa)IvDuQ5k!i2?M1YkI9h5l7w;0S;V!lcb{zc~j&Z#(q{@OO!) zaK^9o$LiJ0vOV0MJlgOc7YV=tg9Lc7Ppqa(KoqIeSUNwFru&&fy~Ex%>k>I%K9^2l|=l7Cu2%HKs3W{~V=l#`&GXTF}{S9kf zUELW0)n4c}OOiDkfkx;-!Wb+kx#?oT^#wlrV{@45t_K`Cl|VR_v3S!RMwpwI_Y3g* zQPI(l_G@5c9~+akv9$%@L?77o@(M(O=g770NB!|mNsGy)y%&6NEl>#OH{MgL z3dqZ2KyxH)V_g>-oukJd^@>3z*m#BwJUMkOT(UmU2!Kx1*Q`$}LTN0xlrCS*%7_|< z@yd~xeiWO%C2VmhSEG4t+m*(+lzgNf^7hReA=o~O+ihEe@9wNviMiU7sWb=<-Vs|LP@o~BFY&An*Mn)dRj~|0c z@NpTLSp3p>%;Qhd%m+V;`-jQSoiRRXx({uedy20|Byi0Xyt~buWNmb~*&VNq`hkr( zPB&2~Kq50uAaiOPZhi}^dWLa;1b#2FW2%zH{{cd?=6B+all4y+wx{AC1Q!%2sh&J8 zHY27R!EUY734Meo;5d%H5Tno<2 zep*1m99^{!mqF(L;3vCE8`aq4)c)@Dzj*teQ25(7h;CL&$i87HMhnA3sufiCzD(X3YJ)!lsCxTppVV z`7W@h)pnR`gWL0<>B0uATC!dVVaXsv1(LS@{p}TSLJm_Ko^Fl~B(X&SPX}`0M4y}# zSLaF?&wh#pda2EtD6pAHIytcdv&DCyU_3@{$xbSWIG_+rRT#d61M8V`mDo~&1qt{+ zf#8G&f_KjI;Z8iB{^xXsVZ)l`ROye2LZt@$gtJZ^$MH=!DjJ%c+PtZf)BDPbjEqm3 zo)@N(*CBfQ8QB8HJalGOJhH0UOMsKD@F3zTnfK3E;W%z~3UalmjRRjU9B^E{eSM!8 z7^3vL!+z|m(@wt8{#YkS|2pC|a1TW$CrgMJqa;8kT$3AkH(nlJ-*sZHi8L6n-T%_}`!0G& zgM9nSRK4;~>~INJqHaf3H?(3w8DUTB{kb)5df6P!}}#|scZ%1-xd zN3Ck5N=Z}4$m~;%<5q8cq;BZy+VRd&$8K3%t?r>VD4)NALJE_2amIih3^XB)p@XR` zgc8uXz5Y({6d4uu6AgDLFae$Hu`B{-7l4lWFqiPV;ho`bLeJg%c_8>xB&R;YIDC$n zx{|@OLbqm3y1PA=KvdozB#ceJLvBvUN_|GPKM?nLjpmJUF(r+_{rp+TP!{)Mbt6`n zG0ztfN&8FUmm4eY`s)GGRJV3uxf2Ji1steO^uTMro*k=clbg)tT77d16jN;AXac3g zG1YRmni??U>xq`lZD!1G@$n^MX*3#F%@+6Z=Q#j?1szl4^*$gD0s;e{Y9Fuma$d~Y zdT2cWS9H1Cl}$|wh{jd0M9V%^3kVmWs5(e-Br}`ifa!TM)9JQ85Kl}@%sAzwB1fFr zf3#U(>G_G!)WlHCLs{rY9Rh+gTjhcC>%fBJ=|HV-m+sWv$05F-FVgp}?#O8dNa>2O zO9tE%IV_tZE-x=lVCScp5>Vvl&xt50gWA3Mz$yvm#1LdAZ=h*cTg;1s#hcKhY?$W@ zTbbk4gXmBM&WW(S*}mDq?JUXYvD>{(W&jE|%vh>MI&}Psi!(W zmSLsStI>ZwLYb2B%V}u!opvQhtmD*M?BTG66XlCZ-XY7DpdDJXoqbAso2Mr1iVdL| zIM{S9c->+6I)epkj9~$KD}MGx_GX~6)Zy`e8*xtS7$p)82n%x*zMEVYfh&y|&%lmp z)gD?k(4osC3;fwQ#|fBgx&m}NSLOopq&Z#O^%V1w8Kk#Z?~uCa>?8!41k#ymOC)$5 z$F&?3BErzoxK-lCw7pOg5vLIxM9s9Bv44fU&~`ddt|lbczFT0xh-GK}t>!(QrcIxR z$Enhj+k)$4CLo`D^N;Fz%QTWa%dg191aQ$WfD%%cmb44RHf{v*Ma|QmP^@`AY40G~ zT&&>`?EL%;K^Ym{+CtUpcvS?D;K1}{?;;`-Vi3BgDy5@C1LAWN6_8P=fd$$%)4!0> zKKA|gFV6aN^*0+%6~%xH3(dAESCrc2+S5e5;$hPmF9Fd3sXizAfLK#%+A)l9xWaLP zKiA+3FlStMb-p#D8!J;`R1y4{WvCyXVjoHL!+@sY^bII$K$QS3Kz3V>Mnls3W(Q6f zW5^f1E+>2r>%Y$u*5|Uis-9m1+xWL{-|`%vDLtI@v4r*X4`ya%`ATtL{hww!h$$L&D@fdtv}T3B!EBvr`f0|KB+RFdwX9>1(Ln{+$6QpV(3G;w^b8z~ zT?ZtQvh+$*pcN`NF)#zh?NRqQ0KWhxZX9!hyoD7gP)eq7s*tCmyd^mt;eVM<7N{hj z6$F+n(>ou3e_R8gqmy3YuV97IfEPxS=(PV{1A0a(mGWrq+Ft~wMoniz4u@c1T&&wG zG*?!A@nF!)!vxIxoqkcwNc-0Le&Zh)*aGBe{jo#{O}>IV%I zfPV1`A77*JsEGKRVYhTCuKiQL^G^jzo*r5?Kc@IO$dN^fHy)<{Kc>DiAj-At8c;z6 zLFqF#bAkQlnVyF0&YJm9IUfKjOmj9eMH6ob9-0AAz;;3?J?K4p4l{6dellTK60C5K)aWO}DVmcjxVLtxC{<#X0*UJ4T{CuV`F0`{#uVhgh{{h1J?}P zy7OC4?Sx*doV6ADP8peHa?asUwp4iytQI2g^5*TaLSbS%?k;4)x*qSBh5`%~Jx zQ`Ow1ZndJBvOGMZB&QYwY9>Qgt{gM(<3QU6UV7b%h9~}d9~MuLDEpyV#$g7*&R<=5 ze{i5|-ivdOVYQN*j0QX9t{h!WY0LD-jx#F{e(%8$`pRTw;aV24@!J9r0kZyR2DJo(C=EmvnR3wN>si>&~0zynr zgtX-31OO>w4Qs70o+aob#fxP&3{MPktuZOj^Q{qop!WW1Ia3{;I9wK|p5V3+`-1Zh zgXSHChCFK!7 zW`hG5t{7N5$|d*C0G{=Rf#E1;CDCqx!Q7Y?Y4<<{$e|>~hw%ID=pvFBe z!D%-ngyZW81!MsbET1{HTkY~v(Y;?UuiV+>Xc1DCr8A0*%REJqYTm3{ymJ_Gh{9Pr zzKdr&a`sSAR0@xA^A0aD~1&8cz< zpeG3G6c93e5}5u)=KKv`Jsp-473u8p**)c}wUjN2a= z6r@_l%pTk_km3Y({%^f|dF3I!dwRRM`Uzgiy7(Hq{qbcK4#5Awy?Wak%%<=8hNHf_lq+GOLnTMf@vLk&1nM`PL0I@;8m1 zL|(5a8SC?=eHV(;b3JnM4iPabswlae5dQq>J-qTTsq_2DQ1PJ&n>>Xp9I`?8`p*VM zl^5ghaMMiXjia$0>u|tZ*57>j$MK*mi(gfMa6{O-J$AEYa^`Dcdi<>lJt^cKQBv7N zQoea&zd7ZxV(03Ge8EoUm3tH(N~{O(?A^88=}xgFU47cGFtNTtA!kheV+OtwqYZk|HcxgCh$u|tcf7a*LHUkADe4=Lsa60KQa$mUyX;b*VgiX** zr5=&*2-~j~2Aa#3vEYiX?-bJvbq79BN$@ZYP&mi5^?VFyr&uP%BF9G6blnhg=D|27+u{`nWw}Jt)ADP z<6u0^F$oNmo%kNQbtihvOPP`fQY-r$pwiao6K&>W#bhQ zmSl6&9iaET4iF0fWc_pVs~jYCcJQ!cL?G%THK)U$cW6$o+)wxC2vVT_oqEsuGu5?Z zrR*i_6SnoC`#d#sRzSG+$yS^Zv9qOUR}(ljj3l~l=i;LHxkjd_Y8zLwWA`^&V?J^1 zY|Et(IvzV;v}e)M_TEK66E1(H=^ynJgC`?VLD^L_q?}1t1>yaWWcAY~z!QsQF~^4T zToA$m^8Sr1t>i(?O6Xv$OSv(0{i3<}A;_1sUU*{NvA%T50^o>%v)B*(Rp!#`%*-CB ziyI<1?A8x~1cm7|*1R4N_G>{-uL=|+faGcbzz`bXijdRc=*C$_a5kP&#b|K&5`?1i z6h|sI7X<}0RreK@t#p$in)>lsvhmF+KQ^8HLX$eYWsUVpr)3^_y7Qu82Ss;J8jx$T ze%~!zIPAQ65E1)`8aM|9!gU}31s+Hhxn~*q(@!{odJQafleKmfM&)?0>yM}}_k;UytEBQhwguBW`u!jymK{qY^D@y&_V>4ik3 z3u0=DaE-n#W+^5K)N3&bO!pt^(5Vl&jG*!yyTGW@MM9#YW``bZKvJ9{R?pB4Ka@aI zL@M~aS$IMvQ}*99mP9==CTDP$D5QA64m`QRLty77W{rulD{JM?n(1c=Y}=T*d*{Oa z&-Bvj_ntCHRZjo@8IpZCaB;O7b@^qwj}p;0!Yn%2fEoi4BDZvW(mx>AMr4FeO1nF$ z`K>2saR>!B*tPfn=9g3tq-(z1-`^KzcS4kWSNr53jMB$qG8r3_{td|Arq=q)(5=IlF0oXvp+#v2Slk~mP1)bMZjhT zB)v8(5Lp$OZonfK6_a{HPVP6~=!yYI&K&_5JCdGN$9DGR2LwUs!!t|inZ}RF6yXu- zzReVeFIMOCZOVWI>O#;$`RnR#*JxYZ54M$J!9s|`3k zwQp;02Tl(&SBLHG`nfP^3{0(+=y5&;Kn+Hn7C2z?k&Nn5R#3dQyxyMxL!G>CS4egw zxvl0KYL5bp@oT%rix>DMy5JfdA8~oz{|XMrIJ{}7$*0OKqUn5v{gsCXy}UDU>{Y1r z#nSoeO0ZOBW{uBwo*A>Exqa4xa7z1~=dCB7RW(8VoD`7lP{x^-s&x1ElD>HZ50gJnAJ0q4h}4U3VL=?Jb&mM3WNxtu=8_>kF>(l!eUo;ChK=r`4>h_xSt@BqE#QWL+(;EAnk z<#ofOywL5D+`NL-NQ!;ZyNyMQ2{%GisoEQ{#7<-zMP>NG@?u{Pu8GmcUuv>NV|rvX zFLn5Zo?I8niF@#(yYosh;M?TjcWTiyuoA?lr`CqlWvMSeRKeJ16~Hjw5A#T90#jTY(Qp-!Ao+lWwl5oIv>ePQlpr z;B-orK19S!Uj|bXOlhygPqA|n(fbs|qn}=UV{Og(B3ode-UB5sgd7L2*n-k%d_i z`M%hkvMw;4l6_C9!ILjXEn$F2XQeBoukMK4YI`c>UUsPF4&FU45Y;44IB=xrwejPr zsi{QI>#fYp%$GPg6U*3Pl{@vht1H)MJ3E@5txs@9w?aKuuj7xJ)n=Y!e_P@D6&?Kw z3#&6vG5<&K)2f!~CJ(OcBu9J(1_ofcp3{JrS1aZB5J)VWJLf@9EHprYbt(cWZ1uRvX!Ju|FiJP<909qR! zGuB1YmGce0huTh?!bU5g4FrJV?}2Mz$5T19Qeoib-`)yi$%8*nAJ=m{>}WsaMM~5F z$}#MZnuAA`@TWo?ugSwl86qLPdHH8(1fC|g!*N~28^u#o9cYAsq~xe%+!4@+8*Y86 z=HTIU?mvOH0l@*JoOHg&!|vlnUO3ts%&$D8(;L{U`(af>kg-L@#K;59n2HLnRxwTr zROIzbepyUrNm4d89L)(3(E&F$AUVRq!s_VkOrsRfUm2Wq4h0N0;BG|%<`n?s8!^&2 z2t%=>EeAaWOZ`7U_^l)xB9-T_D3&<*7~OAqBZ!bTnM!`}{ZuL5Mw*RqVZ5-55Y~~Hzq+C@d+_T1 zb^3t0$d1|`HEv%1l%k4gE#y;fEC27TqsWn-FDYo$ixlRM`h&y6p%IqJ>=rEUwj9hYZClXt+VVBox{;{HjU*MYO7xei)tH;I=FQ5^O zkw4}$qT6N0s>g_*bG%(JrS-A&bGrd!IxfOyUSJO#UgNST3Y(6F4mXPF73Duu;{zK` z;+J)hS!uhmOd@OrQWrm^4f^pTwIRL1g@k(Xw7bH`Y|9nmYi>nKUYx-6#S@qB zb9oMfELe(XX}O;En#fg*+^5Z1PrxfgL>aAuTDkC_&BXKnC}a9=Z=2bot)g2_i2kV5 z|9~g^2+&C`WEkZ#8vcmnPJA0ONS|Hk*NS(rsbf%!v6;T_Tl7ZrXCR3vw% zQ@Iu?=h&^b0tz?l$+vO7*^jZ{0Rd)4Hg2;y@%R#cReBON>%mv-fJ`IvO?IS0rWXPX zrc#IWrNJ=m*Vo}pLQyg?>y&^nAoJ7Ihg76 zB#+B;?Fytn?-P{w@T=)P)@l|AphhcK?_5#(5%8R1*etb7p>vH2l3KGlLFyOPAu5qo zN0Lg5jSSXb;FESjv3fEB;Ki$%g?qn=9Yav}5+S4JQr~-K9C|u;vB0n%#Sl!u779YJ zrkneE;cDvv4}&VTA6sK+A{uY2a!j6AS?C1_Ki5;=f1@a$o0q4z(B!c@Rqvm?#dGA^sGzJ2>UZzy>9f<*5dgW<-JKi6 zf*Az`z^7w#E}N|takr5Arko`uJTmf=k`lHw&lM)9>UFI-E|riFLm3K1@P`z+fx(U4_~$C7Su&pH}7WE=b( zoJdD)B{Zg!m)?*L=Ql42nG$v2#Agyk!^l?th~Ca(RsuX?v|3aoaYd}P_%7o75ZQRY zAsv&ENk5Tag>KxLH|`cDkTQa8$2odbIXS(_q$KH<;-!oH*kHuvw*@Gloyv+kphbFo zU)|9hgI<0A_-0XlNFjtcKvx16KWGj;SWLb6BMe@6`bNrtJj$;*DJ=Mh!8F#$k3bYD z{J~x8qca_Wp%p&YM96iW?v0{=W|!KGYx{xSO7BeQC)pzxZa|lAhWcV3rkPUJ6%kRb z9zK#YGpa*W$oLkB=Z37__gI>3@_9~01$tP1JT>$Hc^{!^;2J-&r-LIqwAHG5>BMz1 zMR@?njWD)-WeOA?g(F{;%OZ!!jt`ds)@&@>g_PA6Uo5Zekiw1oZa(Ek`Ca{0UIT7@ zYxiWHc)BI)vW4UIdvZ^(w)VX5@$vVKOpFK~GwU>9tfYK4mB>H>%-d{7sU$~Y*=_VP zAmhx1180MI$TJ3d9o?^DC0fIu6tGg8@(g#+M-y4>Vwd_9sC=jLl7q z)_k{Ttv<%nz{8@rpt@kdus>>J;1M~tJIU-AlH@cnRp4^=C_*H-bs4378D%3oMyqv0 z@%_MEbYP|e)n{ae3+Xpi#w5GpL%3MJElw#*7dNtsETe%nodF*-MHnbm3Y8QTJJ%d# zWmUfdZ7MxIS~aBq>m3ph!~#PcIT;y#kb-RSi~v*vD2a3|4TEaRDUvle4nS3n^7KZG zBFQII%E7^*zKSYnT$g;2d@|%_)(&bonELUy=1PRsVzTA>jPI3J-S_eegtiNIn;7RS zJwq0^{Ir)`e2?Ycvt;U2PKim0Tg~Z@d{lJc=6#{a^olqskm+r%5<>qE2*ItMplpkg ztiVlW<=U;cYPo8?qve;U{(-jhm-__E%jmeQ?vHP%sKunDj6Q$leRlM0H3m~&LG4ei zJ_L65w$M}7&gJehWk>$07nSbJ_=^z?4BYB+Pt4$0QkPEx?75Iz%ik(1T&kdo z9SSJH3lO)7h<(|4>8TWqSo!~#ZPz;jFflO?*P8A$X7fqlC0E#<<#InLVt<#y z7c>xj2Shh2eZLkbztG0TrUyW_zOb_ci-R4SeABB-5Sp;m9SGrQj_%sx%SSpF=$22j z?-Z0@f?5s$>x1!_{FtDeCpmW&)B0an^QizGf$*$#!sIpUw77fXvy7qODYH(q%2ZsG z)Ts}Yt)+q?!k?<$J?lW|4-5b6`&OPkMv$~B-|uzkpDyBY2RCXQjd}!i=Xd1!A#ME&`fPX%_#wD2x|G7w2o8}Z58Dw@ ziMd5xTsRDW8?LUc$!cf>LsoQwZ}REZ90jv`8(^jZ;VJ-PBO)V!qbO1-Lup}?7cxCB z=Mdq;{=()$GoNX$Df@1yBat-JZ=lqSUWUJD`HwKw*wk+@y`_6X-B!o-iuxtZ)VyPZY7Lqe- zQp~1*8CW!N6~uQrsOL^6ZNr^s`_@#7FRsrN{CQvYFXa29y$2G%D%M|pYF*&|$U8Si z`h_I{fOEu5#Y`YsleCNHEC)%|cQVMKRrW+D^}SD>^KF#ZANhU4=wYrVW(J`*R@YN> z!gK8CVkG~cD4}A%zh`~z-D_Pr@gG-KR+QJ06;l-A_-&~87-2{SUQ+((2EoKgKW9w$ zGt}c?zVS5Vhn~4EygAygq5jgx(;Afl-ZeI`!j5E!pv~W}IgmT^#G)WZ?4n-l7>uk- z!tmR?ZK^iXHip5nBD)X(&RT0HJKsLzCYDaZ)&X&-Nqm=Sc9K#y*Lk>^lbcnKeqK?L zm2GfiIeBs?V2A|)xK~VB?oIzzgdUY0u;Oe-sWE^xuX?E1i_bOl zLg%z6W2(l66qrA)wtRi0psc9R3e0!PDM*Dwbw+b!0l!1HdPd!2evBBa8o#so!G?sF zCsBIA<(JBI*qIuV2bc zl`Q}mSp0yP!ABKKuK{VO0+Yr_KY!o)pE#iI#a%ZD)|^uaF^JknbL9cRom<|-VV!eF zm7{h-?61v}*kNipQ5rF;EkkWPh(PsRE$CcvaH#*KOo5<}NJaWg<+I3Aa*kKK=qBZ= zKxgxYdp2NVC#@ngYWvUgKfU>~4p^8^6cvxIZcR{`Je#>j&+5pAhlib4AGF@h>ZNt8 zfW42CB8)hsed{$RXZ*Z}E7N`flgh~$o5o-U8l9K7JVu0z{tXl}ggza(n@mnlVoP(6 zOjcz`6HCh3qCdHMa(U}-Of(JF8(@o(U)*GNI=PYLq?NRjR*SmJ#}7DAo?ds~L)MA< z0Nau7ey#q?ht{2&M z7&q-SfN!NI_ZC=7yasyKvNA?TXz9owp&8nI*T$#7MUB_T-@n>*80ULyOKR)) z!|R6Kg=Uh-A)mY_6yAZM&qFH#i$oL%kFY;~z{{k3{ue(CoU*VwzQqSnQp(TB$ab~` z_fNn@41giky&-eDXrWh|w&5V^Z>howYi(r{_ln4AZUO=TKoukhF5N&%TWUH&4k}%r zfRPTVNXR={+86%qLs?>ugRLuLl({HBXU&AAMCXVv%N_3cZTXAg7UNzej3`o+bVGYwCE0Zd7xMFRgquMV~d+%s!NsRoz z2MZ$Wq9WHSw)&Jz9b|K->N)zoQd0EJ{eZ;6f}l9Ypz@-yuK8b-TxxsI(PL_~_nYRr zH`}~3X+?owI@^5S7eGqu5N;FOInzt;HEO@9DbR#Vj~WVi6}E`AO?oPT2I;Z ztEPvrn3VDZOtRs}Hmt^Kr4v{~&>n8IZOh8>m@Oy)6$40om-SY!y8NTk1%6?M~{!I zGUSN#t7eN278DX$La`fv*47e~Lfr7`z!3W{>uph~Lu&9xD_3tt0!tXW`4IJaCF#949m5wa$^jmu&s)swj@e}GY?rq|{TKB7w;!X^wTJ(UPeH8#V<4$76hsQz0&8P z$T#wLU?)s;S&xHdPpYZ`S!TeLEm4XBOzxmg;J&%Myr31#)YlXAaPhX?-|)+@7zM1X zCLw_W;O8~X{seZu@+rb?SJjnKdFkIGVZ@l&nB!Zanj}F}-&##fCalcwn66LSkm;Gt zXM%%+jbi3zZ;aaTFk-)SJqFKL%0X~9-Yq0fA}fPjX4rv9NLJv&rGFtUQ-|OnDgLIW zFszY9Pfrh*$q~h>`X!y_xj3SNJ>m&VeIKB#70w9r%*Y;rR3>+NGMUEZN)1| zl0u0mO2BJN!cKH#Li|2#_1{CG;OuP1Z?sovm9>t-SjK>JUXL?|i?!{E;v^9lx~Q=4 zkppI9?`f!_{^V>t%9>>pcsk?&i^&@r8nAg%c3caEZvwyBZqk23PHx|GtZ$Hd{x{Ts z@35BQ*6V|O5{q)0_eAnuki60~S@F4i3}~z04?4r&iC0s+;M{gsiM|nj`lc?ct4_0b zC-a|iLPXC#!*T|7Op5*4ec*XfKX~bu){p5TGB?+wqV&S6CF<{6Lc7Ql!zaZ432ZoH z5dyEDxh@Ur#AHs-iA17D!gcrZ)zwGXlVGKfBT3X+`@Bs5{AV-eBPcm!$C!h-zHt8E zeQN-{nw-S!N(Jh}gmi)`{^HpXitPe`)h8SZz)ATq{av~Q9>--qhhZr;Z?9c8pl4Nr zIRCtEkG>{zT>5)qptt%;pdt}=gZ?=spG_+XxJO7RQStv=)jzLSBpg?_`lNqpf59ed z`QMQyk$rsix^Ms7)i*vS3Gp2(;k?>6 zwF;qtIHK=Bo*2jE6gv9j-!J*$2+UM6(ZSV5hLEr|N#1xRojD|g%4%s1v^IQ)i^UWI zCe|j*deu{8;^2(xn2Vu73kNZQu(#K-mrv0|zxH_v@rJCJj(LLU(EWIe!jiWuG{uQ9 zd9RKYa4P$a+ILRGqrk1O2Mi;IA%>`^U!n+durm3wT7o+vhu%8^Hp{5zm;yhPobIC0zh@yN34lQ%%)&2mlD))`=^)pd$ztZ#blH3Uyou8_EO;6`} zB*03#*t6B%pvE??+5~K~vKF`-h1Q|Laemq8kh-JqsVJX-R-s6`QMf`(y$6GT_MWl21(}*aGY{svu+3Dk9_OI5Kep>Ed zFVj8tX0OT>+8AWCmk$AbyufM3IN2p@;CwH^9kz9a%3FmI2t9LbrK5W$nxa-T>f?U|D!=d1qu6|ZD`^N0fpUsEgL z9ZBc2rKD=7qv~c4N!_%B+3##sSI+NypcTC~J}-%&YmRBS-)LV0bnG2Gthz%;9pQ{A zz?`mJJij^`8H-Ltv4}Q$qTq3AS6Q?pVo8F3ax_>5s^Y*7zj&~U1(JJr0Sr4r>Ey$$ zCeo2b#XJ$=B768P5<^P$BWlm8UZD^Z&g|-gav>Y{&8~qIFInj)V(rfu;Vc`E?M=|j zsmaB-c4mEZ3hV0Xq>x1=M>6GLV;(#(JvsRicIOYuROykU6>7T+#a=;GFic8>_GWED z8>m7xCq9XZJS8Xgx;l$Nge=GW3QPao&ErfOpCzxdxPEux#B^5XO<$iE5r6`B7DuhQpK^W7TG2%4qo_uDG%*wtYNQOPS~%B4yt>n9T$CvWa^XQau3xz5Ho#V|D|@SL{uEf$pIHW*lxL{=cpz~_DqZgs6zRMN%omKz7I z`ChH-@~D{AB{<#{tfRES#Al4T?;|uYHKhSr$Fn&lb~Dzs9s@Qi(@o#^ym#=7SEB>J zn?JvNlx8(3&39+t$oHiN*fVe0qZb4Er(j~3wl)u-2p8yHS+Sd@#`{RsTZ40lK_ZF)&IXXqoI zTo_ee+Kf8wE)oGHakJWNfG-famghM`z@G zEdK(8k5`wGjd1Q~igd;)N%N}=W)_n_q2P;!rHbrxu{GsgU><1bL|C-{%w;TFG>3qK zEhXhhi-Ng+I^{aa=WhgKHqb5!cAsm`fcn^?{|mm+dXIiauNG*DZu@qHa{kR0xqQe)eEpcqhbP~#4L65jD~G^Lu6Pu zZa;!6eC`K&?QGWZib-5g9>r&|amLMGADp->ezl&et9%+m{bdu;6w0Q*H?v(_DyBwP zU%>Yn+e=z307=sy%E#Bz9)}UiDGV;f)1C36?7{oIKRgPmI+!rLFlR|60x1Oy_m>V$<(>=X)Xf6Z3PluVW&F&9m>@lNFAW z0)@7AS_Q=`yq`w`CXGD?Eqkas)kqr}RJ3QrD{PK0D40m!(j7w6)b*O@0Qh8^(xG=&SoPIQPBT{_x-B;6wIiKG$5WOXG9@f@J7b;+IZI?9M3n zBsqD?8sDXUWVk(euao!K6xqB`5x^vxCDvFHyL z^Qe)=>m}u3V+@Vh%bnCXF%Gc>&p7kwa)ls{ouP5;j7Cs7dxw+kHyMcKfqXGj09?rr zqr4<%Zd(odI1AyYL)apYN6{&vSEipeCw6DX^+!MS7}D2uB_tSsz{gr%-VG*7=p(S! z&@dK=R<|N*jg+=9nqE5yPdP}pUZ6DU#~)if0tV73*fibC*E`f=;;AAQNskZH|xxd{2`Q3TtOtPr^&fkb}cVBD!)%il8&8*#2v zqe=(r7}-^Xq?gO^f%m`Dp_&dzaCYkhZ~E~3^ke`J^KYoYt_w^;K!p57u|CI9@$=tt zyhl^}g!XOo!#!8-hc{BMvlAJG_q}8x9L6c_AX53+KrN)k3j(H1Vg<$DneQeMkL5@wZXfMT^)q9*de+hO{u=dW#fa=Q=^$CYr;_82nKuPqPzmj_fPWR8+J3cjhEszf1+R^VnEidrip7ndooWj7qYAK)FD;#U5UvGx?p!@N)c%RaZ!1@(0HV4dR%!X}p==~B6iHllv29T)NV%OpQ#xSb)H0-3-aGR@yvzV>`g_@@=P%clS z%O6Yqydb#FKe+&mMn_ihKkq5FFmexTZ>lanp4tN;VQT}DXwWOB_!_tDFll_fP; zV+^4D%_u1;`Lt}y4XN*pLbbZ8p|Jy2$^%dD?tq;e!`X2z5bwDiG(&P%q+S#vKSrR@ zEQEbQMA zDCM(M?6vtKUqSfpKYDud0%ib>hspczh%Z1Jiw$$t24@D~rA!VO*m2c;tAW%-ITwjW zeTi@WMh38p*@S~<88kH{14!J5gGC0u>R-H}0|gl?ELAQ@C$W59yxIjf2w^krFtM*o zuLSU%AI;sMDYd*i-?Q-|ry%q9bmB}3#%Bpc!sg)@78Z`Y0aw__eKT90X#3|q5q8W9 z%Y5O`(p-_b8qKvkuaZ|yd>G#quD95R#4>1J22^rzB_OE<_Kcm76!+kft<`YDFrD(L z?w8lY69AgEb(cQZ2K87D+A%1Fl6#T%yd2YO`AH>huSQ{`VXm$ERr1Im;Wm{+RWw zuxqKmbX;F)+R92`zlw@fy=hScikK;YZ6~{KzbBVUocs-~ukWa;ov9Y_0Qd(Szo8)+ zj8w~%1=Tqd$xoQ2r>74KClzrtk*Je5*ZCxZlS=tKFula}%*+p!0JKkd4kRcjc$_d7 zZORJIwLj4`u3uh(*I){fg}V#i@iAU0k6xIq4fcHVPXJS*qoX_P3_WUS+}`7yp;N8% z0bNP}STbTPVGJ6krJVsq7LaCvPZs_BS$~SOHaXjX% zcQz-^0Zu7T|uIGBY zv84^S!@WsrDVk(epc&xe`HVFMIXPm+Q1^R%siiBNWNSu0^=b>l+nS@t2ww-QzVdq? ztpE>#9VK^O5;Qv3pG)n2BgNKyAjwP$JboTvNgWXes*xhm^5rzNEHAt(Mk_dHSQPz3 z#+rfUA;=F6fd5EN-n0qLh};M$YZ9CCY;$M9MB(yMyuRRH@!Z1l43A*$%KeiJ`dee= zIDm*^)ElNAPZSA0O!&guRI_s9OeTf3(!F5Lr}90uwssG21`+Ur0oc*S#jDFf^oXgz zS{()u^Mt0iy&ZNVo@e9XNdjUm&Kbb<_w}rv*?WxOpHO|jGv#%(nGqHd7bhkt`1oSM zi!YL#ZH};>96l~C?)?D(1OBce6j1}a5wp|pghiq*zyJ@AiGhH?DRqa_ZliB)$)9+= zsQv(9vCh0$zxCS_8ZUPakg!0AJ%Vrc>%&AyJTSfeNnB&om)|z2Ts#3i0XAm261c15 z|2`mC;JdVq248bBz}4f<9@%_*Mh^#*b^z`w!_jU4CKgsH&=b<7IJ(5tBy%!V0p|zPhhr?aLB51~4#A!wv$iEPsO%&Z!B8T3A_2z@|exm+yI?caNhRATy`|Iwd zi%5*Lp1q*UgUbeAL&Nf#%%fj!>kI89_Zw)pSM*+pi{BqSUrvu(url3*P9?f@#ii+k z#*SPL=P6E5?(rhcnSxb)dBaCQYkhE7y3xOa_Hcryksa(uiqJn70ly614pf;)e4G* zvWn3Y+HOf3DPGB7rFcF0dTTj|&IpVZ^cf|K1ptDjt*~aJhK*)lED_4P3vh!mJ+-Ss zta`8Mv>;?)U|`}R4>6%KLdK?f%}9mr4cL>RkQl!C%`1}J(mQo|Wg=l&PR~A(Fi1Pl zE)H0GU8oa#UM_L&++W8umjQt|%v7JQ@l+1)6Rs1 zgg`xMVyZdUE?;#*VTwOVKl@#_3?L3%yMYsfwX2|cxUq#1uE7-I0OXB2O$*@W_^A*o z{`vD2pq%ztR?l~VBIdLK3J}x_{4%7=$SHZMIiXr@MRYOeL;_?6V1WmMdy=QDM#Id7 zQoCeTv@=ajcV_flwjOrdhoZn-8;mblMZCe~WU|Z<89d?sz_oBlNJv0oc|oo|Ggdi> z3s|EM2xc8FG}995y1;ntUhWL4-OkIe zS?VI_?(19qc0v!n!YbL*&g6#g{wVBrzq+}7&9?L`yU-!@#Rt1}31XE~IO8Ndl;u@B z3MSAVmUE3r)p5_zSc3g~f>l$%-Oc$3Xqf~ancTrSOS0F#ix~I6aHgOe1w$QwF9g_O zobS!xY!}r7D_AgpKFth(#RKM358$*UQ11Xb3p_4I3lk4XXhZxR*g|GjYsU)A^DI&a zu7S_TDCKXN*Jt&K*U^tkcTT#wC4na8VqKo0+o*-$0&zN>Zw1R3ulCHZ*LC@wiy~4iV*E|!-h41t3_^ZE{$eg z6p)KCIPOjwbsl%G5MMd{9n+GPw-%C()vK;M5{OZuw2N08$;O@3)VQ4Xl*D1#1JIvo zpPXGfd!4z75x&9!k>>IUly?m<6+si_ia|$ZZ95ha^?WozpD=&01s2;rc-U) zv-FqC$$DDGM7^a)??AjW_TMH0o)@&mP3Ke@B4NB{H}NF@yPFU)hR`z~rj2AbI+y_p zh(mxu39cJA?H=0(+iwB84blvu3&yw!1M$-G@$XOgb{H$elQ*&{JX@F^Fm+85@^Mn%)BPLSw1lBEJX9hh%d3=3+ zVU=RACTi);1g@^!UY*n)G~GB~Z)F1x;NrA-@fvW^KqcDQ&M#gE%>NEBH*HqBj3#vD z!}fq7_tFuBWCQpEm@)p6taP{7b_HuNEzwCC$Jue;>Ly<*RP&WY&e%KT7+Q7V z{nlCX3u!66X%XFSNf~x3!IWV&O5^P0Qq5fccoDKp^>{M zId$TbM=_d(!iS-uyCROnQSM~1<^M8BP9JBBn8KUAR z@Tof6KC`5+d$|6~E<<*t!~#Hb_#LGU+S2GrM~L~y|B5!SL+qbKME#r$#Ney4rM2ga z_>1eq_TM2g(f{Rx{gn1v)&G~TrZfEiZyEl-%vLbwwb-+OLiQtl>Is1h(jFK-@b|`O zwtaKM5hVlpo(=9yk1g#FVbTA68f3QSXvO)YknQ(dkfu5ZTY`Ic5pJHAAlve~5>#FO zxwWtq>FNK@?(dmD6@$SU|98N2O1jg$4->fKV!rsb^MG~eF#|p z_?C8-^A@zp{`r79&4142-?Qq_p!!INqosQEd_v2Kw)Yq9%ATUNU1tUL2izBFXQ21k zTR7H)LiJHd<%A|R_yoa;EYV&Fh87@-gGoejn=l#54b@lmho~p@@ObLY_o7?ZVu!{! zr-(u)AlDjF9XB`5wY;mueA7UC0(?Y?!Mlj$*p7LRFH8T+r+KVq*?I3*^|K`65L)6{ z%r{epQb6k#;`%w_x+)UY^QW+09AE(`hjJuz2H~vObHc0KT&aO6-nTzjFD4;juujWV z3j~t!8r5D4o?t~01tc|)kjO)l#6d4Dpy7Z6+XPTy5%b<2__HTT-JfRjmD+E~IT{|A zovd&U2gfnN@QKY~346T}h&TS`AtS6K5;k8=EHH@-aFU#rB*y^JF^sJWd%&%q5UV%Y`wJ6Rmd4))lf!OVGb0rLD zt6{0Ufsql|@ATkcDQd*;&#=t^JZ|pm?hFmPeiq51dLTIk@H~?9dJ1&$;;N^w&j2JW z-1i+TaNMVZpK9_n-EZcq;reRzrIH{EzaWY!T|(Z#Onzq3g_@tTZO(HfE_DrmP(5)NjWR*t!7MfUVB@08IdVV9mFF zb4O~M!N>NRz!?r$ovGB?lEIo1okbTjnGB|)x)cz-f?%vATbtK%dCm7IDrhp+~QJ!CP9=QT5hO`K&?T-&udWMSpyMI!?>dRwx5#XJ`>sMzRD3mbeObNGdaG!R`m<_CrRE#jy*kVHLOpl9wS%*y zkyrOiY~@Tn8j*25@3f#0ed4}a_koRug%l`o?oVWbKp;r-yz`*qRjjLP^%cBaqhR5)O9*b1zLUqnPiz|HdEQ5ImQ7ZsrG=7;AWz00zx7pcsQWZ2Q55&q_%%cDA;34^P`8qLY-ay>M-Nr zsKh$&vOy%_X~YQEGBSdZYnnT}ckO)h+EJgz(W{04aH2q4Pan~D0%~UXyf?c{%q%Q# z-o1MaEX_;Gn!IY=K>Nkz6(CC4Rh_MOLIW67Th-po;^HD4iFL}&%+cXvI7}=Yu?u;{ zIL+K?zdDtw%1T`z+GBTJrG(R2FNpgQ76t(c^Xl?3fXGs7Yww7?99#J(_|( z2VzNCTU$e}9d>Mh^PGyR>Kkru4XXs+d0t8?x`=g=V|e-=G&uJYsP!S3$mzd-KbcaU z`Z4!1Xo?;xY^h0$_=4D{BU4Z%Rz3CO=xgPwI_Dd3b-LyVjz$N9K&eE0?uNT%x^?K) zv7lr5X`~L};^A#VL_~Ud)esKS1n7C&0eWod>gj!}yXNF(K7O-%=S)vSOS`nWm{am1 zC&+xFRN#0`URHe@dc}Copvj2XaNo59ONRh$+z+rfqdh1u4Cny31-g);fm{K&iy;)> z-Lw2&fuH$ybY|Vt6Tng2_fcJ)pp3D+Waqo4iM92FGYVFKAXSXwI5FZiu4T77FjIPw zpP{60+95X!y4Y4aR34rmbrqpG>K^`VHL)<;l?}aqn^i{`^ln9b;!c)X($;;71u^dr z>p3sol;7{)WFQkP)xSXvxyg^oj$uaS;mA_PsSX20+^wSo-muQIXz0E86p>8ct<4Y# ztk3P!#|Q=L%~DG}JErp4@RtW9wFc5U`}YfTlYmVPShYIl=0U)P5a$ilKPSoQe%8fe zs_Y5h-D%|Mw(}x(hX-+I2~YuD*9QnedeIS^7Kln%F|4o%FNu{=4@LLw4Zql5;dc0hla+6 z-&f&{fn}*BaFvyn-B75=moFaxAHe4R)&;bcCvZ4(FflVjfU~!^PgPTyE93Av(8)r;&8@z|GI4%Koe!iWovbsOWQB~B`%4knB zBEur~eh9vmNMgkT*I80oDx~NT-KC$iyHTHR7+vZAl~zkW=9%5z3hQd7t4+DdD zV7eTFtu{R?3lTtZ&W8Kc!*xkKcGxf%LJLbvSQiOcpwDi9`Ex$3b8IX~+oV2n4@0jM zH!>wIxT=a3t|jWdeC7$+11A^PO7{@y7Y7GL6)7E^*XR3l$fYX5kq?{!IXRRX&ucRs zwSe^>Yp12aVTF#$j7mmn>8p%8;m^Ge_V$8eV$a;&_fz=k-@hMHZB)2FqVOO{PtQQP zA9*Wi#ksp-Fe`i$(sf2KQK=^Kx{2zgh*t%Ei`RpA1aR~L9yuWcO6Joh1IZjgrC;^W zh`sYCirRoUe(6@0RAi~1X`yv$N|n=cdeju=GUykEiwc*Mo7>ulW4ye3VT|=_Xn6P= zn0{hj_4=dTvX^V)^tQbw>REM`l+$QEtSQN-%=dK<#fN8S|F5m@4yW=D|34ZCg=B9k zeG(BF2^FF25M^eRbttlT_D*I)GCq-$8IFB~$P5|b*cr#(d;IPvpRVisyT0G&>ip3; z$8(A`Z+2ahV8J5cNCCJDjBCXT4{GNa+*U@P1odJ6zP^WG z!9RQ~B34#bCMBb|Wn#h&T(Sb_X<-l-qKYKG9s(1r$Xw+_sL->O__uex!tnh~%+*Ys z4|R3h`}#s)<(xPUb|~*wWX}NE+!0YHQTV=Me_d=+_J^XP?hoP%;jj<)&98yq8yarP z$Q*^p_=Uqv&)1fgEL|nx@EKTy+Wq^)y1KfgR(@2$vUi&Zkz3O1MXBYRjVI+%4D?hVPywUbP3*1%-vl zA98QZF^l&C!+1!y|;`^u-3E+!T;u=Q3OJNYb&>3#$<5 zdG*;sF`4m|+nYYVB+vK9?=4rfwX`G-H3lo}HOQZA6>YB)+nSn~Ce{=3VKk~5a-VHm zFw_K|0yS-25;r%uf1AX9Nqp~0&Cfp#qW+1d zbY^^f96VMaCKOYRzPNJ$V+FqS2F^rq)u)Pkh`@&9E8OVk&~ug>=|x3!ky00NbI@m{ zqpPckGw8R6#)j2duMQz5N%? z3x~J0Yv@*vE-o!A8v~~?;Mt?tCAE%qXIx3(rwiqz3yn%j0<*moS?n-F2Q~)mAk194 zgXUOJXsB;t;Z;Nh6j<&4U3;u6P`S@n#+s}~Dj^{OEwkoV11!rv&rWXKU`svu+7{mI z?CDXI*3B`*osyQ8245QHZhqDVU)-L`!g%dt08?mzctm@ewaMIAPmW=r&LugpGf1Do zcq46bX{qJ&S$v^qAKT9-rlv-Ke0_Jmd{jh4WMK3$8qKHQU5y{zpBp9?qtn*D%*Bp-IJ_0k zzKD*d0oh8Pjh)MxqqK~S!4S0@!6f%nJG)yN8Z@)Bv!&>qbO*i*7hbl;7n}s=V8*Up zIFO&eBV8wLJ9r&{{HlQgR;YrI&3v@bJBM8~FOA&eL);jEi9b-@e7Z%*{={6C)B2=- zFDyjD6%-Q_8(t+K9v3;wo|H`Vo4->~hSgOOaL-OVL%x1E+0U5*cWe=PW1M;sWK zh5BTfKq?lNOOnqn@01MwWLdkdD=5gELqKqqUdy8r z7?k~>gfIdb(`_p&UMT!f)6j4y=470*pKSdG6odfm2d%F=>ft{$ix!2FYz+wF#S}5$L4FCz*1+R)hi|}1ZfkE(E||~%3Hfa(j9mhU%R!ab z{t7!{_`wX-1BYQu(McyKCt(qhQG_29>JXV%r24uY0H!PkYVrbf`Q~V7$5ueIi>(3F z%0TUf9dSHhn?RDF=Eo08KyB~;g1`oovZt=8;?<&UxbY0#g#GeG2A%|@D#HMwn4{6(fUdr6hK2FU$8Dxi(CmHr=1oXk9G#}7CI>&i%Gel# zgBi0Md%VZO)Km~4p(Bu8T1F<)vg%s6DY4Vi`o9&mP07kS$rYu*zYx+W)R|YD=}Pz# zNkdJ|*x_BeEXcuug3&%%P}v0v#o_7c5CC#8yBGp!Msv`GQq$29gVixKH1zZLzZ2gN z6R99+od;ydViFQa=@k56RBIA+G9V<(!lI&M9sepafn_g6f48)?1>X3DgCv+-zXA;1 zk6`Epg~(?^VL{Vo0Ms22HBWOJ8#&;ChH=HP{mc`+JQa5oMwzLpeSp0O;b-k&kNMHm zq~Y8q<+bk)nutW87hC+Ca2h$|po0!eQ+7S40R;1i{yFFajzPsP0E6L${SA+d_<+Vl z$uj8Q1;BF&#E`cx(T#0QCdtE8Iovy`>laT(Dfodn_Hff>9Kt^W8rZ`#GoheRTiw(| z4iE`he;wE|HBHT9VB(;fNGdKaPKM>QVD9U500voSP}**5Yx4%qbnAgq+O@T{z3Ik! zsD2tj)ke%~|9W#viy)L5k;t8okB_Y1TjW{n9xlah+pRLpLn)r`0I=$6C;~j)TzoX! zSEy*g4z!d^poZ=X^HiJL+r|*0->pAdbbM@P2&yR%o9AM&^`O_h1k2zS6Vut2mr|}* zQ;yS$sXq*cx#c5d0a`;u4WTMTmzbEixUqq>wG3hYGb-Qe>Og}0gl>_w512=Y=%0?( zo(PXHL1kR(|Fz@XgGMe36vJvkC9soC0#mlEKCrX_rHx#;>@hJhRXsiQAkWOiT1ME> z(bKPh?vQP1qGO{N2u9Bwzi~kMZfSk#akE?UmoGGdr&z1C198=ZksC~CN$pF9K2uXu z2IFqknP-1P7e7& zRe`1=qC5D`Z(8bXw6Q=$%d$8((ZzFz!}8(nKnOF#d$sh=Eh**&hfichKeJRVJP18anM zvvD)Bp38iEx1muLH4OAXH->-RARK*U3Ou37+1V;+4_Pj1o5`W>%z6Fv*tpn~g3p?% zI-T9!j&5X6dT7$4-@iEqph}vpqP&KEG@kF~n@+7|x8S|PNKB)CkH`lLJy5Gq7vB>% ztb1pBdnqR;N8ZDuqEG5<$yzu%`M@Ip!@P5qQKpd5Hg^2khlqBMs0H9UrS0*o=pJ*w z*mSsZ$n=P`JxjSnv-0!r%{>b{Z?+0vGFo`i%Pe*SqcUp6CG3ijaE(_XduyF6A9#y{nyT1f`uzaq$ zjI$O!s>-fpB&XPnYS}rOMgQ&)_6+BPQox7deAp3ibcY+^sH)WIzyFDvKYGkg)$!FN-=1g zq>Vg%9z|jW2X(l02ofQ;-rvpD_=uEk09cU2ZPi=*|2vN7i&d}NJyRJK{{A`F^ha$T zcHWD;PxtB^oKuvg)fZI~|`!llJU(@x$WI)$KCOdkUp(2^bW}VBvnehMhlbu%_J)~k=Mh?v8tQ< zf`I|_2JBc@7}#LK>uumrkl{1m^0v2?vLBGwzg(u zXWwV0G1!dbS!QNCXglC0b5(OQ3r_ePKVl!E@!9#Gm75Bo~^R>Zm`Z9yl1+Q)CTE z4$E%;O=z^jXpgTRSDwzmm{ENCT&}e3Md?IYva!c`IbfcBn~IGs0+{Go(p8dPBqp-* z>lJ%LrHE^@ci5ooi}Zx5p+j83On@QtV!J&1BPfq=)(3knM$1KR3Dm7W3A*;Fzs^@6 z`_HqWeqfaHr9WFjmI-GXZ);;I_gqtWmu=m5sK!%=rh>Rdxy7#OvDxEC)>S%4wsrq@ z_AN#G(8hcdW8;^v-o5CKyYJtB>HFoX7hB|uiy47}cqcJ~gPNI)?98~*#*L z$Eys-juUfE&ajx4$NR|dvforQqEZ=u|BAnVusgz!?*s$003BtxGpXX>!xv>v^Om%f z4OYlR_Ps9PlLBts}$< zW7!KHSL59E%AKiswX^;91l$tdBp8p5(Wp<(1fx)7m+r{k)Xa1GVPNr=WIl;u{pm(q zM$QG@`ULybAMW4dtSl^oA+pAoyJ(~)?5@;GQ(xy}07x8x{%3cZq{8bJdVlf0nHZV( z(O+1o2KPNo82M+;>aB>)t*TTa1|e69{U?(Lt9SNY-%^^*SYD~ag!b0EN!QiZ^HkUO zll%z09@!*q5XX#(`9|s8=+N~|TfI_q&PmapoJ(8I__qu;pO2HgBoDmD+2)q;ec{NT8FkqpX4@<7m7 zxi_y1t%#gbQU;~ga*v7m4J*R{MIOd)*)s^6Q=Kk4Z%#{TmKWs#sTYFRq^=dV1ST7z zjLgvfP@kp-`mSh|A3GwHCP(Y5Z88%3%4e?4Z{xL18ss5-JxxOcsPYin!1JaQ>JPA7 znOT`)&1%vbF15m`YqOW=YP!%IfWzVB1cSrEWC61DEZwG&+SwJ-D|Wt#5xl3Rj~a&J zqL|$(DL7)ez>K371dHNlW5f~rdlytD6XoEzl78o4x73QV&zqE&CM1g66C?2E{>qpa z)v`M&(iux|*ILrRW|soxd38T-{!zX+tYYhoV{&C#||3MO42u-tIN z{3b7lODnc z=)mgaF^|dn&CM%84w*#4PNUwj>rCEeit)(>1)65eKhttx;Nj0bkE#k9;TAC7Bs~^! z5($MDq4nD0O!QY@lGOan)3=hT0PO&))@B)|dDQ?_Rk}7~^yCRoqT^!K&03o)&<=b=e3Hoz+C@jEyD&`OR0m3@M==)+GpAi44JcWs z{=)gOUhv$Z?-2LlXBSHy=hJ;PZe?W!AtS%X0z71I-Y}Ic#&cT+h88Ce?l%~dF@4(WD6 zN(${e&r#k03q5)A1e@>5tO_6!zWA9;&X$011Nt{;e2J}Zm^hF4(=YDzE-bD0VgGf| zj&<_*rVkaj9+p|wT&UonZg_Y|N`Z9TXPwF;&_w#F!_~4wyEOYJyIpEdDFP(`E&+6p zNNo`ka>z9^Ma~1*jvzW$2AjO0yzn351;*s|4!11k^1|Q?K41ec{n(;ow z^2`;@2sb29qUa{*?8YiHH$UlWM{hc|#AohhfBF=~%zI8cu&O`fk1zYKGd26$M3r4^ zYW9E>=+py=FomWy9?Q&nAo)p{Cm?uX4`TfXk8jB9KxL!^)UN=_p|;N zI_P5#h%KZA&xv$pJC>bP>)O9FC?PKX2yU&Xj?d<`uAB1d6;QEzZgSG`KMVr<{k6+V zd+j}?OmwI1*SF*^V-k+hYtw^*UUf5G>6)t6;2O1)%xq3xZeHQn4l~8BqMi4vvHLHX zJ-Tk+%PtF)c=alJaT>2J2oHv($(1@U3Q&$lkiz)*KxiBM{l2lwJPhigw@oy-p(%_4 zRct@0g7ug!#YIF!T)1$_J155$>oFC&OW5`in(jlZ8lRU?*4pjN!rXB$bje8YO?BS^ zJ;iDIB%(i$@#?UE&ka%4cLajWky|n{QN>rOt1UUfft`*gGEHC?X_O1B9Xeto=^km2IuizJLk=cCD_b8K%rE+R(C4DxEoq1EsECfEJLE zleL2GoQ~HR8hQ{o#%A?Sm)+V;F9kO%7b6BbN z73uEc9;G?>T(mNuV+D@f)6=tK3n0m2kC`I;wdw7U6o)Wz(d}mW9y?Z67D4D!VUe`c zL@PnrZKO0I8@d!pIe!S>8-K|A$s65J9*1S5T5+4x@C+F4aXjc}E!+122 zhLpl<+{DdI0$}8{CizR@FvxV}akAy1lR=JLYd zeBs&d$Gj(HlIjgN4zz5xf$0kzQ%Dy^yQa67ab@C14b*?#o{x|19$$fLp9hT_fP`;u zZUZ~d=N|3E-H|ovVT3Pye{q|A^-W|Ymo83pqQWQU_nBkiRaEaP0q<}|++B6;xO zL9y%FMM!#=ewjo*vKqZ_F)-1R6gULbu#h^|`G?XAPxFR!6DUjCH)11C<8}rXUcP=E zjGNsFZA?&leeHM@hD-h7Ju*Omtnd6vSz;)8R6|^gV~zxn7K%xXNPnryJF#TD>*TsD z0Z?l+YUQ;@E$wZ1^kQ8#9F2@V;CIOBFK3{!lEJTMh5vY$^GjV5jrEAp&OJv2P+o3+ zel;|KzJ%TgUiQNWS0RX#ivC1xJ0pe&rQWWtpsFYj2vs9*V^=o+gLMe97nj%XmAQk# zJ;i#>kK2&->-!2f1}{mS6613q@^Q5>Fi*^Rk)yG(F&A3#2?fECsGoG4R|tzOUO3emS~<;&{PJZ4f*lX7-(c_cGSEcHO+$F`z7lpyk;1rnNW95E|5 zEV->0kf{97Z&I@8OU;$0%IxtOK!n<1>C#~ zB66^QLj0+lrft0J4Ntdaq|U0YXlV}NHA>2tqy9$}lp` zQ~p2mf<*l-2JAl(?f)yuQ0C!b2kM}3Foi;IULpBR$4R0^uX5A( V=bVzbdQq_5xve6beaq;@{{wH?_qYH6 literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_main_buttons.png b/doc/images/jobmanager_main_buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..e283d9dd5661331c98cf39aecf3d9b956d5720a7 GIT binary patch literal 35060 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 literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_overview.png b/doc/images/jobmanager_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..24526bba4799c9fe5438f0827a1146d8b26ab779 GIT binary patch literal 101581 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 z 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�v`ln%yy27=Ty}ECU@X;0sfC`gXSJ{JbO8Qo~RO$mFm* zD6zqHNU)J9}=w zH}I#Az+f%WA;<9N7X4q1u<*e-*2>{2d23tS#CRRW(UI!;x8v5|+u_BCIwU$0t5JwB zwbm2wHy0q!LtwGP;dyiIU|{$=R*87+mQ`h_E0USDi{&2~u7^Po=Glu+q%NP@o5$G~ zd7xW*Atte{l+xl^*H>4w9Q<+gU~R7|7FE!zzhL+JbGU~-{Rw4Eq*uUtk8f{Ujfs)5 zu_opH_AnC|?}2$ojhN?Zv&m7RR8Z{Mz%%SGE%Lim3x|93(}vlB+zN_3IPMa7$z{=H zrwxuQ`747eY{Cv=(~ske4FiYbBF~hw#NE$*)XxQFx*#2PI|2Zy9!@P4Ln$aoniKT^ z4~K}}+32vzH5Qg%SlC@qgvz4ZN}2DnfA&gKM+Xi@zr#1$O}jm)@rF<3PQcBzKPF4y zSFPm-m`)JE)+eVVFIv%ec|SjgILUr`EShLkQhC^rR2lGDZWlT^S)k81`XVBh#qScA znyP8|?iOHUx+h^|V`83!F&aU|1|Tm~y?%vZP~>_woG>hY;hcksqmv6xO#D#woXf5# zH8V46)WEL)-s8OL`mU|p)ywM+cK6FQX=Y|-u+!c`86$vmpu+rR52=^whg7uRKF^7| zgC}6o?fj|6_zY&TyTJ&Q3gcu8D!-cqypl`)3J{mMV>)`--wy`87~2c$R+Dfz4wBIZ zJIcVkxb7`hm~ZEej@uEkf@JtF{JVq4GbxLYiZyt<<5$Vo@`Ta5>wCf=-`+)kO4=bM z;Vq9=%(6zbxj6r~7NF96oVl^3feG_*^oqn{cBOgbwco0DD73?`olgz0LA4MiZo`K~ zaR5azUU>;aRxO34tD zkp48p&P(7Y?{pq0_jdPpnHTTTosmHRncvMLlJnt=g4tr5*R|?neO;ZJm$H|aSLPe9 zcbY%7lIcEpWLIRhk!@^l{yt%xF#4fg0C3+%2em)={2p8TYpt!VRmWZm3+wYCadL9< z@$+whjWQcIcV8HVFS17rX_()eD1fm?k^5F>yG*RpVAEH3IQzHqHj@5E?!trM^8UNy zpqE?+Edh&uXGkQ$bpLousng1kLAXS2HK{X*=&Bp(dvQuKAMqI@rDM&^hN=v^=xc3i z;A|F;Is*}k;*wrzgxB~ko7Gyj!7=Mt4=nj7f_{q{%60Yv{eS}( z39exiX&*zAnd|dBYV74t@A1a7&9#3s8_Uqz7{xs7unFm?zF?6Uu0fF>NizbviHlE;OO|dB8}p; z2N*xB5tmVNOL}p1q-(wCO183M6XM)US`&FrzSNvV)eC?z^{3ZmI`n%RtwnD=3-+Ps z^0l73B(3i8YKC4JGXkd@lIr0(Iu3`ypD!pfo}n$SN@eQv>_vd zEm&sYEA0~`rL4pZcv@r+mi@28=mF??)=f_pw=o@{Ich6JFpd*9fDez7s2 zj3FZu-oyS@R);I2IrY?Z#MkC&^BE{q5rq~tLM=onHL(dIXwMqed?ll~I3 zf3Uo`(dcjtduPF47%3;7Dg3ab(H0(VnaX=jqu=%u`)mSGCpm0T@$qR1`6}66 zPn3NGJIBZ-2zg2^16nfVHkKlEUQ4L5w|ZVauh4hEP6bG+&p&gRR0^Bz1;M%cw4ip0cHKZC zfW&{r3nFy1REP6|ghw^}@aQNCz|*O~jNu@}7u~o3Q@H-KL*!w+NSO{dmCuNZT+kh+ zs9*8){2ZtIwPN~b5GIXoKCioHJrYm(6rvh^Xe~4xTzlybJ$tnQ=_l|sesM&y)dce? z;F`ZZEU84jcr-TQTGb970imldhY`lGv-8>M*%kJN%kd0=I5SB-J$r};XVN3wt;xiO zBp4Q&fw>EGWu3h!IPr0D{vhEr{(Yd9JO0nrMdv!*m%gApny!KVNyvAjapAPP-U-Db z_ovCzqo(y!A*;2`C=85TvTH!mK*i}(X%MFQPy$P3m4{Q8@1G5pQ$jyNU*D%t5<=;< z?cey{4q09bwz7)N>IXJlx3IA(A7}VJJ(#T9efU5yoQd$P=TEiuP z&Z>{y<|iS+(5S4L}KQXPNeX)iQsZsh8G{7eWIw%$jdzsX#07o5Y5>Cz$}*(Ead zyVlF`l&R{Bn@qkRc>OU@qQs)w(D?XgK&4-0BE@wjg~pKN#2C*1GB;vfZJ}dWltdaW z`04Kwh?T^>O=Iss>*t~cyD&I{MuE!_24j))dPr$8)1Si|NPje&P3a5evtg~QtnOEz z9w>Z;FKT9>2vv7pN|*gWm-MSe!;X-MsB3wd?6p$n);*#M3f&JVg^XwVo{8+_)N@4` z^KG4zuV4i1+=WY*+3i_>i_0B8OlQwj-doZpU377A@uV9Q5u(VdoG4~4p&TON)3o&u zlp~{~FKlgXl~cy=JyfKc#>*BPo*%KsOJibU`uqFC)ZKB}Ea39mE@9TEWn`4xQ^4F_ z9Y?nN+~Irbr~fOt81ksWznd_TlI;618#)~l-u3EhI76&d?Bv?s4TQBTGxHNQyUJyd z=*lTbCh(Av{8jSOMTs4s#bdc)l0BfUFW%w*UGH(2bUg7jDul6;iFmkFA7Jt_?-5o6 zb@-^oS^lo|lfmJ=_fSOtFpLiqZHsOUi)Tvj7Z)=unJQTHjtng<{1acB?JfL9ABYi> z$l@=wm>tu$@m3f(S{Oxl+RcWCIa;L%QY+Cr{jK4*ndo4**&RYts{1>y_fP z!y8ahLO@hn6h$NjX#r6{Ktkz|2I=l*BPB?wbR*K;NH-`52qG=r-5u}Tdd^+X{e0he z|9STq$8iR*_g=phbIx^L*PL_c+S$Ato=FmrG;d0omGpR&GMq;Kz4P@wgi zOI_Bj^_%ia!NL-rmYF(kM#iAQpmybamC^86OAF54T3V8!EcUHD$HC$Lrn1VTPg;Uo z4YhTC4!dxhT+=?OXh%&m8OK$ZzJdXr=qP#5Pdbd`ybhSDslxl~f|%Ja9SPnb%iq9a zqoPM@^)c<$yYbt|9D*xWH$304waj+(<6j-g>Fvx(Ui9*%3)Ig9NwkeR*U3&;D-#ALT8yW^z~#US2yM3--*7&CTz5$#@;eKPgeQ>G<5cHxsqps<}ChpMV77K6E@&{J8NEq?ygG{I$3&;DFBS#Glo2?XWQ7O~iE zwWPMmkppY4&7=3)wut6uw+GAp=RZRscLn12H@4yiZ-|G-3fI;gp&>jkaJJx#+0j{6 z*q4bU1n=JBQ3?7e7}KENQu*{@xQ#9z>ba)Rc+icPNY^)w`~}}kikl$EqE=XtqqLtt zFF!3Y@>ySZ!K8U{dX&;(-N3`l{7%zjF7Gq)j5?aFpl&X~zW0C^WG<=Cjs2r)klH(> zM1hti6hBfFF&H%5E(`i_pdoNbhR*q4kMjZNPf=56Mz?NnNfSULX%yJS&mW{VRuR5f z9wrwTDolbey)b!)`L_)&X}D`=>w0=WahSc!WGgz%E>{QQMPhEF?MdIz__EdwFU*svz5eii%JElQ3@YgFJ6V!@PaR_oz@~`vd9{ zYd`r(2=TbOUQp9zH8%Z3cDT6yXCRrEWS&fb-_2Zdgs*JbVkolO(!S zxL()!5hhKF_4Fud3OOYihU6G@C*}6(`qLNs;C4(5-A5lBET13lCn%b;dDTovuuxtV zQg=o4-636=w*cy@?$mLUQO#xqkH@~HV{NbSyKnlppJcq}@XKG;zgZcYn61ZXI15a^ zB@=#A`Wh?CEi`lgfGlPfz1IW_e$IO|3a6)rGV~I$y>G)Lh2-j|EkOtIPg${*3P@hJpF+7U5z9%HdSXZBgdo3L8dTzrn3$-|<+pjbV_fBSLWU(ZXLw3{EsEL^vkI1_fnz{Dk$Gm3(0^)wJjiti97 ztGF%?cRf4H6pNsK{y)#kCK{9X4ME5{7| zQih->LeUF_O4XcBVgXQF@N zQ*ai&WPdc}@%Nwm(&5aoGGl*g-;q|Eyh0F`JbA3-O;{%+|E|91YPV&_g9k#c2B^pT z^UAzvQ~oGZTotZv^_Mi0=tQ-&Zap-s@VkT^@Xt@g{d>?tM|4bRl0p^lc#%vG%>utk zTqj1&-tU(@>E8qN+m)v-IcF2Zo7T&!a=rClKu#c|s#7^Mv#a$MqN2rD7{HkDql+1- zuoY^RWM$WV{r5)@NT+=Kd)x*Z@&R*UOE#G6!I;P)K zY=wD&pE19FKA^%dl}M=n(MX7adAaG`N5Nvf#3~x)2nIEeTY^4`#{IblJ;{DURnU7) z3(6GuKD_1~8%u5jQ8yqN=_+MRh`R220`UmOrvoj_yiVH}p}W}rgL(0hYG(lB!xK7s+h3On>6jpAH*v%8KFBgZ(h3yJ%l&tX)Q_%JeDUYTq@lz zld`S7)-R>h)EVG1!5a%2Pt&af+i<=``_wnPL4ERy^_0Wt}a`} zjI4JNO_2c_NsyH4sf84?hli)v=i0MV9;h{lCQdKzWsd!(GKMEMF0KF&PzJ^^lOyd; zqJe6CPK0LrEF;%7Tdc~OU*0cEjI_ENo?g5Jm_)htphw2Hg+j9`g0%pezc*i!STa}F zPjWT`d~7NIcs^(Cu~S!XpCTM(pF2VC<>+ei+V-lfatQ07n*UP+gL^m8B#a|(@tn}A zx8;6xGre6URvz5XE&Q&1W`CPML0fj^n~A-no2LCXv=4iVe59y#kqv zD{iN5=Qnq!UhrcLXUb>!L>1{Zlq6({jYcr4U7$CnN4UpSl0h-)e21^vO3EjdjBIRj z1NwXMzXm>Q-3Ij;0#P*gt)=z$qZa57G2nqRV}HHq5Rb$@=ze*ST&S&7#&m~jY8J4G z#d8)xMxF;y#X-y591j~C`-}DT!0`zQZ`CfLRlK@Dkm~E~02)#87lga*ZEX!bDdGjl zGq+bnnSBUiaiZB0$7)tM*qgkZn^G3l9^>Ee$uVjbu& zF$jj=@>@pA$UbfDIIFS>v`64kJ|bsfVc9=gtL;veB!fLrpRDKFr0(FpSd!h{(tK@= zqsT{=2ZZ_Vr1XwY0>d}+y_&v`f9t0R`1P+eVJ3DRhc z`m+7tlKT+~KG8WU+TVyS9RvU$pqky?U6&A<@~JD|QD*Y@OHTfp{v`wTANL=H-)eu? zL<_dAmxBU>Txyzt+{6AJTT>KEB+ooQ0pC_rsg8NJl`^aEtJ z_MO!F020;@CbZ4_kNsvF>3;E# z!N_&bTe-3!RULCrRezKf7B_^Xz1Y4>QLvqXvs3UW(~2aX$Nut<)aQZ_L1u*NDwpj{ z%G|s9bW~9nol7KM)<7sioylThM#kWCs;mE%JUP)8u5t6a9^=h%$ zU=cS4uPkwqZ>8{m0q|coC+w++h6Vwf5gS6nf3s8I13D-b$IKS#GLA!M9OY-prrH)q z=!{92UVgr~HQOb4c6uVdLQXF;I78~M@lk$`I&tuxA06e_t+}MBzVBLoXn*fh@JMOx zJKe{Y>>ZW^!-KbQ=b>4yHmA!%KQ?T> zq6YLLo|go+^Tn|nK^JgI$7k9jQ2qf#$@LIrsSf!+3fIwU{o2vdyt^`7aMJ><)MV7d zFXV1RU0q^tXBqPzNgi%g=9y zt5nZ-(Q|%5_N464`RlBwIJ-*yeDyAz>0$0OJC6T!+q1!0D;3UKzYl<>=FOopcP zZ6`}z89)Ha>{RSrMln=u=ILlXcMHTc7tfaRYR8AVu9>sDVt2;HZLH*)`?H@V8je9d z9L-K5>+$h%1O^6%l9EzgNiDtI+F(veHh`$zrKT#p&bt!S9n;gVP@f4dz-M{cBwM-q zf?8~4qHR{+I(X^cUb$-e)}-)>wc4|wp%UXp06nhTGOV{!BGbKi*lh0Q2V2Dm3SuJM z;h!*vp-vUqC}>=P9dc@px_nzcj5!>MqXKY=!!C{~R>==62=G6NW%KQkL-Za4np%mu4lH3%T6iI|l!1Jh4!rUmxe zXbAX+z?nv2+tHY=2-e9&sTK`5%s0^FKAB8X&55sHAXIfJwYuPr;$+pv zRvQks=DI)W7Z6%8_<0J98?N#-b79u#k%V;+ z&}v|-6W%T*`sdsV{h8Zb-m>ozsp}AzX|9fx=a&}xl!UR*cEr4apIn^4#JeGs78Iwc z+Ci+x{*C#E{oT{Ut^2olA3V4MR>3(+i}&Me@#Pf&ZyPAF zCW7?Q_w-#)?G!ldkd+oN4m zMBV!|r0IdQk0B2S zBFqBVxUlu_-=(rOYHvV{@)X5%0|0r0&nZ-lL?KU|;zz1vBjjZyO5L-V>!bkM+Fz7WZ=H-57;^i`Bbg6!{y-MNNVFpRf_JqUE z%vCAN#qS>&P*O@&VURppdZ_?q-{DGp9s*f{YuCKz=M8=qez8}~yL*tJnEL>&irGRd z!#+sY5{IfMn~DL=6~-74B0f6pb)6A6@Z?iHXKH zTyB#Nesg(16({w~pyoFEs{JJcNi6KL!omjNF~282BSbugW+K@+Io|s)86FW4M9DI= zfakuCjz+bT#+vBs>!Ujwt9Dj2b_>-S3c`I%eGFTIZUPQpEA+iZO(s|glnMrdTzad6 zr3Ztv)6-s1UU3Q(NLSSq65I}HLA3DZk?Y}jjCoBx^!xN;CL<$*mL&C~qv|&C+XduX zbDXTKC_IYGWk0{IoEqpW&@4g3;p69bNkT&6U3mBf=;MK?gA$VRJt3lZ&i7om9`&B- z8XZN^x5PYl3=eG=?_?ftr2)X~BvM?;RvcDTdTBkWSVL{dx1y^n=VeI)Y$2?skmMA< zPQ}x?Fl@rQ#y5Da>l2OQ)jEv+I{5GPl$~nM*$4=rQ{ARw(OZtZB3?A*Oo0-5#O;!> z+Tq+M#V2^L9-!025)D%xpru9Dh-$(3dE1J%#D(s@l2!Iis-z^k&MV)a#v$x%ZJ$a> z;a|V6j)Q>vkVjTl7XBG@9ZH8*mH~l*8{_pD*)L1PsQDBX70+Q}Vjp2*Vj6e67E6>Ek4>?yYB@DnGE{O2{-!SzJ~|1`yfRWy&DJGJ7}~O2th|8>`_rMu?Cpm?p!sV zZrvS-^ikz42Fk5zG8OZJAO-c3)+gaW0dTr{UGahc9$mi0k`FrAPM&?pz-Ix2U2M>eu2N>^4ICwS#k;X(R+MmwfZmfRjv#3`xAa(9MdcHO#QV?{ zUMLKCYO{5wp#nZldH9^gaH**!Q1Ed>c}%84ad2123Jg)niJs?pf7VJTyu9d_DXg=L z`L`AzUbTocX-aSLdwpmqU*%q%YZVX5x!;wH)O9QI4txW#*1xI>99csz0uv_s;>jpLlN%5j}9-!$HxmeLB0Aq zFr6FF+@>CaWH7)GBm=*?u;BOZ9ew~Y3%and@O~Ha)Dw28f3z3M%+L2`5Te!!F6i4U z!$dc3+z@bpMFl!s;>)WCY|xkqE+dR3m&T#5rxyG|sqob$s9dV4tLqJ?Pa7IRB(-B9 z9vw^ru~CWxR!x5J5eOX+_?@lw^=PA`qt|lDx7Nz^yKXo*I%Y_&O$GC}^lKmk(J(ID zym=GoGKP9^Pttknd;ygFH{gU4?ryEGyTfwI$jVx7Og`w+UA}zT3AqZG2Ju6id%*ndS#j3{2jlIo zjHPj8CxvP`M(F6$3ev^Tj*c=D4J+C%`Ao0vVVxwP`3I*jO3$y4uiLz@&1QNA_eOP4B&YoiD{E`{Ab5_kDbG>L@wo6c&2jhFpW(jXcDy07 zz4Alxi)=&VxwsyN<=E)zpEz|f{-6Q+iaH6)EzC1x;DjO{n$kg+oRZzO#ltl{bN0qg z3ZCvFkr!;{eX700mJ`S4L6Crxqf#QAr(TUuK=APcr(42ps-(%D-}j77)pGUP2M<{D z&CecHL5JpQByYBNt`*$wFaSX(`Ks9}I34DiUnh*YW1oY- zOToc;oW_RDLo?HM8&KO@Spf3Bz|zTH;%}Gw!H_ydT@Ik&u}?Jok&191E;DaTN%OZjzVXXhQ)Qon&9LVj zVtx86AT$?xbOtvs%-`>pUnJXsUE2lbpu;lz9vdT?8sOaB z{UWS~yHCU%xZF9#*Ip{C6eJZ#o*bA2wiErv=bpFUuX$WeNMpO2WnyZg)iilK)9G*I zm1z&p3S6HDJm?o+Q6UkL+b+%yuel=bYqS)mv|H>f%2zpTpd*0xRWgWf^FNP}s&=w{ z_3D*xjneqsnqm^Au%EAJZPl-1(~&A$*|ioHNu7w&6G}d(--i2;7b05Q}4a#5EixcnyRQy$&Tt3YOIpZM%B zb8?D616S~>vNsuRk;X&e{n0;-y)>F2@(P>d3P;A2oJ@h|LfNcdK1t3>wlarJA+6Qk1re@DnesHAZ2Wpvc2?-^0PDSP( z;SqBoUSnfy%tUCQBd%XylDk9+aT}XLjr2&n(*;JmPd65H*g& z7H!x}B>&{++oq3$;SRFBkKhpZC*DxL?X8_Vt1V?isk$;`(;B+F36uww--+Hiek39! zL@gGv^yy&AYBFbE$%jGkO6xs#c^8eaHOHA)#9gXt!crET)u~@4Zhl>4H5T0h*-8cI zur&FFg&s!^_T-OTJ`3G-FMDH-i8y^33tXNa`43yDy9r0tM?pX8C96Z@Lb6Sb+GX!YrA`yWQKP3bZP$HZLqx&} zebd6u#37O8Dv(xK-X7G?P-4~P_iFy9qfPfNDIVoEx$kbRTYsXQ%2cNbj zfZ`L8Zi)Wh4RwZ_RGHdreD;}1fjZvMEbet}0{>-lUMa05Kh)rUk~eZG;Qu+|p*jgb zU*=14U+<&X%a~vK6jkj!HJBR*Q8b?%>cih@2duFU?{zSG9iKV4CU`{m3~GKvAK|t zZVK0LAVvCGsIh{e&B!;SpKUAR6>LISi21ppJk`zh_A|GMW^|xA^QV;D!o$N+a;d_i zqV5!NqR-{!@&lJNQ7%E=_|J`%S`s!wMH4j@-LvL{0<7N-&{Ll_X(~Ew%3Ev3`;Erw zo_IM$!k>%UfjnGAA$V*!3qG|h7KmU3ix%W){RfXkortUCA|xL?ePG>fY5Yp>KS9EDCQCnGvEsZ*c=lxf{|~xr zmIn8|!a?C|CY4b0eAe5IDy!!RLir~b3>V;0Ug;P82lxn|8wMzdCm2^83XbBoh!QrT zwr842NxSmR4(i;$r$MbRu#1K5)xUCJ(y?ogZBlH@c5j^)%-TV5_|40ozZWu z4KSE=tRCH84!6r={}u2Swv5lp=!pO2JpO2u0)+^M+?CAd*XF--#ScGM>K?PnJabcX z^F-TEdikWPU#*qaS0dBzxyrNrHZ1=@a;T`1v_JTWvN*QAnmGGuEGGg`l+)fSqY2OE zFhTGBoN^q5eDbL#cV9$(d!|W6ac$0V<^sytz7c=?TZ4rn^Pp8gwD{wg=x8j$%KsW0 z8Uw%&`e^8&K03dzF7hpg2M+|A0{h-uM9d}w%mBiZ0@e%cwpTiHl*ENGlA8J60zyDV z@e&puiN1J2)Bs3BJ`~2ZSsb_o7^Eh|G6uT}MOVH?RP^JFk-YN}9YpvE(E*~ujbdOe zFa48C&CC=7-Q4Zlw~0xrm0fJVk3WIRS1l>E_v^oWxv1Y2|FmuEDh@fD6!j`}kU`}) z9OtiLqNJTx<>XlkxmOxoU0o-DJy9t$zXiw@biloGZFXknJl+dD)#D?oP7N+R6&@9^ zW&#)S)X1=uJ#aun-E3Za;v-A*B21|U3l*J#7E<&#`EvM@8d1N0!!?@a|N`;W$g6DupY7#KgDx9nC%yiF&DQP3?y3I8(!;}Gxhc*A3a zJM=^SaD#dR0=)dPvNv*vYv(dk^P!8d+Wv5F?^Q@adM*BfNJ~XX=$zg1$m>In9W;dh z_4_iH?mw?#lYWl=#>*?8B7Pr?*oJ~#>#4QhLs6Z$jzGXDvXl&^&DK!ixA^1F>A&2Gv@H*V_{MJ>qB(?q{5~+)Mrji14c`2k4F+M-9qID2ojuR$k!R$9u{v~2KW&;K?|d0ult@gSFe@+w>V&b%+K(@xP3XlY5LlgiD5K%`?D(xJ&M;h9A^+H zqk6})*rwZ3varap`}H;{YR&P7ZxooJw&$%rZgA>Mf3y^T+~k*U-fcM*$orwQV*gai)Nu1Kh8 z&E`;%bFkDSp=7~-v(PAYfV$1i>J|wL1ehIw0AYKSt7xa?QSQzhekK7al!b;;&+bSxX%kT<-pQ1gMaLW zLWgpj>e5Ta*^8;ghaGJX)gy$erx~}ZisRBY2QEPp=2}DB+&>f2gpeF_O=2^rv65jT zmWL~3oMtEt#EJD;mN8}5-fiix^c~cRTa(i?1lL3?|BCn11>mArUo+j*+N#sEP7pcC zetwJS+ncbkYbe1goX?b+5pnqw0VU;5=gsM_VCzNpcP+p~A?|C`2!W-}ep!yy+1W|$ zRwJKN9om2J2m~(xmo`EcA9(850D#^CXjxiXTB*{G@o;yE-btC7M}>#iVgK<~gp4;j z0)|`yHfG>FF}uO)znu>1}1pZv{!p_bO#;l*Auw^HTsCwyhSt1HJ{& zDI#a2IsXu*X=%6NX5m~r<_|T|F9K-_*P;`O8j$Dv9rHgx%Ljwen37nCz8C=rKcp-np<0^YUxk?)6?%w zPfw#HM*v|9#8udi_s)0Z#Zizxtnzc_JeA}#epXbN&Y%H#U)-LMcGxg7LXObX(n9M$ z&9zur10qk|fX~>7Y;h=NQ^5YzhOTnci00NAZvFRhV=lnqBlpD2=-mzN&VLl8iH+Id~F>aEki>; zhyrxBBfAC2+K>{q!=a{h$Vcoc9i@t;uHSyGttR;>;{vCBQzYJ#Nv#r<(gru-H_$+C z=nzCN0u~m`ZoK=q5t?)EPZ?OjqbkpxiDo z3vFd%VW}Tx9BqNT9H}BbNz~mAO0QkvbEE%3@WWoNsS8tAjgxxN{Cb~0k!{uW;XTD< zr|!__AfgRtQ1^iJcLKnQp_c83wnuFnY5BXj2;|8Q5%i@zUk-giiyTL{o3|Z7!qx1v zL$(eC8YKB#0iwg8uSz-P__*T|P0yU2a+U(4#9{5Ti`dwnK!Z9;FtqJinI;(5LawjC z5vJr^QqCHh`_57y(V=5jCUW#Ho&UdFQ{MiDI$0dTsUGG=ec|~bw$-lo)G3bF@d|L6 zy~LP^=OS?}r>;i?gk%^n1B@|cH|glGc!^zQI=K@%L%-?>jV%cs+(afpYwIFeCHdmv-BlR z1=XDC8RFia_Vn9XEf26rtjD_dDrPurZlkbpIFX*f#wXW^c|&5&rW@b>)Ds{e>Hs4p z>oa$!QoPk0CGgQ*;N#=lt-_@3kC`HFb90k`9!U_kx|WGaHj68aUzt^33(!|yw_{?O z7x7JyMWw0GC?U#u#kw=^dBxWn?m7|z$}A0JUBvzPSzi)p3*mc2td9;WOz(o9C{8!7?xZRGqE}uH! zzj1ry1>4~!2-M_i_9wHbTr~17qGC63q2&7xm=IGZ=jVei^jA}|>Q*#;R}M6D`|tt1 z-6{O#7N7m9s?y6-GIO9jAR!IokFbqDArPgM>RjeVxO-yaVI7ewvbIQ!Ma_@Z*0x!0 zQp&1Chdq62eA`>O#OPY7$)HEw`PaU|!Eln<54RUE%+1Xway4z|=u=In&CSCyMz*Wt z?$FSD0wmL6cRA|a8@-OxYA7GDGTd-v3%YfK(QNJ;{B8j#<1zi^Jqm@7f8dy^?wQp={I#=GsUKZ6bBsc2v_F0T+ zp2=Y((5l*yaR1r$$nK-7#OWcA#Wo`z0ob$&$Wj&a*H(re~RRt0v;|4c?1D z8S*-A&bB^=tFQnlnovOi>~JNA`^qn0PJ+>*6PNn4bJ$FKit9LL93c6}FOZD0p{)lC z!E8Rti$l(p|9#^wGM*{6)*Yy}#8hR;={D=9NDf6GN-hfoWG{ls;d;>8%1R*26SgI! z3SXqp;yl>eUKav+Y20WCd84mbE?xmJ%D@YQ7J;!RGJR>!3Q~pc@QF2qw7$?ZHueWX zIwLtF19{JEj1|`YqdCsSi>MnPL~nQLG=!4le@Fe|LUKv2*H9usHPLu}B8oC$J-zbT zk|ahRJuR)*Ah1G#r#e*t*k#4WKoaFxjjQ}5F){H)OCZZGWXQdRkOL)oYKY*q74P?x zMERyUSwMB6emE|$|DFOL>*9Fq^L5*=e~V_vhQDUmc4;mSJYLCp5C$bZLjVqZd^e=} z0DrgZmnzWm4j?SN^PWRl$Dp>|5rppk3iI|u$ z0B>HBN=Zuk7E--+00K=1l|38{?Ctq(L1U8ZeV8*RDiT8`&bmKZQMa$IE=aPe0x~jJ9F9VuR%c{P40ebDET6EpHWmCBg}Z~H zNra9>sMP-@;U*S9r@i1IE^2AFtR*$&h$i5*9g@`PcAKk%5&=M`^DV}#MMy;z3k!?K zK%)YtwNpq*o8bcJI8n46d>cx1aYmmI$f#F^=1xfSJP}BY2D^fUj<5|%emB+e{b$df z(Y0oPhG88Esx5%a=eOghiG}5kA3+rZ$Z5s|QA-^#?V36|vdJvc{cAHHKYmoIb>r*H zRr3du@iwq4DQo?`C{yy4%*@<8?@BJ?zwZEfmT>o3)TKQ1sH>=@NtBfxZetWSt0N?D zE>m2IS5z>dn9e*U?QdzhfZCsBWs1(H|6ROr#V`4>vY|NagKVNy$bn~e-ZgOnWS4YF zS!GzNf3!D6b}+2}09f>Ez;ZV?`4PSkn-d%WnqGcW4<;S(1PYjMg&6x83M1`K=%hx5 za8D7B(1sNSvMIf9JBHIdD2!gQp{)%Id3rztN5~8AqvH@zqJniNrwWVZD*HQgwTY=r z;A8ZL>5r=JP*bChJH*>S7tMoW-^A3^^6b>LWJh0Dm)eW=DwdWvI^Z|A)M16(ISCCx zc}tJqS<&tC4U9_?Sb2fS$PE>fk++8jiP>8+JtwIZdp%H51tmrZxWPvXk_`tSssQ9p z+x)}`6*~iXgEhKS*78Jml4vO)HxNZfNJg`vAwUvd_I)=m*EIqBzMGrdUn`xHoh=uX zx4gwBd2?a&_v%`$^!%IDBKgO@a_`#Ae-(ic{`|AHxyM!192!D$UrM+s{>nBGI?B}M z&5P|qA-R9iH1?PRjxOa{qIonc$h&`Q0cd4YHNiro5~n5ZHUcMs(h&fQVdSzqm@fSZ zpP1M;GLjfJ-#DDghGu$j@cnrjp8&dtT(uVP9q_DWK!gl%oQRm%+jR*+ z-BGaA-oVsPK=}IEVgemp$r}JZP=YFfxThi_{%+wZp!SCH4c|diNX}!20}i?`vZl6{ zKUck)jyFceQCgBI;uF+$fx@n5{*bgbQj3JTGfWKI9?=ypMq)8AfU!q+K`jdECBoIm za*D{@+}!nzje5`&+zR=MfAy-@6VD5`cz9Iq^+W$YDhPGpVtDcLM-_9zCkswaPI7K5p^JO} zrhbq%RJa~CXZI28;1Jw8*HaYte2H2%&@}6JS6stgJlb=)57Og}wCnF#@syP|FSpK-!Z{ehn1o z4~CRC1rDmIyunEBB$_G^8d6paPMIT zKMsI9N(uw=7?c!dsD^FLfw2^2XL+_~H?A$YA~&G} zs>1#c$xYH4BG)9L))A9g-ph^~dYNXcRbGdX^D3X)^&MwNm@@Btu*fLqWdYcXITOx=n0) zpp>H&V3d1wW&ke$X_()T$wf&?xjbAOZ0bd4!^6VC;RDi2hyocI0)Yg03z0xr%DbGL z94%nkK@JIa=_c@WU1yGcQYVKyTKf8!5DmrhBh^)}MfPLe z((=ZXt;i63=>PfQW->wMMHxAvCqkLHdDqUKg@pn|`&RuysFE4c!I}u%5 z@X2|@x96pu-rr4j7q~KhK{V>?5vDnMh*RgccM_3n`Z>y8++DO=%htQ!;HtHz_SB63 z-aSaF(kkByqu_Ir)9;LZZ=-cO01i1zz#FTrtqtPL4@N&T!z%N{_f)=HUN14V=Mvd8 za*z~U8LXUp>r9!YT3!f}vRsfgDl=Ty)ze!9&{YiT(I_Y=e4Lq^nMv{Wy?FkDI`J+8 zHTBbtjg7)VlZu7Zn9#Vmoc(4^raqh;YGLHDC|^;s3eGL(m_UZ!?wer&6(JO8q~%CH(b`A zl8f6{S@NbPooSkHAW)YW4&w@_1v({1~|(w5OK;BPrN zh)CGti}(rSrQ#6C5RvCf-Lju(?( z%;=@k!J^~O>c|v)gSYT~LeM)m;$38-SJSz+3%a=`Op4XY-%CPcKV(mbPP^>5Nw;bz zug*muoB?B9RAIN&RwBuF>2t}qZxW10ucE+|d||)f;Qo1l>jNTDw4k8i>1ldX)Ipme z;sP(e;NvN=25$6DLW|XnhqPp!G*V2IXUIJAPRiV;b#b-^V^4M#`+tB*`rP6!qaY*r zxV5?aB2J>Fu-o#|H|SS^z_{_{!+R~RQdL^ytqE)bE|EG%^iICL61T>~2S*Pxi0+X| zF(rO`{h@UBh+S33J%-sD*(+i4B+`xW@sj`?nze7i@&+)FcOA7!69YDs2{L>NHTbWs z&&AS=k64=<_vfUTJRU@S1RCO=?6(n0c0z1K?)2a9QnY$Ip>(!2C%&UpzJTZ?u!wiJ z#tX&O#b`Sp%8fwezM4Hvk5WQd5TOQouhK}qu|VI|_5bg$4b__QzazfoC#RAI6}i#B)T9$DLkQ0#lw2!v|Ow-agB0>pSv#oJqnXpvgjSZw4mvvZ0@ zt&ZYLD#gnox>t$+ni46FP~3Y&QnLue=KyGtp{IQx(_h!4u&7nqVETHzk|H;YMmf;} z25+$9kaA-|O;pq!9K`Qe-L=Mld`p|(pLKf|WjR$;RsD?k&!4!{`><{qRd_T%m?*5~ zP&7ZXy0H{yBT=WDkrf-67kfdo4kL<$vnKYZSi_$;AXHgmqZA1dV%fP?+BH_B?r4Ag z93ckLXLwSQ0;I7j+`3ip_U+4z?QMq2NW&j)Qh}reSeN5d=Mv7uNJ!4x4}D!AF)onE zU!pcH(lzc$-pQ2JFZJ+9UCc;(B>Qrx*=OZv7G8$qR(Yn>E#VU5E@(?=N^9lpsH;23 zX1BbTDQ_H(j*&*kWES#^r6cwr#HcTp_I}Yy_rcf5c_rmDtFoEY9`*PU z>c=?+l8`9y?Tsj+M)B^Ql4Qc^Z5qmvc-F139|#xt=LkH&B*?)TAZ8g|{b7LQU zVt%~7{%tV7X_?EfipIl(xthYk7LteYxoQ#f<#T2VF30#3+*eZ8*AXXk{8{iYAvEUS zYg}ncOotJsqa!agkS8=m=>PR;Mhq{`dt;Xw?=DwfBOplh^+i-~is>_|e(qq>L;dWA zy7I(C7~Bef0aBKey1OwOqq03@d?pk3Q2rY6eA>VOPl?H3?#Rqcn ztofX>RnC%=^Vp}~W4Yr%V33H8al&RjtL7L~Th!1%NA@T_MC9avQP| z5+XUO5=vQ#iCEEm zl|>KjbIl!&Ha61aYu%(iwnO+PLD4na;YZ58$a8Y){6R*hQ~X0!HRJQ@7B8=3#|tBI zto#Ze(TLX{tAC~S(K+c#pwaqkbLSH4tp-Q?*$OEs=~D1UCK=~di+w0YA`2TD>4%$D zD~`wOLtWbM>(VC1u{|h!tB~s=QDUsfXc0HtAz0#a@TmK$0W)B)2fao)RBId=i)^RpNHC*F2zk3I(AWR;qqsr;(E zUp-A6ZrGoT42?1jc{OHTnz%CaGp%cflxy7>H3OlcTci(O$-m!drg-u4Why$l%gox^ zr`pqpDQ+h<7KiM+%Y(g4!P3(7<@n>Lw$}t7V=y;zhPYg}r%F_ov~j z71c!Q2A}$J=IGgXs=ydN`*7iMm9o0}b*PN@9(q4WdtRuI<|@!xeTc_v5m;e!Ac{P( z6$>Pl|A9$qgEA(8#N96q4Wo?u&0hEPJlLM}UwP}&(M-{Ge6VLc|6P8u&(u#qkluKI zz3*kINttXO%fmyCr%!Waex#m-1qYY;;F;&F)$n|2M(pKg#S)_rJun%_Uj_x6uD*WA zvpT`p+9RfeoWmBWbuk*xc*u&T>%48xGz%EvfW|ZD^J#W_940Mkt@y^ zB_FasPE0w!&MZc_sktR1u{5H$cPmqI?OGf!_Xh!VUZv+Ja&mE#5-308j=3quW6agZ z$r|GImlgi39a+wAbhnfX%w0#!UW{24OQ--s%H?FL$z=uy4cFl&>r{)rqjShVcaHw- zPaEMBu@ER(h|8$7e$yL~xPRFCFW#bEIp<#-N|YlzK))MQUokbSPA$O${KIr25Eg>h z+s}P?ygKpGV16!vpAs~q=rx?~j1D-&11P-w(G ztWLwarhWDL^|TsS{{F8ab0cXk3+4XwUVk6b|IKLdH3yKyu(>!GpKNtqJlSYvrBmz_ zf5BT2+k{}6{ZIG*FMjYZixVH8lAa!hb;(a&R5Tmq&iMG+ne>K=Ddj#1XM1?2Ega0% z$_NYBf8vXjF#h-6_s}5A<)A2tI zmFO?zl$BmBuQso7RE^{5S4I7_PJL@MAJg7gY%R56Uv@&V-HKL@ z@|M?Sa^mc75-}}7YB80^8?F4(Ha03LsX;x5J1-W~5+?me)YXmq$onKYy@@JZ7JDg+ zwHgV2zwZWl_Wu44yY~JZp6mqVDt(M;?8m8)TqJNYYadM3$EuEN3>_a7&qj{uvfJ zX(>BDzs)DueyLBt_oJYxeERq&I{D+Pgg>O|6<6))FezQ~89BSSXAq%IYBNpv-)BTA z#~tC!fD=4E{@C=;iv|sF& zlTMP6`3g^-Tw`;#)3;q!tsPj&RdZH)!Ml+W&ajYq0oMaN&_9?z=WxdpOYH^;iRPjM zr}=Zp2p?P68w&~jV5Nm6Xm0K=%PlJUMdR}0jDGp&-xQx?Fps~k>ggm6+UfXq=l|X< zQvA~`67j~`Zq0stS#vB6rgAAOZ+8h5_Q~|*3zX43qjW8n6?~K1GncUUJ&@Dq`T?nN zAI|sFldncS$xgRgO;~KJz&ZUKC|D_e^-NJdV=_xNtp~!rjtp|IH^UK)uQ6zU?+#SF zOM*_i{#dUiuxoSo?mvgz`7LX~2+*hQ@p}4el*pG5Ah0{Ei|x#J_cG~yc_$B3{K?CU z6}(#*&>IT#yHGYE{a59S0X|O6I!UL)h5N_EsnY_P`BnwRN9?b<^OA^Ni<<8JgjyGomKK607|kVmqO3O5Z+j%w#KE`8!H|JMpb5I+x@B zm9K2{alQQvdiStbx+ZXMQOakA*4Dc;`Syv4x64)9VTXo?e{Af zk6FDr!&kh06#CXDav*>-OS8hKaE$?Tnqm0ktgW?GrSVN!pZyrcwDyyQKGX&?BjGSn zvQt%!1&ZM7o$*@_%qk^kIL+9uR`NfPQKaNfYD#X>)|t|t5@q`1HQd{&I5-rZwSK^9 z_VMweTTuESAjq^U)uGJ!*_g9&PlR=-xce(L<*?}wU%0?t>)rhj?WDf5Se+C?BO;UN zj@h1(@HSHx{b>9BSf)9S>DsZHJ)Lg7$4JH78+GoO6|sL^SpR%kT}gnA6ia5Yk9+5r ze528-F&x|&97N||=YnYu|9g8lqxB&%Fch@+5Qw(Vx(N)oFQMK$^4t&?O)aD66+1|O zv9I%r-a_09|4$c2KGf>E_iJu_qr})=>#{H8$IB?0jms_4f^J9VMkwYzyf%!~_TL74 zQGbW5_6C&7eGF;AMX{Xnp*$aX@8LW!#xM!ngB`nT6$KzuIF z)dn}Nrz9hb+o~Y(0=`cn3!Buvy8QLpbJSmlV$S>yMm}Hp9g6g=|I@F#?)*%Mez=2q za%^4Y;Xyaw$+Kj**vljL$*0yi^gf@xWlFC+1SxemDpH9P18n^KZ+4$xSS%btPbo=A zp(!Stk@opBDAbVLb$(y!muR(hkaBWz^tSU-Dx;&zmIB9_fNP6`k6 zn!c8I-n$DAW_NI?er(2LI)wMue>gdt zA;xLjAc=%^Rpwyx0C{Wz7v3YzG@|T|@Eo{I8k`=ZBvOui`!De z=|NUv#6hw(HSNk2MUCz-|Bsc7#9LOQ-O+%Ms#W^MjmLzvCYbe&J~y3}H!wKuh;Ko` z;XVC__TK_^X6E>(T8;)`JqtFI$0l(R>#UcP(sz6p-I_dgsMPT4>eVC~?olTsQpbg&|J7fdbDwj90Qv)Y-bQJLpbX&VOU@NB`R@78)Bk(HfY zI-GW)4bY~1_v_LZ0>NFKy|Hh( zbrUtaY!gqbX4DTk&lVDv76L<{Jw!}o`kUt^d;*J$i zq0*008R$43>vq}c-Yj*vb1TRgS|V@mE4;oe&I>JX{SkZ`C|$z=(jzu-XTYiB+q4Ut zfk?^M`c^yK_|_ya7HGVQUUUx|FbB!%#T`tmszPxD z#O~~9G#c-a?uSgjA?TKDyRP{^1CbJ|tz#0fjBx+~_t+2lI7Zc-Fl>tT8F1u|qvK%5 z7SxSwh&tZO94+QW!K=2_Y6@PEWGmK6usc~0UFv=e19_B=%ei_jK*%3wlhBjky`mOE z`%R{L_!QWn3~>30z~pPutw)*W47}*Zdwy5+h0+HF^(Lpj>B;HnFo{A2aYO!W5oRTN zK2bFzc1@(GZMu&ZOpzoq>CQc&=sX+FT5gSE*H_1n*R})lQlM2>;#}pm*oI0lY@bui z#}yQCxRMh86%9g7*=A%^jxUW{*StxSlo7_iZB0d|m*hY&l86$Gub;kk``{aa-kSF( zpt!r;+9rW1=3^+4I2(5|&hpi(SH*O0jiUfvYax);1>XIc(SCH05xvUb5W=pNslpZT zxEX3knY8EJ#P&L3F3N-_K^1tMI?@YMZEj|-3rNvCy}g^;sVgTk>O|PgMIG8)9KKgA zEG{+yA*z$6a#-jjXo|w51u;~p$luX)GM*0-F!m8MuFs+j_(lo3#C zj*ty`=P=&8Tv=OaAX$9FtcWwq0xcLY+chX@4 z9(bayI07b6v~SUe=2~NsD1j>9Rc=J?ou3z@B1DQFVhqu z7Dta*+-o~QevoRzsvK|u?31fO zMu=_EFNw_j&;l@55hOUlqkHry$Y!p;JXeq~D^olD{M}IF2q}5&u)1r)Q&)BR)2ia` z$HVOS*oX9wbwM%d#L6OlrdSx3+vhu|0){sp1MQD_9 zso$eF1H2DkcB0LIxOMaUcSpHPGQNQ=@1`Fd`%*exHGtrKlz{?zqik^qAbEjnzjZKg z)quoIQDN1H)3D|;WDDN)Un5MWMwXnx&!Qi3c#~73-mX|N>lEk9f^*a!1{sB!vGV+D~^UR+NAI>b!a@Z^T1E9y5sC!FVQ*oNrhf%cX*7t@x4yRsn zS^Cn{)O~$@o{I9+$Mu;)8GoSD&zAnpQZC_6MMp|gob*C&C1o11Gc1J=hJ zmyHcWaDZV!9BfkyRWJp)-AL0{m4RQH85*h=xoh~_7>K(h<)JVfvb>;R+#UbpCr&IT zqu_zNap%sTzo20FHayU1NIx} z;$l-u#y1wMZVE;B-Y+4Atsa%WSOa~yHT29HJ?3PzBxHWA?ZRrFloUK#CX}ax4&w$O zdUz+|k_Yy~>#}BT18n@)As(x+;mu;f5FgAk3bY8_#ZWSplAhiKYjU3d6t7_*C@ww% z>>>->A7Xo2_5%l???tCI@S&66*EK-z-a`!V=hzs;!mAxfK^-3%tNy*dHZ=Nxu=0Z* zEsYe7&8=5h*hemjh!oZ5HHGb-Nz6OEK-n8E6JE<xZdjzIwkue~^`(9gQ-)`{aF{GPX`ocys3X1S{>YjCfo4CIANh%qrq2(s zZPZ0ThJ%sm)7cZxIgv$$*8melysu3tJ_xOgELh_pg~HR% zuQ-av&1#|8py?toRkG0Eq9xY~w*=yz_afvPL6iQDJuxij&iw)Ev{q=Ul?V@6vxfQ)*!JRsoL&frv5&M@qhA2>^5qCK(nrlwjoOS_vL>@$pfZ4V zc>Gv^^Cu1vgEm5~VKJyy*8KReqsi^?s?&{D^3_aX z0xoxPwGmB_3$oO%?MLOX5hC(}j4@UdzNzbe*mx+?MDCNf5i%`5ZcY*q^EVQdw8B(XarE zv8LT+TIHb1n65)9CzB+(0v;r*@k+nFDh|JkwX9D?iGrv^Li*h`x%_2nS2^{D;;000 zX+O+P2BFxdjo(392U&|=??{1_dmu=(3w((#8hTrHw?XI3`r495o}s+_6u$&LluN>S zRs~^t8LLC%R^er_= zFpfVXh{{58u9oBY1>v4q0|$o=V#UZ7=?nx03{6lS0BDd{h$ArY@Anw1YS_(M`{O^q zqu?tw?SR&VDPs){K$X2m)G{E}qgqp|UM86#-a`X1t7%s4B8JV(o14r+LiRclLehAz zGMc!E6%)?xE+qZL1k$TJpc-ld%me&KeP~@d;>9^5WUiAUHDMEy>BhPTC;(4rZui04 z`>3YkCM$ltNrHHKGs3I%_u?yep*Brb&A@!IA8pb7!|F(Y(IQ5@zP^q@5nbQWajP~& zNAnV=S6^7owGa8RT)cQ&-L)%fVWbL!Pfq4_-LO}{k5;R4vI#k)Tt@FX{O9?L5vQ4zzDlyN=-OdilB}K{9}~Yyqi5cUj0&053#tOk$_AtAH{11*uRy z)_cp&W}mr=${S?0f&_muCPZs+)Ro1Y5DF!FRp2-+*R#I{ zP{Mw<TU zL1`PGA}b-`@Vaai+|yy8Ye@eV%@#E0U{s!VRLBaQEsZ~_MkvJw~3_|V*1P`a1yhSM5lO!77-ZEn95sox< zn6fl&3s)zY=?8T!`v!)Ly0Vi$<})*sxEb*K`1!B2k!{t~j)o!@(eJt|Wtw@4h;wvy z={?xk&CBUZNJ!oUHLd){w^DF(68ew9EN&J(9^6qf{X?4sn~?D}+Ls4O0yjv9q#Q}2 z14Yg1_aOodw|rL=mj#He{z7}(pYA2Aj9p#j&m_nAFqDwE$*(-THmgfMb%EU%hoEf!DN!$9eBni?AC)@Jc!&2lv0xfs!PAv z8%f9kssRPuB0sHbEkkM1$ag0qpt6iue%cmB|D#=SzNy6;>* zzB5lN?2+%9uJ^nKu~y(71o$V1(MK%jn$Z?R$-uxsF8UG^lkD##LhDt!%hy#epSbfM zOy7{cwRN;r=6=dWQ=gbdv8P$eHP*GzgC458W9rF}LiJ_4a46E1q zD%#rAGjw~BwJTptwxrj574 zMP(T@6}NnP#2eRYP=7{6D#W(wTflih?T@St2S_L;tBL2Eh%DYaLN7uWll2K>Jccz-x2tADP zYFP$rgI+Fzi2&i1w;;yi>vCu~5qRav!8eUmkMvlb3C z^t60McZ;{)y;&y$4%m`2ulQj2!u*BjyBiliKl&vi!Q9!p#BOY>2Y=92mCKK^sMfBe zcYDM|n5N*u)xmR<5AwIvDs@LkyE7I6N~9Dl4Y(2_{D7itF`#UTo6}^vp7RvIamv$8 z7-a=Ah5~tDq!D8J*+CaXY&^nJT4&RL!xKbGpwp8{)W|JZBM{|D$+etkM&Fl)sp0Y_ zd+P~(jIFs=ssc8wnhgy`)`TAXbT8Y}NQSxJZ z5K(H0^pC?&ZTl3rLb&Z8Cx!d6T)k|qZZNGJMoDqHW3j;Hf?mG;5b-mqXtNh*b_;aQ z3kr3<|BMu!oLbylcc_0aWY#KdEAmuU=$IWsX8R(N=FHdmr33u8Le>c#8Pv5|+Lcog z7}*b@3X_@o6tM{kW^H7A|6#o{_l2A$NooCHR8%WDc^y&U`(uYYjjzwg-P07iZK=1s zvovqraw|>6K=_qqH!C^a>k?HmGCrU;X-80aUQIGrwnoh|0mKI56M2 zDws)lsa_&)BGCZU2r;nx{do>cI;4~;5--7MqVeP&NK>F==sdMQev)*AwlSLta?Q>= z5_*yoQADaBHiADWf;z~;)I&{2D;A+VeI^?CS8IAz?V>W+#pC6F~E!t(&AD0%AUC@h)>U`;je?IIHJ)a;!pZ@FjX z?d^4*yDLK`tX;^r1?D>zZL$`*R>RwK-um22OwtB^)0xa_IcD)Wa7|{hyI=EFTJVQtv6woAOgIL8kQ6Vl7RGf*D z0Ro0VZpD9<8k9O*oQ=?G{V9F)VQ>CYQG?54u1eV)KmZ7qk5c(n2&y+8a`v%_O89{C zt2h05^lCZNJJRvrF8L+i54$nlWhc*BlylK8tWKm0BO~JQAj?p(0kB1gv?C~Ug-;Q1 z5#J`-=QYdAtQ$co^B^tCFWXc&#h{6!R$Ty;YSQm*-LIL=T#{T{84B}!*&#bvxi*VN zrvO*oSjlLoDBpM**)ZH0O`q6rzIlU3PD_)%tt0@lJbgChuzgzC>L7`mp7}34tHRE= z>8O5<%ZQaB-rU*}QNyPAZERKnhGp}jb-fPVNvWnA;he61gxa=&x9x!f;HEIo$E4q7 z_QHq-F$oHGrBK+| zA8{#p_R(&FsgKv_X!%Tnf&`q0@<`@Hnnjw0rn8F7M^=C~o2O!Dvq{tZM|j3Sc0qr`Cc2Jx_v&r4 zY!?v~^8u2O)*YRNlp#1?p5x=krb`XAAA<@uvTTC&(k?Xu`Yuk~Lz&+Bp^5-_gKy|7TSSJEjY$ro<^AnJ6$SaguVEupDi_S! zqPOe4d3+B^Y}jgq_1aNlUe$K20Waabn-vi0e`@a<)VH=JNhIokzY@gdBKf}ehf{65MFo-5`pWfe@@*s8{*t-i|D0%KDt1o|_$onr zHwgbV4Fyh(n!7(D7?PRFpIII|xg@)q$es@_SN8L4-w*=9AMXB-F!0AbBGZCIP&*GM z`u{S4Nskc|-1+1C>vD*WVVe@&QQFzU1>d&}koM2)WhH&Je?c`?iw$>q`&ZQb-2ZY^ z(9wPG(9P-)RzhRd{Dd|<4BHZuC*NtteGq#w0W~aE2aS~+kL{Z~%JUtWP7+yxf8?KN zoOE!)*M|xV5YiO%dcz~rF*l!)o}Sq=HSxm#X*Qt;+c#e1G^>EeBw{|dkS%Rk z)v@vOzx{H#4BCP&siamuU`r29JfN%qophD}z4kvv&Pq;mCCqBA+8|$J)a5_!Pi zMr#!pb|iRi=|2*oWFc-0!z#~0P6kgN94!+mmt9qPdFX{rsu54UspW zS&z+~-JBaDXH`xK1>&ymkb)aKNS7)d`lS(Ng7JL=M4>O*{lwGvnBBv-oE{!*M5jhczr741wpmj;n?SYFQi-E&4J*-VS(ZVrnn}JO~r~Npt(y(qu zSPknM)|!lp3lp?u<+xVMp$lSxwGFR2o8d7E=xeMkIz2@aiMf88ECN7+Fs&vHU$CZLNOGjfb-ChENf^vq(Gt`0*3>l8d1p~hf$BzfT2~;sQ)-djV{zxx`T><>W!`>juLGgeo)r1SH1JlQL zB~~UvL=9iVnva7GW!Nam#6tTB`<8iHO3|93WFu5eNQTA)pkxO{ml3Td1~~0W6k$sW zn51%0azUAe76e3JkO=`dcP*61VgG@HEL<#dP<`Ne1&>kZJx0z|6=+}`$OHl#Dd9YV zms<#|voj=;w{AYDZ#7Z3s(RQLu}*pX_&G@dyX8;>^%Nx#6M!}y7E#W(HK8Z2=afzk z+knWe$GNGdvrx}&=9-rpF;BN`Jlan*-HAR~E!z?^@Wdxj;>HNcba$=-?|CDdq8Hx7 zwNpDj_+)Cn78HwY%xcq8f5<;v(E4;iFQdcK%D#rTZCG7YSQr`}%rrtFg655iQAZdd zdJZ<3TMT!#M(zelZtsc+wD>RXOc8MpB84^0le{EKtcIkL;cm8==>u-jHfrW=rmV#l z(P?>!zqm7h0~DF{^>Lia&I#aj87#A9wB$$*{o(F@Z34t9d1H(CEnWdd3LrJAt#%U)73G2g zpAdC}n_jU=Qn4z%`q=%VJrw3q5Z5eFY__UN=y8fTXLOr2($eiq>6b-%C%MT>7cPuA z(d(oMF|kDH{wKlc>z$cutq`5F5w(yQY`tQ`jw;dsp^D9)KE?hJC17aZ^+jU)T-A?= zs*F8Q-9DoG6LtYqj${nDXKts1n;(>>QE|S_XgT`6MVDZYo3^7A6jp-FdFALAJ`3!{ zOLF~O>X%o;y*xbXeZvGT-6MrvMl(2=e) zu|8X*mT68=DoXu9bKMqFh*V#5ojrS2z0 zaVYMP*=xT^R=7N2bob63Stv__C~bwe+J|zvz?NI$Uq=VNdKC#W1Romy@AX1iDYnZ~ zs*1)Ha<2UV4!j1UX-6MpJ$uH?1bH7QyyDn)~gx7uDMGIpx=vRR$_hGkmPbG_| z1Dc-a{yQP0Y6`N-Al{RMjRH9cVb_dxXLPvEr(5=w!q8lLUzSnV{prqZh0@z(yv}8F zU^WN`i)g%5^xw?n;us*psc2q=}TPf z32R9*;BN7bH_$Hxr$e0VC98Rd3!yKrh&Y3Rcd?o5l!ltD^-!Zm(>5G6ZaJ}7fZlc! zg#vzBm!hR-Y1(#F#!bQBui7YR<3Ib3_r+sEb3*iO5DRdzq_ww${2p3|B8wtXF+aGp zl5cMHPh>+se3-=TYKmpdcP3F4xVTN7`AKoFGCPc! zXtw7V8VgwHYDtqYr~Rc6RiQV&zMD=#LNaIl!<|a63gM%BKQcY7Qhw{Fhi&?G*TcU1 z<7;=H{HD(a9MsNVH~9{s1jV??AbH?#Vwfsq zLy=R7ie#1Hc)ZPz_-XrFIgEc6%@te@2eD!kTSU0%SDT?^OEH z*HPD?g3BTt|`4nCX3>1sL6Uqf21bgQt&>=s6{yYIZF%bS-zjW^`r1t`%?WzJbBB6*z zi!_wC0DbAtsL8-j!>inXRxajl(7BM(H&Cz&(6IZ7vLBuzB5bS~3hF-kmm%-%M#{ZA zpqW1k3hd+^n3=gRzlOLfO5DpDM{k$tkG`OoBr8XBo#@fCf1u7P2zA~p z&-7rx%T9!oH1x`WmBl*I7NEL8;iXng+{(WnA(9MUfg+>p%Gqxpg!=CkhK89Cpftq` zsO+Zv;_lNQ0OuzmE?izsO>JfYDs^E%EQ*W; z@E0Ioa>RU{2Jz5sa^a;{iAu?daC68%{(xwxu0J|_1tbz=bk}9Uolf*8SY2BK=<#AF#Dym>t3*OyyLc$P zk~b2po(TfkxYiB`!5AEdDL{OHxf{ef(HP?e8jnZV8opk8F~mdDL__S8Tg83#>Qc8= z9n1CWD&W3=@Xisa7q9XtC`SY#O|46juM-uG@{X_cG!q zS{0fuO5>L|uvEeq^Ge=8K$bT$jlTvpkdVL@GCCXngrdf8-zKDKSB`SPTvk%i(9lRR3mz6bmS*e$kWz8{R=m3v!@W_GlpK1FGA1n>? zQgZdB2Phd*`xRYO!|~#o3=KxvYYJpvo;iH<;+Ha=&_|}TjAdWVd%Uvf^_JIMMI$yX zGTJiQwAQhNtv`$Pl5q}KT-Uq$D!}vy*-)!@o#(w!-heNNGPte`sN|SGqH`F2%>`Yl zAJp*!(>7SmUFQt~xe91BP7hUnJk4Ae-_tLzLM}tu2^k^Cgyrz&bRIZDAC882qO6a& zMOdjqZ5`(^DwI+1nb^;u)>;tym#J+WIH`K9);_^?^$OX1E7 z-|VN-Djx%A4n2pvZ`BdUWzaOF4E7I?((uHW4uOEkD={&#T_;3yaP+;IZ*a@~`fnpn zwRio1aGC<;%|T>aa^ql^E?$UQtQAZ(0cqadLw~&BVQ@AN6kS%ipN6Iv;CWFOPQPe` zGvl%SPNwh}zGBhmLMV?D!6)D=pxOCl)8fr#`_Z?0gVe<<!25G?A9lGyx`kx+o47E4YATh?w8jUgY@_=HW z=#2q#w8u2IuQx=O3=BBUdb}|{K3>JF8bV%b;$|O_UU0Smdbbs%)V^U{k^$8Cn*S!_dbQU97q;wT zI<^Y4bM>`v8Xf-iUySOKB{ z?sH3}vF1=)XJ@C#3wTkK)0U~Rx3ZSQ1*p39JETlF-GjuF08z|kpp!!eL38H=8}xPC z_D7@vP|)TEpL~AgHN%6=x2B(Vh7Ky1w;qij|K#W4QFO_b7l&`Ccy`QFym-aI-DUJ~ zi&_Gak@T9){jR~Bq3B8lnUTz5s`Y8=*}ipj7mih#MC_nT_k~D4O!wvc0;?bGL9A=Z zx~EVCYK^`Ov+YbM+&}HMXJ2OkJp~21(A*87<#z4)w{^}J;aS{6Q+bS`J|}u>F@npq zI|qprIIHuv20I>my%9y1UOG?>qnZs^!?Gx7)t9-OV}DRk5Cz5b%XURS zM2nsfzWC(`XW3^`Mmm@EWuK_1sCMVYn&|B8Aygu*;}&#%Y;|PpnP2o!age{|-zUqV z9kOKCL0`e03`@myVLgw~>!e*tZ>OQRz;`aHpg;)b8k;kjl0WDxICBTDs#Alk9jIjH z4P&dmfItF6fo=!$p7CsczuxQeq{fX;dDvjteP@fF?vl0Tv1Thg*9RKT`M_RkI*_|J*^ z9+2F?4^4wk*VNR^ZzI;>#?=5h3KaP9^*Lv#yE06!^_orbWu~Qd1@72YHsoL}v-Jez z&E!oEMtN~`>T7^5KQJT&H|?Y~1~EnW_4%?B+R#idt&+j%)bFr(y`|Dc-Z7m#6VVu& zbZ*bl(+>*tEo##g$;jR>(HLp9tgr49VZ=qCU6JKJ-;(OetHhJ+fk`Q1#j&}G&cBo? zgFfK`Lf4R4=hnRk{Wi}-8B&VWf`z-G=3fp?cNK4pa8^P~Wd>hiFGiON`Zh-SVYO0VcJGhD|BS<21K!8JzkwAZvH-Ey6vYs-QLVKEhdm09p(Y>)p7czrmLH zvQ;9WY_IiOhuYt7EN3bzl5+OgKxBbUm~XS@=|#F+0XVMEv@9Lq&oq^PX`UyYvvat zh|bT}1sA@aA404K;`j=fD_R)u`KE}iW@=q}WV=DOY@yZRfV3)({9CiVg+oahwG*$# z@l zo>Ob()S6V%S=|e@AAH#Wl?|`M({JzUP>~(6)vvX%HzRd(k!PEZ`R3*6`4~dYgAh}k ziS|$OyZG|J*GY|_sQuOrU_foL6#P%BJcXA%80thL6sFXl9W1Yhd3T+zSogZ0`{?ey zw^uK~To#=YdNOyBv9Cifj2>#^WRf37oK@(D)OjFFjyv+AA$9X8Wie~E?hR>oms_`t zEt(tnQ~gq4#oH6xiYGqRX(Xw!1v%~c`zCr#c^Zo`S&OMwik_|` z$4g$_l$@yG3kfuCG|JhFh^$D)JR6r<_K#)evWgd59(wpSGKz}L(wDubjLkt^oe7k1 zu%c5geOuG_S8*$-RkX2rPsg_Bs56tAS`Y~EkiT|HgS8+j*z8$==!3r}LC5QF*u9EH zgLsMzq_s2IdrI9#c8zBHaUvfwsWM6*Kk}*#UjC3i z^75@kE|$KUT5^xJpU3U#>wh2R-sUI&>kIzPK4u&&To2)ONN#+-)1-VNvT5|k9Kna2 zCIS^O zOOWsXeB}Qc!lT>MEqi6h*2k_chMsksGQgzN@@E$nK;{wh>jUS1PW0Uy`y?q_T1M#9 zJKFV2kPm-eS_{W|A@WZqwe{t1{I(9_&-ZM@J%?}qHQY;VAuz$LT3QiS#tsSr|LY5P z<@t(oKbHNtw=_!H?f!d={LZhD4>M!R|LwzFJZ9{V#+|Rq?}Xi7k;j@jBfV|MXD&o; z+intkICgCJC~8(yd~0Q_t@`%YCt3|0eL{sy|Dd>+m2a}4{*{Nw3&Zqnub#-NYO5C{ z>2b+<0=V|I1kG`1Ju9RB$A8?L$Ax!~fXRn|Nf3=~1 zGq##!c`Z2TA5SE+yVbF3WnRa%C%!oNV}^E2C$Cya@3%8forxH*I!;c$ zhsgbZSlyXaD`X=*{y+CD*cr~e{J#zB$I0}68`e+L`Txy^RnR9+^Sad@_Opc^qoXY%W!F$okhRplAFQJ1 z=DQu&rzdv5wYvH(1%)!f*;^WDmojqK-{;4oDV%0H#1E#&52cMZ>4^+^ZM$%cd$!LK zSl)MU{B_2*+8lH4NcRBmQzgC39r4RajQw|y0hZmZpxo;u_+c&e^#+xS>Vn0aC)wF4 zIEzkM^w?0ith=6SZa-zwX>fYwmFM~FZcCjn>y1*%z6X#iy;9pbKsBEqum8)fLEj@D zX46tVxXK;zGG{Ex<5B53-CB*@=>~}-M6tE&QfA2Edt=XT%=M2w!`A0n(MT})EO9YH zWk4< zO0Avco3mab1<95(xolEgA;GrYMUK_)>NHW?2isiQ&j&#qPGsz;I8*ERvkMXujOdm! z>Rj#7HDwbY+*8*1O-v}Hr71G>Bs82Y%B1;{r()Ck|bsvbEw|n?~ZRscBZos zX-6l`JWf>NUN~JtDhh$Q2C|eK|N0CO{qG;1NG4C#VtALUcf$WmTjA%;9z9)XjXxt+~>5v*N<}mGi!@HV`{<+xu}p zPd)v|ab*q&zMI+a-bj^KI+@m@L~-KM?aLZD>3p+!1zV0~uO(70Q)?<^FC6Y|F;h2P zePqlrOPtDZkwb16Ndi92wx=$)m*#4GR^nA$dqsNseZiE@&edsx(ZS~7t+F)j^QMKo zgz)^_vgtxB=k~gxjQn5AA*-)CkcGZV5GPd^Uc`*tMAq$BUsS4I3|mxCU{w6pD0Oqr zRaF(@;@jP5bXoOVimH&*f=+BQ``|Nj=Q-rZH==$x_lSSRoQSF7&rVNEgCC27c@n$& zZqu2U%oX5o=0zSs$j$FNlhQ-vT;uk}6qH_nW^5 zciqNsx_vELvm+rcX~<6_X?NT~IGBF~Q{`2YR=(_Jh7+A;y7>M0NABVqmFQaq^S5tl z_Izi1D&gll*2ejGUZNfoZJBil-$xW4BozCNO$Y}dCVFP*Z*k{NwB(;RUvuGt=6Vg_ zu#CNC`W`uho*wkJ9%D_H2J6Mnn-&X0y$#p{7Kohy4Y(8foUL?L$7`;sJLt?McEzf> zFiv*1Rb+2FAb`r)}EibeW9`yi}bfb8g-tJal z(CQz^L*3x>|NGDO^{D$XP|Oyb02J;!##LGKkh*+&`qJWm4pC%f!G<cu6N#=_&rpc7N4`dTOPi%vs?b3@BT}m_FrbGa=sTW8YL6qQSNm>zZ9u*Zqq}U1QhXD%^>Q_K#y}$nhdw)Co zNp{b%7Pf4aJf1k-%H?(j;Z8zVToMn&NxqF88KVAK58RyZ?gU}Xk{$jvG&F$AueN!sJHCk&sFI14TM?Zy*7zMT}am$7Rj z8i~ldbg6#)R~QPe-%2XEiA-ZRi*%D96qI`%A%a|~q=J$&mG5t#UH%=yL`J>s`fDV{ z_xu?`0c}AaUpj;0R@!?iJ-%Ir5&7LiZU3eI{a+_H0wPIQ-=(GBcqJYaQ-OQ}yQq5&sRVtlGYuE6|JZ=3v{1r|y2 z1zv505AY9Uf7@1!ri02xT*O{tenUIJtG92JK_ztt&XX-a0g%3JdVfXX}yi0 znQ`9!3l|Pc+t}DVFw-h*NJAL1$Vtp;*%Pyz@jmbN@J{=&Ysu15Y@7L#{X|0OGEC{5 zg{0-)@9)xniB3P68Y^Bcg6`iG6twq@v$HdAD<~-FR!$TWdcB~Xe0$XFNm_a~WLol4 zf1Kmr4lx^5+y&o*ic>Ar%2-kC*`CQ!OXg+jZKR@$nzIOn+v$9++bV7EeOTNa|?2Wr<@Y z;z790u>FcbT^L(bLm;TbWflGFyx|%l79g}pwKKKqS z)6j{PsZFb5V-;B#T4he1&`f_K={)Py=LJ<>t{CFlZaX+QOl1+YEIP-U9v5#Cs=D=x zKQNiAtE*>bXS-VW5^epNy|4I!ZI4b{yTeK?LI-p_>=@Jwceu#$-dgo&kF9=SP*C|vbz=$%dYcE` zeA7kCZ(wfP9D67H$dXQdi9u}Xo7xC!s5v*;xMNi_|BB-X z;MLFJ%nz0?k$1y&`^sCB|MLr2O^?e)2@dqwQx&~ z&hqP7i-zaaF^;t$3K=JNoX}`o<6=@l^3@joD*p%*y5Z zWhH06f>to_W)b|~&?JiJxHQw_6g`W`+|rCYzB8GF3O%td*+5+3UZI7d^ZXH%H>c}> z7Z<)Fp&>I$`|*~Z=(?)&z#M1U2X{IeJ`Hr~MLexmThM0;HmRF^TLE3#&0pm#z7j>4 zQt}oOSNflkcVb0}8;ceQC59sqoxOz|pKPot7vEpXTO6(P0#@^OYIq^jpU8=km-`Ej zI3^FN04ISf)@g2Tz6ErThC@pb7qsd<#)bUHqo=N%0pj}izO7~KP!XyZ+q=2hFN*#h z2vJSv#rJ*Q1A=6Jg@jJQl#S&e+QL6djIS4G(RBv&)O=R&dhot%Zx4@sT1y zf@>|afxkFar%L(apH)tQ5>UwL+NxFlrf-*a>y)ZRWtd$VDB3BY-<`MMOir{|wH1VM zqMIEuL)3Pg=SB;JFU=Gz))u&!&E&3!+s~I%53OUJMPqwJ+25(Z8v?6^95zPf4T(_4 zi3Bc}wWXCh#w|UB(|?JA-D~5Gpqb9`96d!DQ6(5c5)zTCyZndE$np9kCog+|v>Z!x z0Bw$(x_Z}HUHr5d6yh>kpMW-SRMZ;wH-(_E(Db42K-Y`b3M?kws>}klO?F?OaYhY@ z1kl7SdIt5y!$TkI96-W7v@+!DhYT#TcUIEddZWR@=$CU7si#?oDpLy%=fuQZNGTpz zyS`Y>-GyRPt_tS#x*!#DYgVgJyT0V+`=wmrg}L(O9eKd5akbTt%s$Q1{tU zSl2!vcNZ^q-9(yrA?9vk9^o{dtL)zOLTC;{I=FG9)(^BYw_%V6L#=AZUkP!tu)KUe z%kC}iMGffuzCra6XQO~#XjNxY?cj8OX{v+UaXD~5f{~B;?hqB5-=)YHpU6N!D*Uj- z4SE^hpZZjKjDmv8X?ZF>Az}RYjJ0Lxo0OF0QaGC*&y2`2R+fYMe0xN&>gz*LOmiOS z`^-!C+wSGr23u%XmX}#wsz}E6&=fl2JwZ=aQCn)KH7T4lQ(t<_2l&3qtTqi=wBvxx zJg8Od0<`jrTt`sHFvqK50Z1)v0HdEOX6ZPYjP)gK&1<>8X~CLhwI~^xpcMRzijNpl zmlZP-XX%Mw*tX{A;=Z-X_(p83T$+z&++=nn%+TY)olK_+>w4ewC}D~i#SW6c^azT{ zM3&Q-$jSB-5P1pxV~z-Ghs!FT z&Vcml_Yj#pAz%K{H~5*^c5PoD6mhK$;rqqmh%Nwc!2%B+D}&Qi149O=4=TuA=bnLf z#1CZaf*b{NU;IX_65wC83YC`MKs`274fCx7v_w*UIXQ&ZHq9Lgeskr~ABkE;;8vtP z8TUWMqc1zi_UAf&682b^H$1MmFuN$I#Y6vCsZRvd6j|AETrgQV#6Q=E;8Zdw7T&Ck z>%z|F4EfH7ed~LP2#+t`3;kVL(?&6|ZM{--i^8nNfz44V_c#LEMCR`@kN;2s7zOff z#Y?}reimVn-5G7|>0H|f(n@^=%T^8z36@P2gL#gfb+7Q)CsFq5tk_`aJTA!&eWEVx zRIy{f^8D(iD5K!fuCu;?pfIzu`^>r!ou;|^-fo21Z=_WY1qhrLD%EGij8)=nwO>^0-n$1rnnXw9;p>zrkD zZ2y4lzR;5H3nHRIj_PBAQ=g8d@%30M6cD%85$QxFNEs%Z$Q zeb~?QL{{C#rZx>fGQv2Xc3Cx@DN$K49JF(Qc4Atco{w&Hu2N7~RJ_$2&Lo0Oa6);^ zVzP><%%=PEeZ<*fK_T0PZ?r->3k6}wUp7R{Ro2YNjD-xh{Kp8U|yVnuUyep%1?-`-pr7w4_ zP_)bXO;UPFYE65&>eMjCu46sdQi?_=9w<%C_>kYrf&c@~?#aYP1QMlA-Gc()Lrsd<|!KGa>ytIZHS(yQxMXH! ziQ`Av*2Ah@jk0g5`a#QS6%Fk5wFiXPB-{IZ)W5oBmcG+18OqHZ@w_Dm#-5RjctCH* zGv}0o!*z$0@Y@H(8T3Nh)*A$G(%YdY-R=`5t|3pvl-1-bSdJntEAQL$e!iv_eS=3o@}J3~it@QS->efIzkjA`{&z4luXwF*8YTV19i=%;!KQBujNGL8 z zd7Fowf2e&Z7^#uwRw7>Tnon6QbZi9>3rZ%|J}sQ=4j+2OT2=D)?DqUIW;2e!qP~ld z>VHWJw=Z6If_r(M-niK!df%QMk9w-Y`B$}Z4n=(FT05Lo)9yl6Lf$RD3%UtiaBQ`V zgx6<0$4f$UrX2;fd1_00^EtEuxyc9jjY;~>0RYa~gB&V=9xG21F}k|`8|6h2Bns!& zB`HsrCgtD{L*x}-)bTDpLY%v)cq}!(Q>kwu+WW(eu8GGh6|!o=HEsBi|3iKB2d@RL zzmB53F^Jj)Y3)IG*Q@82V|BeDjc*f`wtwj8Fj*_lr`cn>*FB> z1sU_PCb_F6zos#5@`+DF^fp3&PCA)0`X(BR0B6%G;+=1UKy3+&K_N7;wFm*xdzItb z_LlN<6DiwTxYf>iHFkwutD(M=YHG1B9Zh0>-;O`HuLF>R6C-N4!1wRpyMo_mWY^v) z*ZFq)!IHpDvU|=5d07-py!RV=6K&uVc0)$WZTJ%}^CF84oqw4R4_IF;7@xAVt9`ws zG`nard7PeT6FpHP(&@83&<8zYUOa_m=t7i=4ZJM@*|8y7%H+mG6=wie5v6Ms*AfZ_ zLxw6dYL2R@siA;|Ilgr5&XPZuuI;qNadZ{Gyjldc7miypE7?t9aC&5BF>Se*Jd3}Y zhYk>aC)Kbb;lw&a=r;{5uKkd)w*x3<34>k3==7Ja_UY^l>`6Nntz5{$LSFzq&!JMg z4-1y0xDZHQJ$VSRd$gpS#fctFmL8xP7i~6F{#ao*)m$G7l&Y}sa4HI|PUYiTcNPxZ zn(pi&_>c#4lo0;c$LFEra);-9OQy!!Eg(pfPVLRd$sOHnL*{Y|g|V@(g7qI>a$yu)^cLqQX46iVcl!`gSQxEmw962*5!lp$nMMZK z$*!EK=ZVxHjKOV$d0m~h?{c1U;yuFZ)c^+7*`E~uX$)+=FvK&))7`HrC1+KI*RNs| zmKbNZyZC{aqxE~5&0EkDGzPa|@Jn;wZJ>bUD8+Ti$v~6RHH}`+spVp+{k5CiytKv^ z4)o(RxVvPk|0VUz5Q)IbJZ~udx8a=%5?inmaGM3nJ$ad^61czAehZf-6M3nm4H zMRwKlJte@ui_OW&DIN!ZKmeQuIRNmY1IE9_wknWNFdPDYkdCFHWe26!IMF6neUngj zyR+_oSy`fWb~_(MU?kwQdpkHc+K|*^MnnH^1uJ3jN)^G;q|#kFYzT!iJ+J_gDb=;j zmtjv2M^lGSgb+)Xt|fU?CfdOCpqan(RY_;YEON0jrwe>#py&O@*3`H9PB`#>sAC&a ziO*uy^?SyrrlxjDO5!^^J0C*7733<@+DUy3+0o|bWN@)pgSz}};r8)ZKz9SqkYaP+ zfN?*1>WU|aNx_3yI}vs~_094<{V!O5N=E20na5f6A zPV0DInV8gyEyd}r2HJa|L$$mJ@KN|hqV4S!0putY1&WoM+^vEDhb&dZqT3QBRC1mk z(Yr?iM@Nn7TaoG`%?e`s0|W*lv^OSa3%j)0)j@}3Gk=Bc(5jpt`Dz)}%86dg z1<@*7ss&t*H#9YsAtzaeWRTHeTr?7>uzi~zYx%dMR^wTu|K6=9njbCdfPjFZ>E$)5 z#>P~4V+^GT!j+OjLP2)%xG`QS%Zu5UMr$1`GoVodC$cB9x3eX-Jx1efN6ryZWzx>O zIaYOZ`(+$_&q~mvKMi6LYhk-u9|8EElZ|eBJIBd|sg3fVJUs2Hb5;GPKa4*A*7-$JaGDs=xxov!>6sa24nG@Km9JWfuwjwJu4 z9HsAuLj(MB_Aj(67diD;VYfoi#VNWkhdQp{c^!T5)y{b+1(YKHtCG8q=+*8-Dpki0 z-v|0ex4SX&T8xX7cRFt_a_G+~4&-Kvp$ib5yrgM`KY)s*$6Fmz1q!M@2-tn_aUB>` z9nhG=0_65|La(~pfbW;R#k*mn>Sntu-hkn?4hXl&+dbZ9Tq96a|K*{aolyhHMX-3l zadH21V_l4<2bxvqxuouwfL{ym1S%0D)&@UcwEjXP5LAE!Jsi4@>H41u&Z5jM1J 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 literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_resource_1.png b/doc/images/jobmanager_resource_1.png new file mode 100644 index 0000000000000000000000000000000000000000..f60b1f7c0a2d905bee5f5a4192cb8deb2b3c6607 GIT binary patch literal 12170 zcma)i2RPO5`~R`Z3K5EsQL6U)P+lHmd4u2i zp`*_K!De0c%Rn-m9o1*fiBWL-q4ay9 zRBU-{Ew3Y7@EI3*k{#B(AdtBM#=twz2C}}uAdv3aad?F)ro_0`AVse1)~C;$p~;#*@`4AayxnPQ2_aq~El=jfoi(&_ zbnqEVMTfJUsqHiL%Pgj9Tn(>Q^&t=qs)n}m)I7$}dTUoNubS7dTlTIEw!OQSneH6l zV-(GBi=#|GP~-)+j*br6X?3K?W=-qSqjoOG#)kt1x9=Z#unTg=P*_AJlIT6ZWCH8Ia>_jhr_T05- zh_DuIDJ^_qKK9P?+T^a=*Y#8jiTOAV4vt!vjpze+nr7bTU!J25);YMi==h&1?Uh>L z;NZx%AMY+^GGz`74t95UTlS`6h679R87V0#85tQH&kn>H=S-N-C~0W&b8=YA%$IZ4 zZ6~-0jmynpanznX18JW^TYfI(F3AOx@;$K_S<@f<^pH8QokM24{Mld-DT9>#q)6gH zS6A0fl{jdv+e7HhjfqN!$+seAX0u?2M@$nb&@aRyp2`^v1%*nBI zaVg)k$F4)#PK;YDKHXI-Dk>~6S!5x@FD)&@XAEZ$Mff|WnY4^|e%New%|-k?iZWBS z?&Q!YUE97=2?dsPT^;F35no+dDK@O!m}w4XRZZo+a|e38PQ*h0!BcG(#vcx;CN3^} zkr{IGO#S(>1r4W%@W9BWTq})+rJYz9C+y_pq}ZU^T4Rf8nF~fNkMHSt))Yd)S_OUd zIbX-2NxQncDaa|#&7I?(Ch2|X z$eIrxC$dRyL%K>0|M|weg!4kz%trHTS;oe=_wNTY0)ofKDwqSaa&jUVgim{>#3$pN zot%&C(ON1Q^Ha6%-CSMO2gZ`#bVvIyQc_Y}LUsrvM_Owhww4jw+1cSy80hMbfLmqF zWv%QFjXy;A?Ypda9<|SWwVNQ9b}JHMNd(MCiudBc*U>#ht5kPDN9r7!|U0n|k4<{$5XV2L3s17>a-&dM2MYWHgqy^}#3XR}S z<20w)=5Ke!JV;wnJM-F$m$@+=k#*{|rx#{f^3?h5s-2BZt=p8r;migGbto(#fLcF9 za&mG$t=V7dHv@si2}_mq9&t!TN>+LYl2K^AUrg+^n-~LD5fBJ_cuGJ*N0(AsTKef> z61l8#z1K~LwC=7h@SS;h&K%{9?&`|jYUjn)2nL?Pjrn;Ha$=5sGIDaw!VU-#7nj`U z`v$cg6Fgwq!a~js5B610Dy*Y#TMm6fcH=C&ncYdk&S$WAPYPB{xnZR}di#p|*8X%; zz)Gf72d(k#D+kMii(50zTAv;eY>~FNx08joM9@oq;4`}bZ<$XYE?>S(%>ymW&+lw+PY`$Kh8r6j7w6>Ul$4|;CSD^W`*tYI&+oM}M{uTX zESy@0p%L(U@W|?s>93cP)tfpDwugyMNJ0J&C+Wso-^GJ<@k;X(N40_?CCo z_&Mq6JmGF7eN@)O?F;2B;;dHi#8X-wD_Go_hsAU148cbmJnQu%yF9aS>2f7+v8)nRr>w;U|`x~k)MzhU8ci|r5f_vabYenY(_ z)6~()o)!yWXPb1OK#mqz@x}?^)Fvj(dfvd5mn= zWFa(f>CO_j9eWYI1a=$dZca2$!Au9TVW`*4>$&<79Dv)h0F1Nr&LK$Rv#!ez$1?u0UWmPy_-l zT-w>*ZhHFtVz%npbaf9qIvoE|T)q35v5_7QWU0SiF_elcX48M>=j)o{=;#kSJ1sa^ zuu@@%sY3795Xinw`!pk{%y^!M+YO|U+}6@U)s*li2!tk8RoPnE3=V;$zfpzSLeKxF zUN$=VNMl2iPF4we{UaeHw|UBUE^RgEXb}Rr5{;643VwE8n6V-Gj5&}OZiTp_c#t7E zRV>JQq!vU*@TJU)^Y3OP#2|eeXC=GZ)8oT7m(&R%J_#o^2SpWX>!SDYuZcR%iBsc1 zZrFT#fpw9TPJ2=@ZS>hA2E|DLOXg9zGiz+t^pTq=?GikoT-}`&}@Yvy+o1 zOeM2RA%^Fj5WjbPY)ZC=|8_}=P^WQ3k4(UHP7MGaAf}!@dq&)>t*fh`An&$0QeW@u zy?G7MQWAPC=*!nq3;nNQuCz8BHXF+z-FS%~+M7)&AlQkUlSO?O%I>C(eXVd^o-Or; z+xzvcPgK_KJ^x~7v%0Vlw|8UNi159z^0Q}ojg9`S!Kx|O#qe-(W8&hR)}a`Q)4VQv z9c}Hvpg_0P@$PNrwlG>DC*L_rb+h^5;9TRJidaF$ALE?{pV)Jyl@%zR-ZG)JsVOOo zOd1jW{ZXa~f;J-(9$PoID}N+a+OI4x-;-D1C4PT;CxtBf^o}IvnONn|DRFlSe-)qT zQ~C4#9)Ti!a&k-h0ix0$2{OU)-4dgEw`n-e;Re##+1c>(YNvQ zQzYGm#5ue@yPOiaU=p!onN?L)LqkJIzq9q9*`cDMqEH4;yrHV56|Ujcm_!{bNatLH zJW~@&s%EsJY?kUl_XE;3>2JJUr@kov(_>35EiKtMX^qHs|1jc9m*!8D8o7yZsJ~kE zzp{y{eB03AhX|F3QhI7?3esLv2|W$X_(yXh+4f4LU+qGhpkTvfC$;YEZ30CKx3*3D zvC^B2Pc^na`uk%xK@!qK5-sNpc)Ki3XV8heJDPD3LvuZZ&9#wq#rF`l(~-TL}G$YOD_D#Zb@**bUc z-VO6+#Atf~V?@Pf$39TQ6VRHyU~Vwiec`lXP~isIw8vZSNo_-YeJ;bVUCqtSEiElW zLwBU45R;S8Po&34_&qOu1bcXRxDCA6T>oGoTcxR~iJBXl+hD(+&_ZE*W9XSsdOw@@ zS)P|)DB)RTsx<`#1uJXLk00`+q!E#kk?-EU>+I}|iMb*z-MErsZp`diaCCf}ot+K5 zl$V&9D%1vA*&1J~`g&NT^RsF5$B!SY3hJ4dnS)6gdMd<4L~N&O_CWwtS65Hgex-q3 z6|~ltmzP&nRn^eY(AJLmIi+1E?xPasN<%{<<++n};+CFz`c`MMZU5~SYMYV5 zu?ib%SZQi%DgYBBBO`-@@AK9@tXGEe1dI6{r@w)kF6DnZIWnT#bS;s_#D1Qr;CW1< zfTe<>V#HOxS7iJyOX>^^48@WnA|jlewg5m|SXdx^cDwVma;ytGVKAHd&RBppE%n_1 z%A1UsTmSUVeyV00=DvxTuY{VVfRdibYbpy+4V=R2TWR69-d-MVZq+8_wR*Sx4-XBK zf;fpFQe?>9Q{!!4Banq)i-$8Fgb=G>kS@o6rP6jbNIK2NDmJ7Xq|+A{)Y)@n)yPEVqY6fvmi+4xc;QqAa@{6AUWTPQu>v3>o##9mwqK)Hdl-`NaZ*&*bs(v zkjl+Z$r3f;YAr2{`4E}zE0e0qL7E@~GqS{(>w{daDDm@hgtcc^x0aA^jHGmn-3PK) zzdl>>(vB__)yWA{HX9=w*2R5scokNv>|O-hj(Ix|foN-OwrRP!6_JzQii_doXAZd zl#gfGbdOj2vxUd2cTdVJ)8b-7Od5;vi6v$iEP5;AV?$oc%4ul@balZ~Qwap^7i%}Y zdQvfpy1LKr-=8OyPNo+>U_MpcT}UAdQI0LV2)XlNr%kIc`mlppGwtxQEYxU%(@^L~ z$9=2E=_>d$!L-8mCXQP#`ubj$n8c$_=+z!PC}^PL;AjpewIr9t#r~LmGm=}7HAlYV z2}EX)0QXh$IL{VKma6DYUx^C;vv@y0)^G-YC=_aHm3w%yPYOkKCy8b%tY5}|Q|ldE zWT;5+S`bS2Aqn-#0m(Hs_J-vJse!MNbPJELUA~qvH#ZM;r48JAcOl9Ll`1)Vo$jHl zYXu(m$IRW{xX`zqbl2YU}xr=!%Msy1}WG*k(hv=<^PHQ4J_=)0VfU z4#*2B;==o#u@4$BOZ`J~!3|z0A;+=O3=@CfH#YCW>b+LusLwo2T=qa36X;D&G%%pK z!XUk|HKW)GCxmQ#ZLS6Dt@m z7s!j180pmfW{gC27;s9DADIU9t1cMrl#TdrMFGDZ)kAxsN9%gUR4;`CF;;r26~Z^z z9DDm{dp6)A={eK;@?{%t;-8Y1hJ5rIOGdK4E;$;oL_&Xm|0t!srT$DRE`tZjB4566 zU_%78Zsz3Y=Yxc7X>C28uT!v6$)c*J#vo`NlaZ0p(9lp@EAIb-nGFAXbF*QE_021U z6y)R}bAkN%T6Si6FvrH|Imiii|hKauSd(;nyre8 z3Leg7*^Q}MVYjtWkmg`lEt;D!~ywU%>kP+cx zwC9;Qkh1FqzIvZvuh3F*6$KQ}a#rv=oIl-O8MNbb0A zKoddO#xAd(zodOnhF~z2<8JoqC$Km!01=LJICKjWr2S99;Q-FOTEh&Hk*4g;3=RzR z+3QyXth%zStnAB|sN?04BEv;+@Q)w!TJ@#-VNTc@^>6C!9Ui*7xh+U+ z+UPnpJ}F(?vjU)q34Sf8hd?}fZ~Lc7m~W>MEBniPY)v<>LUuIQ zu06A{DUh{;Y^7>!OVs>C-E0?eTT7^}K2~J#Wf?3kDw+bPd359<_5I2u4;Dn~5&J^S z`Bjfh%n-Em-ZJnWZU@o!mGlM|AYIjKU^Bs_Pz zg^}+Vq*HD5junVNVkwA6-BdCJ>i`gCPSXZJy64UufW{hBs!cV78M5)M0>Q^+AQ_eD}c0nLln0z?TE>@Xl)0pSmD z!(--55C^Wy1KIcA-vZK&;aA%knrlJ&RgM{ni2%KK-+GXsuBj<|>dpHarG_O_q+Qn| zAR_XJg z$P9QyRBPiEp*HB5UnS66OgF|Pj zo(vEx$iIB{o0KLiUi_#3aNGq~@Bhg!|6btN#s9kI@8A14T=)&R{td1D^28wU1Tr`` z&dKmOg8TK^pSTR{<=2MPAKoDQmn(iPls|($-~XT9{f|XxdNOfdT#z|`C`Wp_f84v~ z%lSQMd(;3xJpcNC+VXGW4F8wQ1SeTZ|FP8H0Yy`s_8Wu#V+ZGt@o!H{Q>+4762Iwv z1NR>cT`>7Se@lZn{O9%r|2)b+o`{8<;5>qZRzdXsvYR#btKB7tjO2fw+qqC2{p(b~QImu4@<3kv^F2!Hk5xa&Go45C)T8Ta|L2%? ziCK<$pY%Q{-Vm7$s7za_?Ybx>E$svZyldC;R-I8IgwRlf82dxhnsmSVI~M*|JO7&p z{I-?y6v&@8dL?-UBoBw+6(tW~!4ixKm#!s{JsY;nR7J4m;4?BShWoT}S>4csXYA&-xS=nVw@A(BDz$9 zWnAG`jKOErD>l~1co%f0m_7amt>W-c1unmWd%WLOLeTfbWf9Rs{hg=Ws{d!tx;Owo zXKQ7>D`x2@S|zR)=9X*%RPfZ;loofZ!m)zQ=MGafKs&gHf4ti(?Y+OE1LvplGtj1w z@?KU^Rt6o8h1qrIpK}BiBll|E>*-T83dG$vx)KF)K(h&e-FnpC>2Z8owVQ1F!TN;J zN!2Kj*_@qKydr;8#K*;*piu5kOG6zQS~4;+fUY<5rtP8THp?5Y1$FfF0EO-rD{HW6 zLV0<)+KKPSR!v$9*{2GHU+N1BZHqT2N!G>pmJnu`ntdPPb73!v?1`Ouw`5V{IE{yp z2XA+s``u^Q|iti<(h57=Zn3k8{2{L8p;9zEEs&!ul9n1Pd z;?1A%7AS)a$Eps8o~Ym4(opjX^z~qHJRoB?XT-7sTGQ zJb^b9cXV{@1gXPqZ{NRksG?qE?^)xvPD4kD*;^i5L3ysPRNyqySGk|1CM8V(+*Wn) zU(~rE(+k8`9p_glgG^OZMaBT*(8^KeBX*wOiG7K4G5^a@P$F64WgA-)`m(xd^QIOR z>NAmpwpb3mBl}6&lR+0*rIW$Ey`1HJ14EqN3(dUd=H>v^(Mo#lCGeS@9?eFSmhu-H zAp+ZNN=R2y$oyIWfdY_UTuh9g7$C3@7fI<^PUAdwM;=N_*1u`TZzxk@sqtFR2L$f0 ztdV*?l-s0wZE>-Z#g+h`apLe$F*sa7K_Q;UXh95GEVsK67Y1OUrA!T`lkP*8Aqa1eDc;lKdka0To2hxmkq)?=mS1-eC4cs$BV zN{_F8I?KV7m^AkAb^$1x^B~3PWbav!X|Yl5$l2hjHD`tCEqM$1S~s_Wv*+sosDl3|G_i?gF4_bt{WX1(gqx`7rFUko5E*ttjuzCc{%L5U}<@|%R*P;xc+20 zC#@k3g8>qFHG`l7BAK=z#GWF^v}!({$Hah;tJ<7Hr2sHEg)WgpCu8!jSy@$cfCU2X z${^;lG$HJ;iELz`q|8QG+h~`_0T8IoP>`N319AZC-I|~kqDzIwZIUiqeF^<$RgA6g z=$)6Q87njFVrWfc{Z2A}HZv#qKrV%u$D{J~L^-+ybNznU6v-@UsoE1tYdPdy5@6(K9vR)(*r2DQGg4Ov_#Q+PXc@oC$e00Lsg)AmPka{4 zjEtr~-drZldPgJ3&c_!OCC#`qz8c`gD(`jge^qU5pmB$W0v25f0L7yL4=`(eH)Ak& zDMJ>s`KEX_Z+o__#HdzCR8(J2uTrnX7$~#vzR%|U7YTK0c-R$$*5ph=XejJ0B?r{V zXxK1cVqZ)dbPTi7fGft6{ajzKcUjgH78V9PflccZ2?u{OPiR|`+W(RoL|)@}WXJ`jAhSjfl5$GyC~ zMvh>bzWNAEU;ZD3`hy{m-@fq0(s^6^XH<~qU?n}>nnmuUxlno?lb#H zqfjfA`A3gganH*tQ&H=fdUT)cRf$8xn(!P1&VQ}F*kQ-?r5Bn4m6~nazXj%A5Y4vu z^E%3D4`mE5;{Y!$KQCkcUDdp6x8!Lo}_AKTlK~&IK- z(N)ep{HAURtQQ8HFv3T1c5D1#MrS8YO2e`4GaD9D!P)-@f zZTm<|U>9M%$Os@A1BE>`)!2-B5Fd;W(A47Q(yC;bo5e%I9wW+2a6!brE+Jg(N*o+* zxs#h#iGdpEu7JfxU(0YsM@N71erQ5pTW8Yf7iL6sCw#QU*%hCWTtQP`e+*oIn~&Lk zjXd2gFE0-vP#4c>^eXb?+cKH#RRS#?o#D~gJGTj#pMeXg5_|dUKY4bW@cOq$GM=w= zE6)5(G*$Cf&d%Ukyz4KVa`mUxnOns!if#G0P()E-;lfeR@k&9-6&L%@5Y1MQOMy@) z_H5^zK;LoWlELGW#aDS`F7d$cC}q(dkY_LfjYG}`fvLj$$izb4I z>36D8i$EMi13@Q<L3AU0~{IWA~AaIy&6c1=YvcoR~ZLZNzW`H_uer{oIZeg;)c>>(=Q*W1-58KenNVlQiE*c1&g-%H=p;lY@cOpy zwKRninNZO`6cGb&bP9CY#+s15{@()$+SIN~11-QX>FWT86qo}5#TxDaJufX$%!*a5 zU+cX4rCS|XcfP}k6Cs(|_Y=#j3tVqlM`tJdo^){WB*j08$= zUt}M5O0A32Qu*^)g&g%SdH^@3NIY}8 zdlyT(Cc7`1C$rUlU~XN{)AKlab8&QH%zbmj7XU%m`siuUyc(3q0pnpinB>jXa;7@u zN~Bgl>?5qR6Zrg@ZJ*`cmv=$6&vlJ`Huy=l2@O0<1={=T=*ht42imUbcQ+FY*r)z@>P-zl&XI1 z9wL-OuLRoQBnoOI7|1Fz1KQH!T;BUJ(XqhD-#uHc95syRZtr9=v^d~=z6!m&0G2PP zR7>G^1+B3A9rsD2=|?LoNiPxHJj49F;y#y~o^;0(MOnuAsVeKJH_1O$(*2+{O<2h& zCN}oi1Ld+bYC7}%wX4Bpgtu6yyC5GQ0Wl#<;1x>B^~o>J8hszrzM``{D8YoG>>GOu zqh<3T)0nl$y&KPfJP6wD0AdD`y_C6OL|pmU+U&cEJH3B(ctSH?!ZO;3QYIi zQ;-L(LiTDn`tr-_YERiG*o;rr(4goaI>Hq$Uce){Cc(lk_Ll4;7>7AyIs*UzDDI#t zOd147T$gg$BGa?;kUu(lJ{v%Nk%OL(^G?_3Xo8{C=d*7wO-LQhUUL!5o)6j-0Sf_G zFf8nM`rXt1u8E01crM_Xd0&Fgr-VuXvAZtilu#hed1q~?L+h=3oSu%3Al%*FW_AQ* z$^o7`5RG*|0-&iSF9@#pXDUu=fmSS-gS0;eAlaHDEb`m8Z(!1pA9U(%;3X-d-Ue^^Q5aCZ3pPJOW4fphLi;5U&4RsohkdYBek_0$_#PldPPtjUEQzN`|Nf_ zVrYJRTx>(biHg+`ZnWtP$P-}D(H>EAEV1gT>qZs-1X>B&5Vpt$$zxL|4|$JsjA!-4 zdPibcv@$s{@tN&T@5|`$a1!@OC4A5QmDswB-}7Jv!XuAf+yT6Gu_vVf0cOGW*DH~T zYHwC?R&hZt9pgRt`Pf}z!iT5k=FegJy=8Oj@pt0P0|Ej<-@er?hUOI%6m+p~W#q}J zhS3STfsQihQPB&#P0ltl@EFy^*pLzv*E!C7pYFY&wwt`LwpQ5s^A#0dk#U6=7>W__ zwE*)ZMt6HVOw@XMIyc73a$ZT%3fZ>zbReppWrFq;VGAhMQobhuHF|*Bjdh9z^2n1f zN5G8$iklYm@b=Eh&ITj1apu*#=7Ev@nF=5QRe{-s^z<7Z8e8X(-Az%k?GmjJh|Br; zd9H*;8ALigJv~TOpc4-!3m8M?s?LY4k|b^1~5K$N8=L4|4(31kIh>wp4Oa=5} z01DqRRmSK0U+2mADQGWW-k#fj4^FY*pyr#m8dDVh_wV0J%gP#e(ZydvJz0ZE>3Vv4 zQU$%^>PV!|(7WBz4y~IZi#-o8<;OWcqkkGSB3Yev`d<@KGchwo&`E!_U$03KcW?06 z{*FK(;Bfb$C5^zyOvP|8(*X4DE(Ah~<<3)(+yf(lq7EVnN$$@ah_;z)1d|8V$kw^J zIZx-s?5wOuj~;aawPS{qsQM+K`uX_=phHn|(a&7pZKJLl4EY3-g~)4~Vey}yov_(( zfIbZ=DXDBbK*Y_m&0v%eOdr`j@f_paQrB%YC@sBnzC0oDSIHk%qfGwRG5z-1pC zAI4mw6;4P>f{&Vl6b3~5ADbaSAQ6Ore5%@1>j9`B{C#7CpWH^ap`qWn6X-2XZPy;d z@zQH@UzdSNY=d!w58lSlj%sN~~wo+`;S)eHO^gfok>i>gJlkAyTE&rVTbme+k_@|me=|Kpp!)93T9y%i?+ z?!BJit$cATm^{H0cwN-#>0s+a4|JQsM2#JXF|~TDbek5)Y5)~DtUVbjtgG_@X)eisoO3g&`EYaU?3ptc zJnz*wm{HywD^qM*#a2)0S!9;-H$v9{W_o^`ZfU!PhGk8fl=%*BOJ&Jrn8H|%j_SHx%#ex;d;pZd#duqvX5W=KRPaw Ai2wiq literal 0 HcmV?d00001 diff --git a/doc/images/jobmanager_resource_2.png b/doc/images/jobmanager_resource_2.png new file mode 100644 index 0000000000000000000000000000000000000000..93de34a06cecd1a17a6fac93db7d424c0c878517 GIT binary patch literal 36341 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 literal 0 HcmV?d00001 diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..1cf7c46 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,21 @@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +JOBMANAGER documentation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Welcome to JOBMANAGER's module documentation! +============================================= + +**Contents:** + +.. toctree:: + :maxdepth: 2 + + intro + job + jobmanager_gui + resource + advanced + +* :ref:`search` + diff --git a/doc/intro.rst b/doc/intro.rst new file mode 100644 index 0000000..4b42133 --- /dev/null +++ b/doc/intro.rst @@ -0,0 +1,50 @@ +Introduction: What is the JOBMANAGER ? +====================================== + +The JOBMANAGER module allows creating, launching and following +calculation jobs on different types of computers. + +.. figure:: images/jobmanager_overview.png + :scale: 75 % + :align: center + + **Overview of the JOBMANAGER module** + + +Main functionalities +++++++++++++++++++++ + +The JOBMANAGER module permits to define three types of jobs: + +- User scripts. +- Python scripts launched in a SALOME session. +- YACS schemas. + +The module handles different types of computational resources: + +- Interactive computers (rsh, ssh). +- Clusters managed by batch systems like PBS, LSF or SGE. + +User's job list could be saved and loaded. Finally, the module provides +an editor for managing user's SALOME resources. + +General description of the GUI +++++++++++++++++++++++++++++++ + +JOBMANAGER's GUI is divided in four parts: + +- Part 1 shows the user job list. It also provides many buttons + to manage a job (create, delete, start, ...). +- Part 2 shows the parameters of the job selected in the list of part 1. + It's divided in two tabs. The first is for the general information, the second + is dedicated to the files. +- Part 3 provides a text widget dedicated of SALOME messages. It provides + the buttons for loading or saving the job list. It also provides an auto refresh button. +- Part 4 is divided in two tabs. The first tab provides a summary of user's jobs status. + The second tab provides the SALOME resource editor. + +.. figure:: images/jobmanager_overview_part.png + :scale: 75 % + :align: center + + **The JOBMANAGER GUI is divided in four parts** diff --git a/doc/job.rst b/doc/job.rst new file mode 100644 index 0000000..ecb98a8 --- /dev/null +++ b/doc/job.rst @@ -0,0 +1,99 @@ +Main JOBMANAGER concept: Job +============================ + +This chapter explains the main JOBMANAGER concept: a job. + +What is a job? +++++++++++++++ + +A job is a work that a user wants to perform on a computation resource (single computer or a cluster). +The JOBMANAGER provides different types of job depending of what a user wants to do. + +There are three types of described in the table below. + +======================== ============================================================================== +**Type of job** **Description** +======================== ============================================================================== +**Command script** It's a shell script containing the user's commands. This kind of job is not + related to SALOME. It could be used to launch any codes. +**SALOME Python script** It's a Python script that will be launched into a SALOME session dedicated to + this script. +**YACS schema** It's a YACS schema that will be launched into a SALOME session dedicated to this + schema. +======================== ============================================================================== + +Job content description ++++++++++++++++++++++++ + +All types of job share some attributes. There could be specific attributes for some types of jobs. These exceptions +will be indicated in the future in this documentation. A job has two kinds of attributes: +attributes that describes the job himself, and attributes that describes the computation requirements. + +The first table below describes the attributes of a job. + +======================== ================ ============================================================================== +**Attribute** **Mandatory** **Description** +======================== ================ ============================================================================== +**Name** Yes This is the name of the job. It's unique into a SALOME session. +**Type** Yes This is the type of the job. Currently, there are three types: *command*, + *python_salome* and *yacs_file*. +**Job file** Yes This is the name, with the location, of the file containing the job's data. + Depending of the type it could a *shell* script, a *Python script* or + a *YACS schema*, e.g. **/home/user/work.sh**. +**Env file** No An environment file could be attached to the job. It will be executed before + the job. +**Input files** No A list of files or directories in the user computer that have to copied into + the job's *work directory*. +**Output files** No A list of files or directories that have to be copied from the job's resource + to the user computer into the *result directory*. +**Work directory** Yes It's the directory on the job's resource where the job will be executed. +**Result directory** Yes It's the directory in the user computer where the job's results have to be + copied at the end of the job. +======================== ================ ============================================================================== + +The second table below describes the attributes of computation requirements. + +======================== ============================================================================== +**Attribute** **Description** +======================== ============================================================================== +**Maximum duration** It's the maximum expected duration of the job. When a batch manager is used, this + time is interpreted as a **walltime** and not as a **cputime**. If maximum + duration is set to 0, the time will be set to the default value of the + batch queue selected. +**Number of cpu** It's the number of cpus/cores requested. +**Memory** It's the amount of memory per node expected. +**Queue** It's optional. It permits to choose a specific batch queue on the targeted cluster. + If it is not defined, most of the batch systems will affect your job to the queue + that fits with the other attributes requirements. +======================== ============================================================================== + +Job's states +++++++++++++ + +A job could have many states in the JOBMANAGER. The table below describes the normal states. + +======================== ============================================================================== +**State** **Description** +======================== ============================================================================== +**Created** The job is correctly created and could be launched. +**In_Process** It's a transient state between *Created* and *Queued*. +**Queued** The job is queued into the resource's batch manager. +**Paused** The job is paused. Currently the JOBMANAGER GUI does not allow to paused a + job. +**Running** The job is running on the resource. +**Finished** The job has run and it's finished. +======================== ============================================================================== + +The table below describes the error states. + +======================== ============================================================================== +**State** **Description** +======================== ============================================================================== +**Not Created** This state means that the job cannot be created with it's current description. + It's often a problem with the selected resource. +**Failed** This state means that the execution of the job in the resource failed. +**Error** This state is used when a job is loaded and that it cannot be followed. It + mainly happens when a job was launched into a *ssh* resource. If the list is + saved, an error will happen when the list is loaded (*ssh* resource cannot + be followed). +======================== ============================================================================== diff --git a/doc/jobmanager_gui.rst b/doc/jobmanager_gui.rst new file mode 100644 index 0000000..986207e --- /dev/null +++ b/doc/jobmanager_gui.rst @@ -0,0 +1,146 @@ +Using the JOBMANAGER GUI +======================== + +Job management with the GUI +--------------------------- + +This section describes the parts 1 and 2 (described in the introduction section) of the JOBMANAGER GUI +dedicated to the management of jobs. + +JOBMANAGER provides some buttons to manage the user job list (see figure :ref:`figure_jobmanager_main_buttons`). + +.. _figure_jobmanager_main_buttons: + +.. figure:: images/jobmanager_main_buttons.png + :align: center + + **Main buttons for job management and job list** + +The description of each button (framed in blue in the figure) is given in the table below. + +======================== ============================ ================================================================ =================== +**Button** **Condition of activation** **Description** **Multi Selection** +======================== ============================ ================================================================ =================== +**Create** Always activated Launch the job wizard to create a job. Not matter +**Start** Job selected and job state Start a job. No + equals to *Created* +**Get Results** Job selected and job state Get job results in the result directory. Yes + equals to *Finish* or + *Failed* +**Stop** Job selected and job state Stop the job. If the job is registered into a remote batch Yes + equals to *Queued* or manager, it is removed from it. + *Running* or *Paused* +**Delete** Job selected Delete a job. If the job is registered into a remote batch Yes + manager, it is removed from it. +**Restart** Job selected and job state Restart a job. No + equals to *Finish* or + *Failed* +**Edit/Clone** Job selected Edit a job in *created* or *Error* or *Failed* or *Not Created* No + state. Clone a job in other state. +**Refresh jobs** Always activated Update jobs states. Not matter +======================== ============================ ================================================================ =================== + +**Tip:** You could use the **Auto Refresh** button in GUI part 3 to enable an automatic refresh. + +When a job is selected, the part 2 is filled with all the information that the JOBMANAGER has on the job. The figure +:ref:`figure_jobmanager_job_focus` shows this part of the GUI. It contains two tabs. The first tab provides the main +information and the run information. The second tab shows the input and output file list of the job. + +.. _figure_jobmanager_job_focus: + +.. figure:: images/jobmanager_job_focus.png + :align: center + + **Job widget information** + +Job creation workflow +--------------------- + +This section describes the workflow when a job is created. The jobmanager uses a wizard to create a job. + +The first page (see :ref:`figure_jobmanager_job_workflow_1`) of the wizard permits to define the **job name** +and the **job type**. For each job type, the page provides an explanation of what job type refers. + +.. _figure_jobmanager_job_workflow_1: + +.. figure:: images/jobmanager_job_workflow_1.png + :align: center + + **Create wizard page 1** + +The second page (see :ref:`figure_jobmanager_job_workflow_2`) permits to add two files, the main job file +(in this example a command file). You could also add an environment file that is not mandatory. + +.. _figure_jobmanager_job_workflow_2: + +.. figure:: images/jobmanager_job_workflow_2.png + :align: center + + **Create wizard page 2** + +The third page (see :ref:`figure_jobmanager_job_workflow_3`) permits to define the batch parameters related +to the job. It's mandatory to define the *Remote work directory* that is the directory where the job will be executed. +Input files defined in page 4 will be copied in this directory. You also have to define the maximum duration, +the amount of memory needed and the number of processors/cores of the job. + +.. _figure_jobmanager_job_workflow_3: + +.. figure:: images/jobmanager_job_workflow_3.png + :align: center + + **Create wizard page 3** + +The fourth page (see :ref:`figure_jobmanager_job_workflow_4`) permits to add the input and output files. +Input files are files located into the user +computer that have to be transferred into the execution resource. In this page, you could also define the result +directory where job's results and logs will be copied. + +.. _figure_jobmanager_job_workflow_4: + +.. figure:: images/jobmanager_job_workflow_4.png + :align: center + + **Create wizard page 4** + +The fifth page (see :ref:`figure_jobmanager_job_workflow_5`) permits to choose the resource where the job +will be executed. You can also define the batch queue that you want to use. + +.. _figure_jobmanager_job_workflow_5: + +.. figure:: images/jobmanager_job_workflow_5.png + :align: center + + **Create wizard page 5** + +The last page (see :ref:`figure_jobmanager_job_workflow_6`) finalizes the job creation. You could choose +if you want or not start the job at the end of the wizard. + +.. _figure_jobmanager_job_workflow_6: + +.. figure:: images/jobmanager_job_workflow_6.png + :align: center + + **Create wizard page 6** + +Loading and saving job list +--------------------------- + +The JOBMANAGER permits to save and load the job list. +For some jobs, this feature permits to follow the execution of a job +into a different SALOME session by loading the list. + +The figure :ref:`figure_jobmanager_load_save_buttons` shows where are located +the load and save buttons in the JOBMANAGER GUI. + +.. _figure_jobmanager_load_save_buttons: + +.. figure:: images/jobmanager_load_save_buttons.png + :align: center + + **Location of load and save job list buttons** + +All jobs cannot be followed between two SALOME sessions. Indeed, It's the *batch* type +of the resource that allows to know if you can or not follow a job. Currently, resources +that use **ssh** for batch configuration cannot be followed. In this case, when the JOBMANAGER +load the job, it will set this kind of job in the **Error** state. + diff --git a/doc/resource.rst b/doc/resource.rst new file mode 100644 index 0000000..d38f0b7 --- /dev/null +++ b/doc/resource.rst @@ -0,0 +1,167 @@ +Managing SALOME resources with the JOBMANAGER +============================================= + +The JOBMANAGER provides a GUI to manage SALOME resources. +Later in the chapter, we use resource for SALOME resource. + +Definition of a SALOME resource ++++++++++++++++++++++++++++++++ + +A resource is the SALOME abstraction for computer. +A resource contains three different kinds of information: + +- A name. +- A physical description of the computer. +- A description of a SALOME installation in the computer. + +A resource's name could be different from the computer name since +different SALOME installation could coexist in the computer. + +Physical description of the computer +------------------------------------ + +A resource contains a physical description of the computer. +These informations are used by the resource manager (service provided +by the KERNEL) to choose and use a resource when a container (in YACS) +or a job (in JOBMANAGER) has to be launched. + +The description of each attribute is given in the table below. + +**Warning:** The *mandatory* part is for using the resource with the JOBMANAGER. + +========================== ================ ============================================================= +**Attribute** **Mandatory** **Description** +========================== ================ ============================================================= +**hostname** Yes It's the network name of the computer. If the computer is a + cluster, you have to give the frontal node name. +**protocol** Yes Network protocol to use for creating connections + (ssh or rsh). +**username** Yes User name to use for creating connections. +**batch** Yes Type of batch system installed in the resource. Use *ssh* if + the resource is a single computer. +**iprotocol** Yes Internal protocol to use on a cluster (ssh, rsh or srun). +**mpiImpl** No MPI implementation to use. + +**OS** No It's the operating system name, e.g.: Linux, Windows. +**nb_node** No It's the amount of node of the computer. +**nb_proc_per_node** No It's the amount or processor or core in each node. +**mem_mb** No It's the amount of memory in megabytes per node. +**cpu_clock** No It's the frequency in gigahertz of the computer's processors. +========================== ================ ============================================================= + +SALOME installation description +------------------------------- + +A resource could contain a SALOME installation description. +The description of each attribute is given in the table below. + +**Warning:** Attribute **applipath** is *mandatory* with JOBMANAGER SALOME related type of job. + +========================== ============================================================= +**Attribute** **Description** +========================== ============================================================= +**applipath** It's the directory of the SALOME application to use into the + resource. +**componentList** It's the SALOME component list available in the SALOME + application. +========================== ============================================================= + +Where is the resource file? +--------------------------- + +Resources are located into a XML resource file. SALOME tries to find this file +in three different locations: + +1. If **USER_CATALOG_RESOURCES_FILE** env file is defined, SALOME uses this file. +2. If not, in the SALOME application directory: $APPLIPATH/CatalogResources.xml. +3. If not, in the directory of the installation of SALOME KERNEL: + $KERNEL_ROOT_DIR/share/salome/resources/kernel/CatalogResources.xml. + +By default, the resource manager creates a resource with the name and the hostname of the user computer. + +JOBMANAGER resource management GUI +++++++++++++++++++++++++++++++++++ + +The JOBMANAGER provides a panel to manage user's resources. This panel is shown in the +figure :ref:`figure_jobmanager_resource_1`. The panel provides some buttons and a list +that shows the available resources. You have to select one resource to enable some buttons. + +.. _figure_jobmanager_resource_1: + +.. figure:: images/jobmanager_resource_1.png + :align: center + + **JOBMANAGER resource management panel** + +The description of each button is given in the table below. + +========================== ============================================================= +**Button** **Description** +========================== ============================================================= +**Refresh Resource List** Resource file is read to refresh the list. +**Show** Show the selected resource. +**Edit** Edit the selected resource. The resource is saved is **Ok** + is clicked. If the resource name is changed, a new resource + is added. +**Add** Add a new resource. +**Remove** Remove the selected resource. +========================== ============================================================= + +The figure :ref:`figure_jobmanager_resource_2` shows the panel of a resource. This panel +shows all the information of a resource. + +.. _figure_jobmanager_resource_2: + +.. figure:: images/jobmanager_resource_2.png + :align: center + + **JOBMANAGER resource panel** + +Two usage scenarios of SALOME's resource with the JOBMANAGER +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +This section describes to common scenarios for understanding how to describe +a resource for the JOBMANAGER. + +Using an interactive resource +----------------------------- + +In this scenario, you need to launch a job into your computer or an interactive computer +available in your network. + +To launch a **command** job you need to fill the following attributes: + +- **hostname** +- **protocol** = *ssh* +- **username** +- **batch** = *ssh* + +**Warning:** You have to configure ssh for allowing ssh commands without asking +interactive password (RSA or DSA keys). + +To launch a **SALOME** type of job, you also need to fill the following attributes: + +- **applipath** + +Using a cluster managed by a batch system +----------------------------------------- + +In this scenario, you need to launch a job into a cluster managed by a batch system. + +To launch a **command** job you need to fill the following attributes: + +- **hostname** +- **protocol** +- **username** +- **batch** +- **iprotocol** +- **nb_proc_per_node** + +**Warning:** You have to configure ssh for allowing ssh commands without asking +interactive password (RSA or DSA keys) between your computer and the cluster and between +the cluster's nodes. + +To launch a **SALOME** command job you also need to fill the following attributes: + +- **applipath** + diff --git a/idl/JOBMANAGER_IDL.idl b/idl/JOBMANAGER_IDL.idl new file mode 100644 index 0000000..2b72d61 --- /dev/null +++ b/idl/JOBMANAGER_IDL.idl @@ -0,0 +1,30 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _JOBMANAGER_IDL_ +#define _JOBMANAGER_IDL_ + +#include "SALOME_ContainerManager.idl" + +module JOBMANAGER +{ + interface LauncherObserver : Engines::SalomeLauncherObserver {}; +}; + +#endif diff --git a/idl/Makefile.am b/idl/Makefile.am new file mode 100644 index 0000000..321a10e --- /dev/null +++ b/idl/Makefile.am @@ -0,0 +1,47 @@ +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +salomeidldir = $(prefix)/idl +salomeincludedir = $(includedir)/salome +libdir = $(prefix)/lib/salome + +BUILT_SOURCES = JOBMANAGER_IDLSK.cc +IDL_FILES = JOBMANAGER_IDL.idl + +lib_LTLIBRARIES = libJOBMANAGER_IDL.la +salomeidl_DATA = $(IDL_FILES) + +nodist_libJOBMANAGER_IDL_la_SOURCES = JOBMANAGER_IDLSK.cc +nodist_salomeinclude_HEADERS = JOBMANAGER_IDL.hh + +libJOBMANAGER_IDL_la_CXXFLAGS = -I. @KERNEL_CXXFLAGS@ @OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@ +libJOBMANAGER_IDL_la_LIBADD = $(KERNEL_LIBS) + +OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@ -I$(KERNEL_ROOT_DIR)/idl/salome + +%SK.cc %.hh : %.idl + $(OMNIORB_IDL) -bcxx $(OMNIORB_IDLCXXFLAGS) $< + +# E.A. : IDLPYFLAGS is just to compile with cmake (parsed in am2cmake). + +IDLPYFLAGS = @IDLPYFLAGS@ -I$(KERNEL_ROOT_DIR)/idl/salome + +CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx + +EXTRA_DIST = $(IDL_FILES) diff --git a/m4/ac_cxx_option.m4 b/m4/ac_cxx_option.m4 index 6f31513..bfd9b36 100644 --- a/m4/ac_cxx_option.m4 +++ b/m4/ac_cxx_option.m4 @@ -1,21 +1,22 @@ -dnl Copyright (C) 2006-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + dnl @synopsis AC_CXX_OPTION(-option,variable where we add option if ok,action if ok; action if not ok) dnl Check options for C++ compiler dnl @author Bernard Secher - 15/01/2004 diff --git a/m4/ac_linker_options.m4 b/m4/ac_linker_options.m4 index cec98c4..8da3462 100644 --- a/m4/ac_linker_options.m4 +++ b/m4/ac_linker_options.m4 @@ -1,21 +1,22 @@ -dnl Copyright (C) 2006-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + dnl @synopsis AC_LINKER_OPTIONS dnl Check warning flags for C++ compiler to control warning messages dnl diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4 new file mode 100644 index 0000000..11bc253 --- /dev/null +++ b/m4/acx_pthread.m4 @@ -0,0 +1,224 @@ +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl + +dnl Paul RASCLE: modification for Linux: -pthread required by boost... +dnl Available from the GNU Autoconf Macro Archive at: +dnl +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *linux*) + + # On linux "none" works, but boost requires -pthread, so, try first "-pthread" +acx_pthread_flags="-pthread pthreads none -Kthread -kthread lthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + ;; + + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthread or + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: threads are created detached by default + # and the JOINABLE attribute has a nonstandard name (UNDETACHED). + AC_MSG_CHECKING([for joinable pthread attribute]) + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_JOINABLE;], + ok=PTHREAD_CREATE_JOINABLE, ok=unknown) + if test x"$ok" = xunknown; then + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_UNDETACHED;], + ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) + fi + if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then + AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, + [Define to the necessary symbol if this constant + uses a non-standard name on your system.]) + fi + AC_MSG_RESULT(${ok}) + if test x"$ok" = xunknown; then + AC_MSG_WARN([we do not know how to create joinable pthreads]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with cc_r + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/m4/check_boost.m4 b/m4/check_boost.m4 new file mode 100644 index 0000000..97112c4 --- /dev/null +++ b/m4/check_boost.m4 @@ -0,0 +1,176 @@ +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl + +AC_DEFUN([CHECK_BOOST],[ + +AC_CHECKING(for BOOST Library) + +AC_REQUIRE([ENABLE_PTHREADS])dnl + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +gccver=`$CC -dumpversion | sed 's/^\([[0-9]]\+\)\.\([[0-9]]\+\).*/\1\2/g'` +SUFFIXES="empty -mt -gcc -gcc-mt -gcc${gccver} -gcc${gccver}-mt" + +BOOST_CPPFLAGS="" +BOOST_LIBSUFFIX="" +BOOST_LIBS="" + +AC_CHECKING(for BOOST location) +AC_ARG_WITH(boost, + [AC_HELP_STRING([--with-boost=DIR],[root directory path to BOOST library installation])], + [BOOSTDIR="$withval" + AC_MSG_RESULT("select $withval as path to BOOST library") + ]) + +if test "x${BOOSTDIR}" = "x" ; then + BOOSTDIR="/usr" +fi + +AC_MSG_RESULT(\$BOOSTDIR = ${BOOSTDIR}) + +CPPFLAGS_old="${CPPFLAGS}" +LIBS_old=$LIBS + +LIB_SUFFIX="${LIB_LOCATION_SUFFIX}" + +if test "x${BOOSTDIR}" != "x" ; then + BOOST_CPPFLAGS="-I${BOOSTDIR}/include" + BOOST_LIBS="-L${BOOSTDIR}/lib${LIB_SUFFIX}" +fi + +if test "x${BOOSTDIR}" = "x/usr" ; then + BOOST_CPPFLAGS="" + BOOST_LIBS="" +fi + +boost_ok=no +boost_headers_ok=no +boost_binaries_ok=no + +dnl BOOST headers +AC_CHECKING(for BOOST headers) +CPPFLAGS="${CPPFLAGS_old} ${BOOST_CPPFLAGS}" + +boost_include_dir_ok=yes +if test "x${BOOSTDIR}" != "x" ; then + AC_CHECK_FILE(${BOOSTDIR}/include/boost/shared_ptr.hpp, + boost_include_dir_ok=yes, + boost_include_dir_ok=no) +fi + +BOOST_PROGRAM_OPTIONS_LIB=no +if test "x${boost_include_dir_ok}" = "xyes" ; then + AC_CHECK_FILE(${BOOSTDIR}/include/boost/program_options.hpp, + BOOST_PROGRAM_OPTIONS_LIB=yes, + BOOST_PROGRAM_OPTIONS_LIB=no) +fi +AC_MSG_RESULT(for boost program_options tool: $BOOST_PROGRAM_OPTIONS_LIB) + +if test "x${boost_include_dir_ok}" = "xyes" ; then + AC_TRY_COMPILE([#include ], + [boost::shared_ptr(new int)], + boost_headers_ok=yes, + boost_headers_ok=no) +fi + +if test "x${boost_headers_ok}" = "xno" ; then + BOOST_CPPFLAGS="BOOST_CPPFLAGS_NOT_DEFINED" +else + AC_MSG_RESULT(\$BOOST_CPPFLAGS = ${BOOST_CPPFLAGS}) +fi +AC_MSG_RESULT(for boost headers: $boost_headers_ok) + +if test "x${boost_headers_ok}" = "xyes" ; then + dnl BOOST binaries + AC_CHECKING(for BOOST binaries) + boost_lib_dir_ok=yes + if test "x${BOOSTDIR}" != "x" ; then + for BOOST_LIBSUFFIX in ${SUFFIXES} ; do + test "${BOOST_LIBSUFFIX}" == "empty" && BOOST_LIBSUFFIX="" + AC_CHECK_FILE([${BOOSTDIR}/lib${LIB_SUFFIX}/libboost_thread${BOOST_LIBSUFFIX}.so], + [boost_lib_dir_ok=yes], + [AC_CHECK_FILE([${BOOSTDIR}/lib64/libboost_thread${BOOST_LIBSUFFIX}.so], + [boost_lib_dir_ok=yes; LIB_SUFFIX=64], + [boost_lib_dir_ok=no]) + ]) + if test "x${boost_lib_dir_ok}" = "xyes" ; then + break + fi + done + fi + if test "x${boost_lib_dir_ok}" = "xyes" ; then + LIBS="${LIBS_old} ${BOOST_LIBS} -lboost_thread${BOOST_LIBSUFFIX}" + AC_TRY_LINK([#include ], + [struct TBody{ void operator()(){} }; boost::thread(TBody())], + boost_binaries_ok=yes, + boost_binaries_ok=no) + if test "x${boost_binaries_ok}" = "xyes" ; then + break + fi + fi +fi + +if test "x${boost_binaries_ok}" = "xno" ; then + BOOST_LIBS="BOOST_LIBS_NOT_FOUND" + BOOST_LIBSUFFIX="-not-defined" +else + AC_MSG_RESULT(\$BOOST_LIBSUFFIX = ${BOOST_LIBSUFFIX}) + AC_MSG_RESULT(\$BOOST_LIBS = ${BOOST_LIBS}) + AC_CHECK_FILE(${BOOSTDIR}/lib${LIB_SUFFIX}/libboost_thread${BOOST_LIBSUFFIX}.so, + BOOST_LIB_THREAD="${BOOST_LIBS} -lboost_thread${BOOST_LIBSUFFIX}", + BOOST_LIB_THREAD="") + AC_CHECK_FILE(${BOOSTDIR}/lib${LIB_SUFFIX}/libboost_signals${BOOST_LIBSUFFIX}.so, + BOOST_LIB_SIGNALS="${BOOST_LIBS} -lboost_signals${BOOST_LIBSUFFIX}", + BOOST_LIB_SIGNALS="") + AC_CHECK_FILE(${BOOSTDIR}/lib${LIB_SUFFIX}/libboost_system${BOOST_LIBSUFFIX}.so, + BOOST_LIB_SYSTEM="${BOOST_LIBS} -lboost_system${BOOST_LIBSUFFIX}", + BOOST_LIB_SYSTEM="") + AC_CHECK_FILE(${BOOSTDIR}/lib${LIB_SUFFIX}/libboost_regex${BOOST_LIBSUFFIX}.so, + BOOST_LIB_REGEX="${BOOST_LIBS} -lboost_regex${BOOST_LIBSUFFIX}", + BOOST_LIB_REGEX="") +fi +AC_MSG_RESULT(for boost binaries: $boost_binaries_ok) + +CPPFLAGS="${CPPFLAGS_old}" +LIBS="${LIBS_old}" + +if test "x${boost_headers_ok}" = "xyes" ; then + if test "x${boost_binaries_ok}" = "xyes" ; then + boost_ok=yes + fi +fi + +AC_MSG_RESULT(for boost: $boost_ok) + +AC_SUBST(BOOST_CPPFLAGS) +AC_SUBST(BOOST_LIBSUFFIX) +AC_SUBST(BOOST_LIBS) +AC_SUBST(BOOST_LIB_THREAD) +AC_SUBST(BOOST_LIB_SIGNALS) +AC_SUBST(BOOST_LIB_SYSTEM) +AC_SUBST(BOOST_LIB_REGEX) +AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) + +AC_LANG_RESTORE + +])dnl + + diff --git a/m4/check_omniorb.m4 b/m4/check_omniorb.m4 index f2be9a7..eaf2398 100644 --- a/m4/check_omniorb.m4 +++ b/m4/check_omniorb.m4 @@ -1,20 +1,20 @@ -dnl Copyright (C) 2006-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl AC_DEFUN([AC_CHECK_OMNIORB],[ AC_REQUIRE([AC_PROG_CC])dnl @@ -25,10 +25,12 @@ AC_REQUIRE([AC_PROG_CXXCPP])dnl AC_CHECKING(for omniORB) omniORB_ok=yes -if test "x$PYTHON" = "x" -then - CHECK_PYTHON -fi +#VSR: Python is not currently required. +#Commented to avoid warning message on configure. +#if test "x$PYTHON" = "x" +#then +# CHECK_PYTHON +#fi AC_LANG_SAVE AC_LANG_CPLUSPLUS diff --git a/m4/check_salome.m4 b/m4/check_salome.m4 index f6bdfa7..e3848cf 100644 --- a/m4/check_salome.m4 +++ b/m4/check_salome.m4 @@ -1,20 +1,20 @@ -dnl Copyright (C) 2006-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl # Check availability of Salome's KERNEL binary distribution # diff --git a/m4/check_sphinx.m4 b/m4/check_sphinx.m4 index eec1495..de4082c 100644 --- a/m4/check_sphinx.m4 +++ b/m4/check_sphinx.m4 @@ -1,20 +1,20 @@ -dnl Copyright (C) 2006-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl AC_DEFUN([CHECK_SPHINX],[ diff --git a/m4/enable_pthreads.m4 b/m4/enable_pthreads.m4 new file mode 100644 index 0000000..c7325cc --- /dev/null +++ b/m4/enable_pthreads.m4 @@ -0,0 +1,21 @@ +dnl modify CFLAGS, CXXFLAGS and LIBS for compiling pthread-based programs. +dnl@author (C) Ruslan Shevchenko , 1998, 2000 +dnl@id $Id$ +dnl Modified to use acx_pthread.m4 from GNU Autoconf Macro Archive +dnl +AC_DEFUN([ENABLE_PTHREADS],[ +AC_REQUIRE([ACX_PTHREAD]) + +if test x"$enable_pthreads_done" != xyes; then + if test x"$acx_pthread_ok" = xyes; then + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" + LIBS="$LIBS $PTHREAD_LIBS" + threads_ok=yes + else + threads_ok=no + fi + enable_pthreads_done=yes +fi +])dnl +dnl diff --git a/m4/i2_check_qt4.m4 b/m4/i2_check_qt4.m4 index 355c389..81bcc06 100644 --- a/m4/i2_check_qt4.m4 +++ b/m4/i2_check_qt4.m4 @@ -1,21 +1,22 @@ -dnl Copyright (C) 2006-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + dnl the following variables are exported: dnl QT_MOC dnl QT_UIC @@ -28,6 +29,7 @@ dnl qt4 is searched in the following order dnl path given with --with-qt4 options dnl presence of QTDIR variable dnl /usr +dnl when HAS_GUI is false (no salome gui) and nothing is said for qt4, qt4 is not checked dnl usages dnl ./configure --prefix=/home/prascle/partage/maquettes/install dnl ./configure --prefix=/home/prascle/partage/maquettes/install --with-qt4 @@ -42,6 +44,8 @@ AC_DEFUN([I2_CHECK_QT4], AC_REQUIRE([AC_PROG_CPP]) qt_ok=no + qt4_wanted=yes + WITH_QT4=0 # --- check if qt4 standard install directory is defined (with subdirectories bin lib include) qt4_install_path="" @@ -60,34 +64,49 @@ AC_DEFUN([I2_CHECK_QT4], fi fi - # --- if qt4 standard install directory is not defined: QTDIR value if defined, or /usr + # --- if qt4 standard install directory is not defined + # if HAS_GUI= 0: Qt4 not wanted + # else: QTDIR value if defined, or /usr if test x${withval} = xnotset then - if test -z $QTDIR + if test x${HAS_GUI} = x0 then - qt4_install_path="/usr" + qt4_wanted=no + AC_MSG_NOTICE([SALOME GUI not present, Qt4 not specified, skip detection]) else - if test $QTDIR = /usr/lib/qt3 ; then - if test -d /usr/lib/qt4 ; then - AC_MSG_RESULT(it is strange for a qt4 installation !) - AC_MSG_RESULT(/usr/lib/qt4 is present) - AC_MSG_RESULT(replacing QTDIR by /usr/lib/qt4) - QTDIR=/usr/lib/qt4 + if test -z $QTDIR + then + qt4_install_path="/usr" + else + if test $QTDIR = /usr/lib/qt3 ; then + if test -d /usr/lib/qt4 ; then + AC_MSG_RESULT(it is strange for a qt4 installation !) + AC_MSG_RESULT(/usr/lib/qt4 is present) + AC_MSG_RESULT(replacing QTDIR by /usr/lib/qt4) + QTDIR=/usr/lib/qt4 + fi fi + qt4_install_path=$QTDIR fi - qt4_install_path=$QTDIR fi fi # --- if qt4 standard install directory is not wanted: --without-qt4 or --with-qt4=no if test x${withval} = xno then - qt4_install_path="" + qt4_wanted=no + AC_MSG_NOTICE([Qt4 is not wanted, skip detection]) fi QT_DIR=${qt4_install_path} AC_SUBST(QT_DIR) + # ---------------------------------------------------------------------- + # --- only when qt4 wanted (no explicit --without-qt4 nor --with-qt4=no) + + if test x${qt4_wanted} = xyes + then + # --- check if qt4 includes directory is defined qt4_include_path="" AC_ARG_WITH([qt4-includes], @@ -146,11 +165,6 @@ AC_DEFUN([I2_CHECK_QT4], fi fi - WITH_QT4=0 - - AC_MSG_NOTICE(${qt4_include_path}) - AC_MSG_NOTICE(${qt4_library_path}) - AC_MSG_NOTICE(${qt4_tools_path}) # test if qt4 is completely defined qt4_defined=yes @@ -158,16 +172,22 @@ AC_DEFUN([I2_CHECK_QT4], then qt4_defined=no AC_MSG_NOTICE([No Qt4 include path defined]) + else + AC_MSG_NOTICE([Qt4 include path is ${qt4_include_path}]) fi if test x${qt4_library_path} = x then qt4_defined=no AC_MSG_NOTICE([No Qt4 library path defined]) + else + AC_MSG_NOTICE([Qt4 library path is ${qt4_library_path}]) fi if test x${qt4_tools_path} = x then qt4_defined=no AC_MSG_NOTICE([No Qt4 tools path defined]) + else + AC_MSG_NOTICE([Qt4 tools path is ${qt4_tools_path}]) fi # saving values for compilation variables @@ -218,7 +238,7 @@ AC_DEFUN([I2_CHECK_QT4], AC_SUBST(qt4_cppflags) # --- we test the library file presence and usability - if test x${qt4_library_path} = /usr/lib + if test x${qt4_library_path} = x/usr/lib then qt4_ldflags="" else @@ -226,8 +246,7 @@ AC_DEFUN([I2_CHECK_QT4], fi AC_MSG_NOTICE([checking whether link with qt4 is working]) - qt4_lib_name=QtGui - qt4_libs="-l$qt4_lib_name" + qt4_libs="-lQtCore -lQtGui" LDFLAGS="${LDFLAGS} ${qt4_ldflags}" LIBS="${LIBS} ${qt4_libs}" AC_LANG_PUSH(C++) @@ -257,6 +276,15 @@ AC_DEFUN([I2_CHECK_QT4], AC_MSG_NOTICE([No Qt4 support]) fi + # restoring saved values + CPPFLAGS=$saved_CPPFLAGS + LDFLAGS=$saved_LDFLAGS + LIBS=$saved_LIBS + + fi + # --- end: only when qt4 wanted (no explicit --without-qt4 nor --with-qt4=no) + # ---------------------------------------------------------------------- + # Propagate test into atlocal AC_SUBST(WITH_QT4) @@ -266,21 +294,21 @@ AC_DEFUN([I2_CHECK_QT4], # ... and into source files AC_DEFINE_UNQUOTED(HAS_QT4, $WITH_QT4, [Qt4 library]) - # restoring saved values - CPPFLAGS=$saved_CPPFLAGS - LDFLAGS=$saved_LDFLAGS - LIBS=$saved_LIBS - ]) AC_DEFUN([I2_CHECK_QSCINTILLA], [ AC_REQUIRE([I2_CHECK_QT4]) - qscintilla_ok=no WITH_QSCI4=0 + # ---------------------------------------------------------------------- + # --- check qscintilla only when qt4 OK + + if test x${WITH_QT4} = x1 + then + # --- check if qsci4 includes directory is defined qsci4_include_path="" qsci4_cppflags="" @@ -389,23 +417,30 @@ AC_DEFUN([I2_CHECK_QSCINTILLA], AC_SUBST(qsci4_libs) WITH_QSCI4=1 qscintilla_ok=yes - # Propagate test into atlocal - AC_SUBST(WITH_QSCI4) fi else AC_MSG_NOTICE([no support for qscintilla for qt4]) fi + # restoring saved values + CPPFLAGS=$saved_CPPFLAGS + LDFLAGS=$saved_LDFLAGS + LIBS=$saved_LIBS + + else + # --- end: check qscintilla only when qt4 OK + # ---------------------------------------------------------------------- + AC_MSG_NOTICE([qscintilla for qt4 not checked because Qt4 not wanted or not detected]) + fi + + # Propagate test into atlocal + AC_SUBST(WITH_QSCI4) + # Propagate test into Makefiles... AM_CONDITIONAL(WITH_QSCI4, test $WITH_QSCI4 = 1) # ... and into source files AC_DEFINE_UNQUOTED(HAS_QSCI4, $WITH_QSCI4, [QsciScintilla library]) - # restoring saved values - CPPFLAGS=$saved_CPPFLAGS - LDFLAGS=$saved_LDFLAGS - LIBS=$saved_LIBS - ]) diff --git a/m4/production.m4 b/m4/production.m4 index 802d37e..d69e5bc 100644 --- a/m4/production.m4 +++ b/m4/production.m4 @@ -1,21 +1,22 @@ -dnl Copyright (C) 2006-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2009-2012 CEA/DEN, EDF R&D dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + dnl define macros : dnl AC_ENABLE_PRODUCTION AC_DISABLE_PRODUCTION dnl AC_ENABLE_DEBUG AC_DISABLE_DEBUG diff --git a/src/Makefile.am b/src/Makefile.am index 0897ae9..8ae3eb6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,20 +1,20 @@ -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # SUBDIRS = bases engine genericgui wrappers standalone salomegui diff --git a/src/bases/BL_Exception.cxx b/src/bases/BL_Exception.cxx index 087eeb7..d925307 100644 --- a/src/bases/BL_Exception.cxx +++ b/src/bases/BL_Exception.cxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_Exception.hxx" diff --git a/src/bases/BL_Exception.hxx b/src/bases/BL_Exception.hxx index a03a836..4d78925 100644 --- a/src/bases/BL_Exception.hxx +++ b/src/bases/BL_Exception.hxx @@ -1,30 +1,40 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef __BL_EXCEPTION_HXX__ #define __BL_EXCEPTION_HXX__ +#ifdef WNT +# if defined BL_Bases_EXPORTS +# define BL_Bases_EXPORT __declspec( dllexport ) +# else +# define BL_Bases_EXPORT __declspec( dllimport ) +# endif +#else +# define BL_Bases_EXPORT +#endif + #include #include namespace BL { - class Exception : public std::exception + class BL_Bases_EXPORT Exception : public std::exception { protected: std::string _what; diff --git a/src/bases/BL_Traces.hxx b/src/bases/BL_Traces.hxx index 74ea636..1e30b07 100644 --- a/src/bases/BL_Traces.hxx +++ b/src/bases/BL_Traces.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef __BL_TRACES_HXX__ diff --git a/src/bases/Makefile.am b/src/bases/Makefile.am index 2429972..0bb9bca 100644 --- a/src/bases/Makefile.am +++ b/src/bases/Makefile.am @@ -1,20 +1,20 @@ -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # include $(top_srcdir)/src/bases/make_begin.am diff --git a/src/bases/make_begin.am b/src/bases/make_begin.am index 0e885b9..c9741e1 100644 --- a/src/bases/make_begin.am +++ b/src/bases/make_begin.am @@ -1,21 +1,22 @@ -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + ## # Here any commonly used variables can be defined ## diff --git a/src/engine/BL_Engine.hxx b/src/engine/BL_Engine.hxx new file mode 100755 index 0000000..6551201 --- /dev/null +++ b/src/engine/BL_Engine.hxx @@ -0,0 +1,32 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef __BL_ENGINE_HXX__ +#define __BL_ENGINE_HXX__ + +#ifdef WNT +# if defined BL_Engine_EXPORTS +# define BL_Engine_EXPORT __declspec( dllexport ) +# else +# define BL_Engine_EXPORT __declspec( dllimport ) +# endif +#else +# define BL_Engine_EXPORT +#endif + +#endif diff --git a/src/engine/BL_Job.cxx b/src/engine/BL_Job.cxx index 85bbb65..46939ab 100644 --- a/src/engine/BL_Job.cxx +++ b/src/engine/BL_Job.cxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_Job.hxx" @@ -23,34 +23,40 @@ BL::Job::Job() { DEBTRACE("Creating BL::Job"); _name = ""; - _yacs_file = ""; - _command = ""; + _job_file = ""; + _env_file = ""; _batch_params.batch_directory = ""; - _batch_params.expected_during_time = ""; + _batch_params.maximum_duration = ""; _batch_params.expected_memory = ""; _batch_params.nb_proc = 0; _files_params.result_directory = ""; - _machine_choosed = ""; + _resource_choosed = ""; + _batch_queue = ""; _state = BL::Job::CREATED; _thread_state = BL::Job::NOTHING; _salome_launcher_id = -1; + _dump_yacs_state = 0; + _ll_jobtype = ""; } BL::Job::Job(const std::string & name) { DEBTRACE("Creating BL::Job with name : " << name); _name = name; - _yacs_file = ""; - _command = ""; + _job_file = ""; + _env_file = ""; _batch_params.batch_directory = ""; - _batch_params.expected_during_time = ""; + _batch_params.maximum_duration = ""; _batch_params.expected_memory = ""; _batch_params.nb_proc = 0; _files_params.result_directory = ""; - _machine_choosed = ""; + _resource_choosed = ""; + _batch_queue = ""; _state = BL::Job::CREATED; _thread_state = BL::Job::NOTHING; _salome_launcher_id = -1; + _dump_yacs_state = 0; + _ll_jobtype = ""; } BL::Job::~Job() @@ -68,47 +74,76 @@ BL::Job::getName() return _name; } -void +void BL::Job::setType(BL::Job::JobType type) { _type = type; } +void +BL::Job::setType(const std::string & type) +{ + if (type == "command") + { + setType(BL::Job::COMMAND); + } + else if (type == "yacs_file") + { + setType(BL::Job::YACS_SCHEMA); + } + else if (type == "python_salome") + { + setType(BL::Job::PYTHON_SALOME); + } +} + BL::Job::JobType BL::Job::getType() { return _type; } +void +BL::Job::setDumpYACSState(const int & dump_yacs_state) +{ + _dump_yacs_state = dump_yacs_state; +} + +int +BL::Job::getDumpYACSState() +{ + return _dump_yacs_state; +} + void -BL::Job::setYACSFile(std::string & yacs_file) +BL::Job::setJobFile(const std::string & job_file) { - _yacs_file = yacs_file; + _job_file = job_file; } std::string & -BL::Job::getYACSFile() +BL::Job::getJobFile() { - return _yacs_file; + return _job_file; } void -BL::Job::setCommand(std::string & command) +BL::Job::setEnvFile(const std::string & env_file) { - _command = command; + _env_file = env_file; } std::string & -BL::Job::getCommand() +BL::Job::getEnvFile() { - return _command; + return _env_file; } void BL::Job::setBatchParameters(BL::Job::BatchParam & param) { _batch_params.batch_directory = param.batch_directory; - _batch_params.expected_during_time = param.expected_during_time; + _batch_params.maximum_duration = param.maximum_duration; _batch_params.expected_memory = param.expected_memory; _batch_params.nb_proc = param.nb_proc; } @@ -134,15 +169,39 @@ BL::Job::getFilesParameters() } void -BL::Job::setMachine(std::string & machine) +BL::Job::setResource(const std::string & resource) { - _machine_choosed = machine; + _resource_choosed = resource; } std::string & -BL::Job::getMachine() +BL::Job::getResource() { - return _machine_choosed; + return _resource_choosed; +} + +void +BL::Job::setBatchQueue(const std::string & queue) +{ + _batch_queue = queue; +} + +std::string & +BL::Job::getBatchQueue() +{ + return _batch_queue; +} + +void +BL::Job::setLoadLevelerJobType(const std::string & jobtype) +{ + _ll_jobtype = jobtype; +} + +std::string & +BL::Job::getLoadLevelerJobType() +{ + return _ll_jobtype; } void @@ -157,6 +216,105 @@ BL::Job::getState() return _state; } +std::string +BL::Job::setStringState(const std::string & state) +{ + std::string result(""); + + // Check if state is an error + if (state != "CREATED" && + state != "IN_PROCESS" && + state != "QUEUED" && + state != "RUNNING" && + state != "PAUSED" && + state != "FINISHED" && + state != "FAILED" && + state != "NOT_CREATED" && + state != "ERROR" + ) + { + DEBTRACE("Error state in setStringState"); + result = "RefreshError"; + } + + if (result == "") + { + if (state == "CREATED") + { + if (_state != BL::Job::CREATED) + { + setState(BL::Job::CREATED); + result = state; + } + } + else if (state == "NOT_CREATED") + { + if (_state != BL::Job::NOT_CREATED) + { + setState(BL::Job::NOT_CREATED); + result = state; + } + } + else if (state == "QUEUED") + { + if (_state != BL::Job::QUEUED) + { + setState(BL::Job::QUEUED); + result = state; + } + } + else if (state == "IN_PROCESS") + { + if (_state != BL::Job::IN_PROCESS) + { + setState(BL::Job::IN_PROCESS); + result = state; + } + } + else if (state == "RUNNING") + { + if (_state != BL::Job::RUNNING) + { + setState(BL::Job::RUNNING); + result = state; + } + } + else if (state == "PAUSED") + { + if (_state != BL::Job::PAUSED) + { + setState(BL::Job::PAUSED); + result = state; + } + } + else if (state == "FINISHED") + { + if (_state != BL::Job::FINISHED) + { + setState(BL::Job::FINISHED); + result = state; + } + } + else if (state == "ERROR") + { + if (_state != BL::Job::ERROR) + { + setState(BL::Job::ERROR); + result = state; + } + } + else if (state == "FAILED") + { + if (_state != BL::Job::FAILED) + { + setState(BL::Job::FAILED); + result = state; + } + } + } + return result; +} + void BL::Job::setThreadState(BL::Job::ThreadState state) { diff --git a/src/engine/BL_Job.hxx b/src/engine/BL_Job.hxx index 6a78e1c..d4e3da0 100644 --- a/src/engine/BL_Job.hxx +++ b/src/engine/BL_Job.hxx @@ -1,33 +1,38 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_JOB_HXX_ #define _BL_JOB_HXX_ +#include "BL_Engine.hxx" #include "BL_Traces.hxx" #include #include +#ifdef WNT +#undef ERROR +#endif + namespace BL{ - class Job + class BL_Engine_EXPORT Job { public: Job(); @@ -37,41 +42,52 @@ namespace BL{ void setName(const std::string & name); std::string getName(); - enum JobType {YACS_SCHEMA, COMMAND}; + enum JobType {YACS_SCHEMA, COMMAND, PYTHON_SALOME}; void setType(BL::Job::JobType type); + void setType(const std::string & type); BL::Job::JobType getType(); - void setYACSFile(std::string & yacs_file); - std::string & getYACSFile(); + void setJobFile(const std::string & job_file); + std::string & getJobFile(); - void setCommand(std::string & command); - std::string & getCommand(); + void setEnvFile(const std::string & env_file); + std::string & getEnvFile(); + + void setDumpYACSState(const int & dump_yacs_state); + int getDumpYACSState(); struct BatchParam { - std::string batch_directory; - std::string expected_during_time; - std::string expected_memory; - int nb_proc; + std::string batch_directory; + std::string maximum_duration; + std::string expected_memory; + int nb_proc; }; void setBatchParameters(BL::Job::BatchParam & param); BL::Job::BatchParam & getBatchParameters(); struct FilesParam { - std::string result_directory; - std::list input_files_list; - std::list output_files_list; + std::string result_directory; + std::list input_files_list; + std::list output_files_list; }; void setFilesParameters(BL::Job::FilesParam & param); BL::Job::FilesParam & getFilesParameters(); - void setMachine(std::string & machine); - std::string & getMachine(); + void setResource(const std::string & resource); + std::string & getResource(); + + void setBatchQueue(const std::string & queue); + std::string & getBatchQueue(); - enum State {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR}; + void setLoadLevelerJobType(const std::string & jobtype); + std::string & getLoadLevelerJobType(); + + enum State {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR, FAILED, NOT_CREATED}; void setState(BL::Job::State state); BL::Job::State getState(); + std::string setStringState(const std::string & state); enum ThreadState {NOTHING, STARTING}; void setThreadState(BL::Job::ThreadState state); @@ -80,20 +96,22 @@ namespace BL{ void setSalomeLauncherId(int id); int getSalomeLauncherId(); - private: BL::Job::State _state; BL::Job::ThreadState _thread_state; + int _dump_yacs_state; std::string _name; BL::Job::JobType _type; - std::string _yacs_file; - std::string _command; - + std::string _job_file; + std::string _env_file; + BL::Job::BatchParam _batch_params; BL::Job::FilesParam _files_params; - std::string _machine_choosed; + std::string _resource_choosed; + std::string _batch_queue; + std::string _ll_jobtype; int _salome_launcher_id; }; diff --git a/src/engine/BL_JobsManager.cxx b/src/engine/BL_JobsManager.cxx index 985d280..c7bf40e 100644 --- a/src/engine/BL_JobsManager.cxx +++ b/src/engine/BL_JobsManager.cxx @@ -1,30 +1,37 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_JobsManager.hxx" +#include + +#ifdef WNT +#undef ERROR +#endif BL::JobsManager::JobsManager(BL::SALOMEServices * salome_services) { DEBTRACE("Creating BL::JobsManager"); BL_ASSERT(salome_services); _salome_services = salome_services; + _salome_services->set_manager(this); _observer = NULL; + _name_counter = 0; } BL::JobsManager::~JobsManager() @@ -45,12 +52,13 @@ BL::JobsManager::setObserver(BL::Observer * observer) } BL::Job * -BL::JobsManager::addNewJob(const std::string & name) +BL::JobsManager::createJob(const std::string & name) { - DEBTRACE("addNewJob BL::JobsManager"); + DEBTRACE("createJob BL::JobsManager"); BL::Job * new_job = NULL; + _thread_mutex_jobs_map.lock(); _jobs_it = _jobs.find(name); if (_jobs_it == _jobs.end()) { @@ -60,15 +68,47 @@ BL::JobsManager::addNewJob(const std::string & name) _jobs[name] = new_job; } else - DEBTRACE("addNewJob Error !!!! Job already exist: " << name); + DEBTRACE("createJob Error !!!! Job already exist: " << name); + _thread_mutex_jobs_map.unlock(); return new_job; } +void +BL::JobsManager::addJobToLauncher(const std::string & name) +{ + DEBTRACE("addJobToLauncher BL::JobsManager"); + + _thread_mutex_jobs_map.lock(); + _jobs_it = _jobs.find(name); + if (_jobs_it == _jobs.end()) + { + // TODO: SHOULD SEND an exeception... + DEBMSG("[addJobToLauncher] failed, job was not found"); + } + std::string result = ""; + result = _salome_services->create_job(_jobs_it->second); + + // Unlock is here to be sure that + // method setSalomeLauncherId is called if + // the creation is successfull + _thread_mutex_jobs_map.unlock(); + + if (_observer) + if (result != "") + { + _jobs_it->second->setState(BL::Job::NOT_CREATED); + _observer->sendEvent("create_job", "Error", name, result); + } + else + _observer->sendEvent("create_job", "Ok", name, ""); +} + void BL::JobsManager::removeJob(const std::string & name) { DEBTRACE("removeJob BL::JobsManager"); + _thread_mutex_jobs_map.lock(); _jobs_it = _jobs.find(name); if (_jobs_it != _jobs.end()) { @@ -81,12 +121,13 @@ BL::JobsManager::removeJob(const std::string & name) if (_observer) if (result != "") - _observer->sendEvent("delete_job", "Error", name, result); + _observer->sendEvent("delete_job", "Error", name, result); else - _observer->sendEvent("delete_job", "Ok", name, ""); + _observer->sendEvent("delete_job", "Ok", name, ""); } else DEBTRACE("removeJob Error !!!! Job does not exist: " << name); + _thread_mutex_jobs_map.unlock(); } BL::Job * @@ -105,78 +146,113 @@ BL::JobsManager::getJobs() bool BL::JobsManager::job_already_exist(const std::string & name) { - _jobs_it = _jobs.find(name); + bool result = true; + _thread_mutex_jobs_map.lock(); + _jobs_it = _jobs.find(name); if (_jobs_it == _jobs.end()) - return false; - else - return true; + result = false; + _thread_mutex_jobs_map.unlock(); + return result; } void BL::JobsManager::start_job(const std::string & name) { DEBTRACE("BL::JobsManager::start_job called for job: " << name); + // Prepare Info for thread + BL::JobsManager::thread_info * ti = new thread_info(); + ti->object_ptr = this; + ti->job_name = name; + omni_thread::create(BL::JobsManager::starting_job_thread, ti); + +} + +void +BL::JobsManager::starting_job_thread(void * object_ptr) +{ + DEBTRACE("starting_job_thread BL::JobsManager called"); + BL::JobsManager::thread_info * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + std::string job_name = ti->job_name; // Check job exits - _jobs_it = _jobs.find(name); - if (_jobs_it == _jobs.end()) + object->_thread_mutex_jobs_map.lock(); + object->_jobs_it = object->_jobs.find(job_name); + if (object->_jobs_it == object->_jobs.end()) { - DEBTRACE("BL::JobsManager::start_job job unknown: " << name); - return; + DEBTRACE("BL::JobsManager::start_job job unknown: " << job_name); } else { - _thread_mutex.lock(); - BL::Job * job = _jobs_it->second; - // Check Job Exec State - multithread protection - if (job->getThreadState() == BL::Job::NOTHING) + BL::Job * job = object->getJob(job_name); + std::string result = object->_salome_services->start_job(job); + if (result == "") { - // Prepare Info for thread - BL::JobsManager::thread_info * ti = new thread_info(); - ti->object_ptr = this; - ti->job_name = name; - job->setState(BL::Job::IN_PROCESS); - job->setThreadState(BL::Job::STARTING); - omni_thread::create(BL::JobsManager::starting_job_thread, ti); + job->setState(BL::Job::QUEUED); + job->setThreadState(BL::Job::NOTHING); + if (object->_observer) + object->_observer->sendEvent("start_job", "Ok", job_name, ""); } else { - DEBTRACE("BL::JobsManager::start_job nothin to do, job already starting, job name: " << name); + job->setState(BL::Job::ERROR); + job->setThreadState(BL::Job::NOTHING); + if (object->_observer) + object->_observer->sendEvent("start_job", "Error", job_name, result); } - _thread_mutex.unlock(); + } + object->_thread_mutex_jobs_map.unlock(); +} + +void +BL::JobsManager::stop_job(const std::string & name) +{ + DEBTRACE("stop_job BL::JobsManager called"); + + _thread_mutex_jobs_map.lock(); + // Check job exits + _jobs_it = _jobs.find(name); + if (_jobs_it == _jobs.end()) + { + DEBTRACE("BL::JobsManager::stop_job job unknown: " << name); + _thread_mutex_jobs_map.unlock(); + return; + } + else + { + // Prepare Info for thread + BL::JobsManager::thread_info * ti = new thread_info(); + ti->object_ptr = this; + ti->job_name = name; + omni_thread::create(BL::JobsManager::stop_job_thread, ti); } } void -BL::JobsManager::starting_job_thread(void * object_ptr) +BL::JobsManager::stop_job_thread(void * object_ptr) { - DEBTRACE("starting_job_thread BL::JobsManager called"); + DEBTRACE("stop_job_thread BL::JobsManager called"); BL::JobsManager::thread_info * ti = reinterpret_cast(object_ptr); BL::JobsManager * object = ti->object_ptr; std::string job_name = ti->job_name; BL::Job * job = object->getJob(job_name); - std::string result = object->_salome_services->start_job(job); + std::string result = object->_salome_services->stop_job(job); - object->_thread_mutex.lock(); // End if (result == "") { if (object->_observer) - object->_observer->sendEvent("start_job", "Ok", job_name, ""); - job->setState(BL::Job::QUEUED); - job->setThreadState(BL::Job::NOTHING); + object->_observer->sendEvent("stop_job", "Ok", job_name, ""); } else { if (object->_observer) - object->_observer->sendEvent("start_job", "Error", job_name, result); - job->setState(BL::Job::ERROR); - job->setThreadState(BL::Job::NOTHING); + object->_observer->sendEvent("stop_job", "Error", job_name, result); } - object->_thread_mutex.unlock(); + object->_thread_mutex_jobs_map.unlock(); } void @@ -184,16 +260,17 @@ BL::JobsManager::refresh_jobs() { DEBTRACE("refresh_jobs BL::JobsManager called"); - omni_thread::create(BL::JobsManager::refresh_job, this); + omni_thread::create(BL::JobsManager::refresh_jobs_thread, this); } void -BL::JobsManager::refresh_job(void * object_ptr) +BL::JobsManager::refresh_jobs_thread(void * object_ptr) { DEBTRACE("refresh_job BL::JobsManager called"); BL::JobsManager * object = reinterpret_cast(object_ptr); //iterate on all jobs + object->_thread_mutex_jobs_map.lock(); _jobs_map::iterator jobs_it; jobs_it = object->_jobs.begin(); for(;jobs_it != object->_jobs.end();jobs_it++) @@ -201,90 +278,55 @@ BL::JobsManager::refresh_job(void * object_ptr) BL::Job * job = jobs_it->second; if (job->getSalomeLauncherId() != -1) { - object->_thread_mutex.lock(); if (job->getThreadState() == BL::Job::NOTHING) { - BL::Job::State job_state = job->getState(); - if (job_state != BL::Job::FINISHED or job_state != BL::Job::ERROR) - { - std::string result = object->_salome_services->refresh_job(job); - if (result == "QUEUED") - { - if (job_state != BL::Job::QUEUED) - { - job->setState(BL::Job::QUEUED); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "IN_PROCESS") - { - if (job_state != BL::Job::IN_PROCESS) - { - job->setState(BL::Job::IN_PROCESS); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "RUNNING") - { - if (job_state != BL::Job::RUNNING) - { - job->setState(BL::Job::RUNNING); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "PAUSED") - { - if (job_state != BL::Job::PAUSED) - { - job->setState(BL::Job::PAUSED); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "FINISHED") - { - job->setState(BL::Job::FINISHED); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - else if (result == "ERROR") - { - job->setState(BL::Job::ERROR); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - else - { - // Error using launcher... - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Error", job->getName(), result); - } - } + BL::Job::State job_state = job->getState(); + if (job_state != BL::Job::FINISHED && + job_state != BL::Job::ERROR && + job_state != BL::Job::FAILED && + job_state != BL::Job::NOT_CREATED) + { + std::string result_launcher = object->_salome_services->refresh_job(job); + std::string result_job = job->setStringState(result_launcher); + if (result_job == "RefreshError") + { + // Error using launcher... + if (object->_observer) + object->_observer->sendEvent("refresh_job", "Error", job->getName(), result_launcher); + } + else if (result_job != "") + { + if (object->_observer) + object->_observer->sendEvent("refresh_job", "Ok", job->getName(), result_job); + } + } } - object->_thread_mutex.unlock(); } } + object->_thread_mutex_jobs_map.unlock(); } void BL::JobsManager::get_results_job(const std::string & name) { DEBTRACE("get_results_job BL::JobsManager called"); - + + _thread_mutex_jobs_map.lock(); // Check job exits _jobs_it = _jobs.find(name); if (_jobs_it == _jobs.end()) { DEBTRACE("BL::JobsManager::get_results_job job unknown: " << name); + _thread_mutex_jobs_map.unlock(); return; } else { BL::Job * job = _jobs_it->second; - if (job->getState() == BL::Job::FINISHED) + if (job->getState() == BL::Job::FINISHED || + job->getState() == BL::Job::ERROR || + job->getState() == BL::Job::FAILED + ) { // Prepare Info for thread BL::JobsManager::thread_info * ti = new thread_info(); @@ -295,6 +337,7 @@ BL::JobsManager::get_results_job(const std::string & name) else { DEBTRACE("BL::JobsManager::get_results_job job bad job state !"); + _thread_mutex_jobs_map.unlock(); return; } } @@ -309,7 +352,6 @@ BL::JobsManager::get_results_job_thread(void * object_ptr) std::string job_name = ti->job_name; BL::Job * job = object->getJob(job_name); - object->_thread_mutex_results.lock(); std::string result = object->_salome_services->get_results_job(job); // End @@ -323,5 +365,195 @@ BL::JobsManager::get_results_job_thread(void * object_ptr) if (object->_observer) object->_observer->sendEvent("get_results_job", "Error", job_name, result); } - object->_thread_mutex_results.unlock(); + object->_thread_mutex_jobs_map.unlock(); +} + +void +BL::JobsManager::save_jobs(const std::string & xml_file) +{ + DEBTRACE("BL::JobsManager::save_jobs called for : " << xml_file); + + // Prepare Info for thread + BL::JobsManager::thread_info_file * ti = new thread_info_file(); + ti->object_ptr = this; + ti->file_name = xml_file; + omni_thread::create(BL::JobsManager::save_jobs_thread, ti); +} + +void +BL::JobsManager::load_jobs(const std::string & xml_file) +{ + DEBTRACE("BL::JobsManager::load_jobs called for : " << xml_file); + + // Prepare Info for thread + BL::JobsManager::thread_info_file * ti = new thread_info_file(); + ti->object_ptr = this; + ti->file_name = xml_file; + omni_thread::create(BL::JobsManager::load_jobs_thread, ti); +} + +void +BL::JobsManager::save_jobs_thread(void * object_ptr) +{ + DEBTRACE("save_jobs_thread BL::JobsManager called"); + BL::JobsManager::thread_info_file * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + std::string file_name = ti->file_name; + + object->_thread_mutex_jobs_map.lock(); + std::string result = object->_salome_services->save_jobs(file_name); + object->_thread_mutex_jobs_map.unlock(); + + if (result != "") + if (object->_observer) + object->_observer->sendEvent("save_jobs", "Error", "", result); +} + +void +BL::JobsManager::load_jobs_thread(void * object_ptr) +{ + DEBTRACE("load_jobs_thread BL::JobsManager called"); + BL::JobsManager::thread_info_file * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + std::string file_name = ti->file_name; + + object->_thread_mutex_jobs_map.lock(); + std::string result = object->_salome_services->load_jobs(file_name); + object->_thread_mutex_jobs_map.unlock(); + + if (result != "") + if (object->_observer) + object->_observer->sendEvent("load_jobs", "Error", "", result); +} + +void +BL::JobsManager::launcher_event_save_jobs(const std::string & data) +{ + if (_observer) + _observer->sendEvent("save_jobs", "Ok", "", data); +} + +void +BL::JobsManager::launcher_event_load_jobs(const std::string & data) +{ + if (_observer) + _observer->sendEvent("load_jobs", "Ok", "", data); +} + +void +BL::JobsManager::launcher_event_new_job(const std::string & data) +{ + int job_number; + std::istringstream job_number_stream(data); + if (job_number_stream >> job_number) + { + DEBTRACE("Receive NEWJOB:" << job_number); + BL::JobsManager::thread_info_new_job * ti = new thread_info_new_job(); + ti->object_ptr = this; + ti->job_number = job_number; + omni_thread::create(BL::JobsManager::launcher_event_new_job_thread, ti); + } +} + +void +BL::JobsManager::launcher_event_update_job_state(const std::string & data) +{ + refresh_jobs(); +} + +void +BL::JobsManager::launcher_event_new_job_thread(void * object_ptr) +{ + DEBTRACE("Start of BL::JobsManager::launcher_event_new_job_thread"); + BL::JobsManager::thread_info_new_job * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + int job_number = ti->job_number; + + object->_thread_mutex_jobs_map.lock(); + + // 1: Check if job is not already on our map + bool job_in_map = false; + _jobs_map::iterator jobs_it; + jobs_it = object->_jobs.begin(); + for(;jobs_it != object->_jobs.end();jobs_it++) + { + BL::Job * job = jobs_it->second; + if (job->getSalomeLauncherId() == job_number) + job_in_map = true; + } + + if (!job_in_map) + { + // 2: We try to get job informations + + BL::Job * new_job = object->_salome_services->get_new_job(job_number); + + // 3: We add it + if (new_job) + { + // 4: Check if job has a name or if the name already exists + if (new_job->getName() == "") + { + std::ostringstream name_stream; + name_stream << "no_name_" << object->_name_counter; + object->_name_counter++; + new_job->setName(name_stream.str()); + } + + _jobs_map::iterator _jobs_it_name = object->_jobs.find(new_job->getName()); + if (_jobs_it_name != object->_jobs.end()) + { + std::ostringstream name_stream; + name_stream << new_job->getName() << "_" << object->_name_counter; + object->_name_counter++; + new_job->setName(name_stream.str()); + } + // 5: Insert job + object->_jobs[new_job->getName()] = new_job; + if (object->_observer) + object->_observer->sendEvent("add_job", "Ok", new_job->getName(), ""); + } + } + + object->_thread_mutex_jobs_map.unlock(); +} + +void +BL::JobsManager::launcher_event_remove_job(const std::string & data) +{ + int job_number; + std::istringstream job_number_stream(data); + if (job_number_stream >> job_number) + { + BL::JobsManager::thread_info_new_job * ti = new thread_info_new_job(); + ti->object_ptr = this; + ti->job_number = job_number; + omni_thread::create(BL::JobsManager::launcher_event_remove_job_thread, ti); + } +} + +void +BL::JobsManager::launcher_event_remove_job_thread(void * object_ptr) +{ + DEBTRACE("Start of BL::JobsManager::launcher_event_remove_job_thread"); + BL::JobsManager::thread_info_new_job * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + int job_number = ti->job_number; + + object->_thread_mutex_jobs_map.lock(); + + _jobs_map::iterator jobs_it; + jobs_it = object->_jobs.begin(); + for(;jobs_it != object->_jobs.end();jobs_it++) + { + BL::Job * job = jobs_it->second; + if (job->getSalomeLauncherId() == job_number) + { + job->setSalomeLauncherId(-1); + if (object->_observer) + object->_observer->sendEvent("to_remove_job", "Ok", job->getName(), ""); + } + } + + object->_thread_mutex_jobs_map.unlock(); } diff --git a/src/engine/BL_JobsManager.hxx b/src/engine/BL_JobsManager.hxx index 675a5ab..180d40f 100644 --- a/src/engine/BL_JobsManager.hxx +++ b/src/engine/BL_JobsManager.hxx @@ -1,25 +1,26 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_JOBSMANAGER_HXX_ #define _BL_JOBSMANAGER_HXX_ +#include "BL_Engine.hxx" #include "BL_Job.hxx" #include "BL_SALOMEServices.hxx" #include "BL_Traces.hxx" @@ -32,34 +33,69 @@ namespace BL{ - class JobsManager + class SALOMEServices; + + class BL_Engine_EXPORT JobsManager { public: JobsManager(BL::SALOMEServices * salome_services); virtual ~JobsManager(); + // Add QT observer void setObserver(BL::Observer * observer); - BL::Job * addNewJob(const std::string & name); - void removeJob(const std::string & name); - + // useful methods + BL::Job * createJob(const std::string & name); BL::Job * getJob(const std::string & name); std::map & getJobs(); - bool job_already_exist(const std::string & name); - virtual void start_job(const std::string & name); - virtual void refresh_jobs(); - virtual void get_results_job(const std::string & name); + // remote methods + void addJobToLauncher(const std::string & name); + void removeJob(const std::string & name); + virtual void start_job(const std::string & name); static void starting_job_thread(void * object_ptr); + + virtual void stop_job(const std::string & name); + static void stop_job_thread(void * object_ptr); + + virtual void get_results_job(const std::string & name); static void get_results_job_thread(void * object_ptr); - static void refresh_job(void * object_ptr); + + virtual void refresh_jobs(); + static void refresh_jobs_thread(void * object_ptr); + + virtual void load_jobs(const std::string & xml_file); + virtual void save_jobs(const std::string & xml_file); + static void load_jobs_thread(void * object_ptr); + static void save_jobs_thread(void * object_ptr); + + // event from launcher + void launcher_event_save_jobs(const std::string & data); + void launcher_event_load_jobs(const std::string & data); + void launcher_event_new_job(const std::string & data); + static void launcher_event_new_job_thread(void * object_ptr); + void launcher_event_remove_job(const std::string & data); + static void launcher_event_remove_job_thread(void * object_ptr); + void launcher_event_update_job_state(const std::string & data); struct thread_info { - BL::JobsManager * object_ptr; - std::string job_name; + BL::JobsManager * object_ptr; + std::string job_name; + }; + + struct thread_info_file + { + BL::JobsManager * object_ptr; + std::string file_name; + }; + + struct thread_info_new_job + { + BL::JobsManager * object_ptr; + int job_number; }; protected: @@ -71,8 +107,11 @@ namespace BL{ _jobs_map _jobs; _jobs_map::iterator _jobs_it; - omni_mutex _thread_mutex; - omni_mutex _thread_mutex_results; + // Mutex used for the jobs map + omni_mutex _thread_mutex_jobs_map; + + // To avoid two jobs with the same name + int _name_counter; }; } diff --git a/src/engine/BL_Observer.hxx b/src/engine/BL_Observer.hxx new file mode 100644 index 0000000..eb42870 --- /dev/null +++ b/src/engine/BL_Observer.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _BL_OBSERVER_HXX_ +#define _BL_OBSERVER_HXX_ + +#include + +namespace BL{ + + class Observer + { + public: + Observer() {}; + virtual ~Observer() {}; + + virtual void sendEvent(const std::string & action, + const std::string & event_name, + const std::string & job_name, + const std::string & data) = 0; + }; + +} + +#endif diff --git a/src/engine/BL_SALOMEServices.cxx b/src/engine/BL_SALOMEServices.cxx index 8f6a9d0..273c517 100644 --- a/src/engine/BL_SALOMEServices.cxx +++ b/src/engine/BL_SALOMEServices.cxx @@ -1,23 +1,38 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_SALOMEServices.hxx" +#include + +static std::ostream & +operator<<(std::ostream & os, const CORBA::Exception & e) +{ + CORBA::Any tmp; + tmp <<=e ; + CORBA::TypeCode_var tc = tmp.type(); + const char * p = tc->name (); + if (*p != '\0') + os << p; + else + os << tc->id(); + return os; +} BL::SALOMEServices::SALOMEServices() { @@ -26,10 +41,16 @@ BL::SALOMEServices::SALOMEServices() _salome_naming_service = NULL; _lcc = NULL; _state = false; + _manager = NULL; } -BL::SALOMEServices::~SALOMEServices() +BL::SALOMEServices::~SALOMEServices() {} + +void +BL::SALOMEServices::end() { + if (!CORBA::is_nil(_salome_launcher)) + _salome_launcher->removeObserver(_this()); if (_salome_naming_service) delete _salome_naming_service; if (_lcc) @@ -47,15 +68,17 @@ BL::SALOMEServices::initNS() if (CORBA::is_nil(_salome_launcher)) { - DEBTRACE("SALOME Launcher is not reachable!") + DEBMSG("SALOME Launcher is not reachable!") return_value = false; } + _salome_launcher->addObserver(_this()); + _remove_ref(); // POA will automatically destroy the object obj = _salome_naming_service->Resolve("/ResourcesManager"); _resources_manager = Engines::ResourcesManager::_narrow(obj); if (CORBA::is_nil(_resources_manager)) { - DEBTRACE("SALOME Resource Manager is not reachable !"); + DEBMSG("SALOME Resource Manager is not reachable !"); return_value = false; } @@ -64,107 +87,306 @@ BL::SALOMEServices::initNS() } std::list -BL::SALOMEServices::getMachineList() +BL::SALOMEServices::getResourceList() { - std::list machine_list; + std::list resource_list; if (_state) { - Engines::MachineParameters params; + Engines::ResourceParameters params; _lcc->preSet(params); - Engines::MachineList * machineList = _resources_manager->GetFittingResources(params); - for (int i = 0; i < machineList->length(); i++) + Engines::ResourceList * resourceList = NULL; + try + { + resourceList = _resources_manager->GetFittingResources(params); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in addResource ! " << ex.details.text.in()); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + } + if (resourceList) + { + for (int i = 0; i < resourceList->length(); i++) + { + const char* aResource = (*resourceList)[i]; + resource_list.push_back(aResource); + } + delete resourceList; + } + } + return resource_list; +} + +BL::ResourceDescr +BL::SALOMEServices::getResourceDescr(const std::string& name) +{ + Engines::ResourceDefinition * resource_definition = NULL; + BL::ResourceDescr resource_descr; + + try + { + resource_definition = _resources_manager-> GetResourceDefinition(name.c_str()); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in addResource ! " << ex.details.text.in()); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + } + + if(resource_definition) + { + resource_descr.name = resource_definition->name.in(); + resource_descr.hostname = resource_definition->hostname.in(); + resource_descr.protocol = resource_definition->protocol.in(); + resource_descr.username = resource_definition->username.in(); + resource_descr.applipath = resource_definition->applipath.in(); + for (int i = 0; i < resource_definition->componentList.length(); i++) { - const char* aMachine = (*machineList)[i]; - machine_list.push_back(aMachine); + resource_descr.componentList.push_back(resource_definition->componentList[i].in()); } + + resource_descr.OS = resource_definition->OS.in(); + resource_descr.mem_mb = resource_definition->mem_mb; + resource_descr.cpu_clock = resource_definition->cpu_clock; + resource_descr.nb_node = resource_definition->nb_node; + resource_descr.nb_proc_per_node = resource_definition->nb_proc_per_node; + resource_descr.batch = resource_definition->batch.in(); + resource_descr.mpiImpl = resource_definition->mpiImpl.in(); + resource_descr.iprotocol = resource_definition->iprotocol.in(); + resource_descr.is_cluster_head = resource_definition->is_cluster_head; + resource_descr.working_directory = resource_definition->working_directory.in(); + + delete resource_definition; + } + return resource_descr; +} + +void +BL::SALOMEServices::addResource(BL::ResourceDescr & new_resource) +{ + Engines::ResourceDefinition_var resource_definition = new Engines::ResourceDefinition; + + resource_definition->name = CORBA::string_dup(new_resource.name.c_str()); + resource_definition->hostname = CORBA::string_dup(new_resource.hostname.c_str()); + resource_definition->protocol = CORBA::string_dup(new_resource.protocol.c_str()); + resource_definition->username = CORBA::string_dup(new_resource.username.c_str()); + resource_definition->applipath = CORBA::string_dup(new_resource.applipath.c_str()); + + int i = 0; + std::list::iterator it = new_resource.componentList.begin(); + resource_definition->componentList.length(new_resource.componentList.size()); + for(; it != new_resource.componentList.end(); it++) + { + resource_definition->componentList[i] = CORBA::string_dup((*it).c_str()); + i++; } - return machine_list; + resource_definition->OS = CORBA::string_dup(new_resource.OS.c_str()); + resource_definition->mem_mb = new_resource.mem_mb; + resource_definition->cpu_clock = new_resource.cpu_clock; + resource_definition->nb_node = new_resource.nb_node; + resource_definition->nb_proc_per_node = new_resource.nb_proc_per_node; + resource_definition->batch = CORBA::string_dup(new_resource.batch.c_str()); + resource_definition->mpiImpl = CORBA::string_dup(new_resource.mpiImpl.c_str()); + resource_definition->iprotocol = CORBA::string_dup(new_resource.iprotocol.c_str()); + resource_definition->is_cluster_head = new_resource.is_cluster_head; + resource_definition->working_directory = CORBA::string_dup(new_resource.working_directory.c_str()); + + try + { + _resources_manager->AddResource(resource_definition, true, ""); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in addResource ! " << ex.details.text.in()); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + } } -std::string -BL::SALOMEServices::start_job(BL::Job * job) +void +BL::SALOMEServices::removeResource(const std::string & name) { - return start_yacs_job(job); + try + { + _resources_manager->RemoveResource(name.c_str(), true, ""); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in removeResource ! " << ex.details.text.in()); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + } } std::string -BL::SALOMEServices::start_yacs_job(BL::Job * job) +BL::SALOMEServices::create_job(BL::Job * job) { + DEBMSG("Begin of create_job"); std::string ret = ""; - // Prepare Arguments - const char * fileToExecute = job->getYACSFile().c_str(); + Engines::JobParameters_var job_parameters = new Engines::JobParameters; + + // Job type + if (job->getType() == BL::Job::COMMAND) + { + job_parameters->job_type = CORBA::string_dup("command"); + } + else if (job->getType() == BL::Job::YACS_SCHEMA) + { + job_parameters->job_type = CORBA::string_dup("yacs_file"); + } + else if (job->getType() == BL::Job::PYTHON_SALOME) + { + job_parameters->job_type = CORBA::string_dup("python_salome"); + } + + // Specific parameters + if (job->getType() == BL::Job::YACS_SCHEMA) + { + if (job->getDumpYACSState() > 0) + { + job_parameters->specific_parameters.length(job_parameters->specific_parameters.length() + 1); + std::ostringstream oss; + oss << job->getDumpYACSState(); + Engines::Parameter_var new_parameter = new Engines::Parameter; + new_parameter->name = CORBA::string_dup("EnableDumpYACS"); + new_parameter->value = CORBA::string_dup(oss.str().c_str()); + job_parameters->specific_parameters[job_parameters->specific_parameters.length() - 1] = new_parameter; + } + } + if (job->getLoadLevelerJobType() != "") + { + job_parameters->specific_parameters.length(job_parameters->specific_parameters.length() + 1); + Engines::Parameter_var new_parameter = new Engines::Parameter; + new_parameter->name = CORBA::string_dup("LoalLevelerJobType"); + new_parameter->value = CORBA::string_dup(job->getLoadLevelerJobType().c_str()); + job_parameters->specific_parameters[job_parameters->specific_parameters.length() - 1] = new_parameter; + } + // Files + job_parameters->job_name = CORBA::string_dup(job->getName().c_str()); + job_parameters->job_file = CORBA::string_dup(job->getJobFile().c_str()); + job_parameters->env_file = CORBA::string_dup(job->getEnvFile().c_str()); BL::Job::FilesParam files = job->getFilesParameters(); - Engines::FilesList_var filesToExport = new Engines::FilesList; - filesToExport->length(files.input_files_list.size()); std::list::iterator it; int i = 0; - for (it=files.input_files_list.begin() ; it != files.input_files_list.end(); it++) + int j = 0; + + job_parameters->in_files.length(files.input_files_list.size()); + for (it = files.input_files_list.begin() ; it != files.input_files_list.end(); it++) { - filesToExport[i] = CORBA::string_dup((*it).c_str()); + job_parameters->in_files[i] = CORBA::string_dup((*it).c_str()); i++; } - Engines::FilesList_var filesToImport = new Engines::FilesList; - filesToImport->length(files.output_files_list.size()); - i = 0; - for (it=files.output_files_list.begin() ; it != files.output_files_list.end(); it++) + + job_parameters->out_files.length(files.output_files_list.size()); + for (it = files.output_files_list.begin() ; it != files.output_files_list.end(); it++) { - filesToImport[i] = CORBA::string_dup((*it).c_str()); - i++; + job_parameters->out_files[j] = CORBA::string_dup((*it).c_str()); + j++; } + job_parameters->local_directory = CORBA::string_dup(""); + job_parameters->result_directory = CORBA::string_dup(files.result_directory.c_str()); BL::Job::BatchParam cpp_batch_params = job->getBatchParameters(); - Engines::BatchParameters_var batch_params = new Engines::BatchParameters; - batch_params->batch_directory = CORBA::string_dup(cpp_batch_params.batch_directory.c_str()); - batch_params->expected_during_time = CORBA::string_dup(cpp_batch_params.expected_during_time.c_str()); - batch_params->mem = CORBA::string_dup(cpp_batch_params.expected_memory.c_str()); - batch_params->nb_proc = cpp_batch_params.nb_proc; + job_parameters->work_directory = CORBA::string_dup(cpp_batch_params.batch_directory.c_str()); + + // Resource + job_parameters->maximum_duration = CORBA::string_dup(cpp_batch_params.maximum_duration.c_str()); + job_parameters->resource_required.name = CORBA::string_dup(job->getResource().c_str()); + job_parameters->resource_required.nb_proc = cpp_batch_params.nb_proc; + job_parameters->queue = CORBA::string_dup(job->getBatchQueue().c_str()); - Engines::MachineParameters_var machine = new Engines::MachineParameters; - machine->hostname = CORBA::string_dup(job->getMachine().c_str()); + // Memory + CORBA::Long memory; + std::string ram = cpp_batch_params.expected_memory.substr(0,cpp_batch_params.expected_memory.size()-2); + std::istringstream iss(ram); + iss >> memory; + std::string unity = cpp_batch_params.expected_memory.substr(cpp_batch_params.expected_memory.size()-2, 2); + if((unity.find("gb") != std::string::npos)) + memory = memory * 1024; + job_parameters->resource_required.mem_mb = memory; - // Start Job ! + // Create Job try { - int job_id = _salome_launcher->submitSalomeJob(fileToExecute, filesToExport, - filesToImport, batch_params, machine); + int job_id = _salome_launcher->createJob(job_parameters); job->setSalomeLauncherId(job_id); } catch (const SALOME::SALOME_Exception & ex) { - DEBTRACE("SALOME Exception in submitSalomeJob !"); + DEBMSG("SALOME Exception in createJob !"); ret = ex.details.text.in(); } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "SALOME System Exception - see logs"; + } return ret; } std::string -BL::SALOMEServices::refresh_job(BL::Job * job) +BL::SALOMEServices::start_job(BL::Job * job) { std::string ret = ""; + // Launch Job ! + try + { + _salome_launcher->launchJob(job->getSalomeLauncherId()); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in launchJob !"); + ret = ex.details.text.in(); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "SALOME System Exception - see logs"; + } + return ret; +} - Engines::MachineParameters_var machine = new Engines::MachineParameters; - machine->hostname = CORBA::string_dup(job->getMachine().c_str()); +std::string +BL::SALOMEServices::refresh_job(BL::Job * job) +{ + std::string ret = ""; // Refresh Job ! try { - CORBA::String_var result = _salome_launcher->queryJob(job->getSalomeLauncherId(), machine); - std::string res = result.in(); - if (res == "Running") - return "RUNNING"; - else if (res == "Done") - return "FINISHED"; - else - return result.in(); + CORBA::String_var result = _salome_launcher->getJobState(job->getSalomeLauncherId()); + ret = result.in(); } catch (const SALOME::SALOME_Exception & ex) { - DEBTRACE("SALOME Exception in refresh_job !"); + DEBMSG("SALOME Exception in getJobState !"); ret = ex.details.text.in(); } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "SALOME System Exception - see logs"; + } return ret; } @@ -172,30 +394,51 @@ std::string BL::SALOMEServices::delete_job(BL::Job * job) { std::string ret = ""; - - Engines::MachineParameters_var machine = new Engines::MachineParameters; - machine->hostname = CORBA::string_dup(job->getMachine().c_str()); - // Delete Job ! try { - _salome_launcher->deleteJob(job->getSalomeLauncherId(), machine); + _salome_launcher->removeJob(job->getSalomeLauncherId()); } catch (const SALOME::SALOME_Exception & ex) { - DEBTRACE("SALOME Exception in refresh_job !"); + DEBMSG("SALOME Exception in removeJob !"); ret = ex.details.text.in(); } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "SALOME System Exception - see logs"; + } return ret; } std::string -BL::SALOMEServices::get_results_job(BL::Job * job) +BL::SALOMEServices::stop_job(BL::Job * job) { std::string ret = ""; + try + { + _salome_launcher->stopJob(job->getSalomeLauncherId()); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in stopJob !"); + ret = ex.details.text.in(); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "SALOME System Exception - see logs"; + } + return ret; +} - Engines::MachineParameters_var machine = new Engines::MachineParameters; - machine->hostname = CORBA::string_dup(job->getMachine().c_str()); +std::string +BL::SALOMEServices::get_results_job(BL::Job * job) +{ + std::string ret = ""; BL::Job::FilesParam files = job->getFilesParameters(); CORBA::String_var directory = CORBA::string_dup(files.result_directory.c_str()); @@ -203,12 +446,182 @@ BL::SALOMEServices::get_results_job(BL::Job * job) // get job results ! try { - _salome_launcher->getResultsJob(directory, job->getSalomeLauncherId(), machine); + _salome_launcher->getJobResults(job->getSalomeLauncherId(), directory); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in refresh_job !"); + ret = ex.details.text.in(); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive SALOME System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "SALOME System Exception - see logs"; + } + return ret; +} + +std::string +BL::SALOMEServices::save_jobs(const std::string & file_name) +{ + CORBA::String_var file = CORBA::string_dup(file_name.c_str()); + std::string ret = ""; + try + { + _salome_launcher->saveJobs(file); } catch (const SALOME::SALOME_Exception & ex) { - DEBTRACE("SALOME Exception in refresh_job !"); + DEBMSG("SALOME Exception in saveJobs !"); ret = ex.details.text.in(); } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive CORBA System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "CORBA System Exception - see SALOME logs"; + } return ret; } + +std::string +BL::SALOMEServices::load_jobs(const std::string & file_name) +{ + CORBA::String_var file = CORBA::string_dup(file_name.c_str()); + std::string ret = ""; + try + { + _salome_launcher->loadJobs(file); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in loadJobs !"); + ret = ex.details.text.in(); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive CORBA System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "CORBA System Exception - see SALOME logs"; + } + return ret; +} + +void +BL::SALOMEServices::notify(const char* event_name, const char * event_data) +{ + DEBMSG("Launcher event received " << event_name << " " << event_data); + + std::string event(event_name); + std::string data(event_data); + + if (event == "SAVE_JOBS") + { + _manager->launcher_event_save_jobs(data); + } + else if (event == "LOAD_JOBS") + { + _manager->launcher_event_load_jobs(data); + } + else if (event == "NEW_JOB") + { + _manager->launcher_event_new_job(data); + } + else if (event == "REMOVE_JOB") + { + _manager->launcher_event_remove_job(data); + } + else if (event == "UPDATE_JOB_STATE") + { + _manager->launcher_event_update_job_state(data); + } + else + { + DEBMSG("Unkown launcher event received"); + } +} + +BL::Job * +BL::SALOMEServices::get_new_job(int job_number) +{ + DEBMSG("Start of BL::SALOMEServices::get_new_job"); + BL::Job * job_return = NULL; + Engines::JobParameters * job_parameters = NULL; + try + { + job_parameters = _salome_launcher->getJobParameters(job_number); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in saveJobs !"); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive CORBA System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + } + + if (job_parameters) + { + job_return = new BL::Job(); + job_return->setSalomeLauncherId(job_number); + + job_return->setName(job_parameters->job_name.in()); + job_return->setType(job_parameters->job_type.in()); + job_return->setJobFile(job_parameters->job_file.in()); + job_return->setEnvFile(job_parameters->env_file.in()); + job_return->setBatchQueue(job_parameters->queue.in()); + + BL::Job::FilesParam param; + param.result_directory = job_parameters->result_directory.in(); + for (CORBA::ULong i = 0; i < job_parameters->in_files.length(); i++) + param.input_files_list.push_back(job_parameters->in_files[i].in()); + for (CORBA::ULong i = 0; i < job_parameters->out_files.length(); i++) + param.output_files_list.push_back(job_parameters->out_files[i].in()); + job_return->setFilesParameters(param); + + BL::Job::BatchParam batch_param; + batch_param.batch_directory = job_parameters->work_directory.in(); + batch_param.maximum_duration = job_parameters->maximum_duration.in(); + batch_param.nb_proc = job_parameters->resource_required.nb_proc; + std::ostringstream mem_stream; + mem_stream << job_parameters->resource_required.mem_mb << "mb"; + batch_param.expected_memory = mem_stream.str(); + job_return->setBatchParameters(batch_param); + + job_return->setResource(job_parameters->resource_required.name.in()); + + // Specific parameters + for (CORBA::ULong i = 0; i < job_parameters->specific_parameters.length(); i++) + { + if (std::string(job_parameters->specific_parameters[i].name.in()) == "EnableDumpYACS") + { + std::string user_value = job_parameters->specific_parameters[i].value.in(); + std::istringstream iss(user_value); + int value; + iss >> value; + job_return->setDumpYACSState(value); + } + if (std::string(job_parameters->specific_parameters[i].name.in()) == "LoalLevelerJobType") + { + std::string user_value = job_parameters->specific_parameters[i].value.in(); + job_return->setLoadLevelerJobType(user_value); + } + } + + // Get current state + std::string result_job = job_return->setStringState(refresh_job(job_return)); + if (result_job != "RefreshError") {} + else + { + // Error in getting state + DEBMSG("Error in getting state of the new job!"); + delete job_return; + job_return = NULL; + } + delete job_parameters; + } + + return job_return; +} diff --git a/src/engine/BL_SALOMEServices.hxx b/src/engine/BL_SALOMEServices.hxx index f5e597d..f3500cc 100644 --- a/src/engine/BL_SALOMEServices.hxx +++ b/src/engine/BL_SALOMEServices.hxx @@ -1,55 +1,97 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_SALOMESERVICES_HXX_ #define _BL_SALOMESERVICES_HXX_ +#include "BL_Engine.hxx" #include "BL_Traces.hxx" #include "BL_Job.hxx" #include "SALOME_NamingService.hxx" #include "SALOME_LifeCycleCORBA.hxx" #include "SALOME_ContainerManager.hh" +#include "BL_JobsManager.hxx" #include #include #include +#include "JOBMANAGER_IDL.hh" + + namespace BL{ - class SALOMEServices + class JobsManager; + + struct BL_Engine_EXPORT ResourceDescr + { + std::string name; + std::string hostname; + std::string protocol; + std::string username; + std::string applipath; + std::list componentList; + + std::string OS; + unsigned int mem_mb; + unsigned int cpu_clock; + unsigned int nb_node; + unsigned int nb_proc_per_node; + std::string batch; + std::string mpiImpl; + std::string iprotocol; + + bool is_cluster_head; + std::string working_directory; + }; + + class BL_Engine_EXPORT SALOMEServices : + public POA_JOBMANAGER::LauncherObserver { public: SALOMEServices(); virtual ~SALOMEServices(); bool initNS(); + void end(); + + void set_manager(BL::JobsManager * manager) {_manager = manager;} + + std::list getResourceList(); + BL::ResourceDescr getResourceDescr(const std::string& name); + void addResource(BL::ResourceDescr & new_resource); + void removeResource(const std::string & name); - std::list getMachineList(); + std::string save_jobs(const std::string & file_name); + std::string load_jobs(const std::string & file_name); + std::string create_job(BL::Job * job); std::string start_job(BL::Job * job); std::string refresh_job(BL::Job * job); std::string delete_job(BL::Job * job); + std::string stop_job(BL::Job * job); std::string get_results_job(BL::Job * job); - protected: - std::string start_yacs_job(BL::Job * job); + BL::Job * get_new_job(int job_number); + + virtual void notify(const char* event_name, const char * event_data); private: CORBA::ORB_var _orb; @@ -58,6 +100,8 @@ namespace BL{ Engines::SalomeLauncher_var _salome_launcher; Engines::ResourcesManager_var _resources_manager; + BL::JobsManager * _manager; + bool _state; }; diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am new file mode 100644 index 0000000..98f4e2f --- /dev/null +++ b/src/engine/Makefile.am @@ -0,0 +1,37 @@ +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +libdir = $(prefix)/lib/salome + +lib_LTLIBRARIES = libBL_Engine.la + +libBL_Engine_la_SOURCES = BL_Engine.hxx BL_JobsManager.hxx BL_JobsManager.cxx \ + BL_Job.hxx BL_Job.cxx \ + BL_SALOMEServices.hxx BL_SALOMEServices.cxx \ + BL_Observer.hxx + +libBL_Engine_la_CXXFLAGS = -I$(top_srcdir)/src/bases \ + $(OMNIORB_INCLUDES) $(OMNIORB_CXXFLAGS) \ + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I../../idl + +libBL_Engine_la_LIBADD = $(top_builddir)/src/bases/libBL_Bases.la $(top_builddir)/idl/libJOBMANAGER_IDL.la $(OMNIORB_LIBS) \ + $(KERNEL_LDFLAGS) -lSalomeIDLKernel -lSalomeNS -lSalomeLifeCycleCORBA \ + @OMNIORB_LIBS@ + diff --git a/src/genericgui/BL_Buttons.cxx b/src/genericgui/BL_Buttons.cxx index b13f7df..7b2ee7a 100644 --- a/src/genericgui/BL_Buttons.cxx +++ b/src/genericgui/BL_Buttons.cxx @@ -1,51 +1,68 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_Buttons.hxx" -BL::Buttons::Buttons(QWidget * parent) : QGroupBox(parent) +BL::Buttons::Buttons(QWidget * parent) : QWidget(parent) { DEBTRACE("Creating BL::Buttons"); - setTitle("Actions"); + _create_button = new QPushButton("Create", this); + _start_button = new QPushButton("Start", this); + _get_results_button = new QPushButton("Get Results", this); - _create_button = new QPushButton("Create Job", this); - _start_button = new QPushButton("Start Job", this); - _delete_button = new QPushButton("Delete Job", this); - _get_results_button = new QPushButton("Get Job Results", this); - _refresh_button = new QPushButton("Refresh Jobs", this); + _stop_button = new QPushButton("Stop", this); + _delete_button = new QPushButton("Delete", this); + _restart_button = new QPushButton("Restart", this); + _edit_clone_button = new QPushButton("Edit/Clone", this); + + _refresh_button = new QPushButton("Refresh Jobs", this); + + QGroupBox * main_buttons = new QGroupBox(this); + main_buttons->setTitle("Main"); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addWidget(_create_button); mainLayout->addWidget(_start_button); - mainLayout->addWidget(_delete_button); mainLayout->addWidget(_get_results_button); - mainLayout->addWidget(_refresh_button); - mainLayout->setSpacing(0); // Space between buttons - - setLayout(mainLayout); - - //QSizePolicy poli; - //poli.setControlType(QSizePolicy::PushButton); - //poli.setVerticalPolicy(QSizePolicy::Fixed); - //poli.setHorizontalPolicy(QSizePolicy::Fixed); - //setSizePolicy(poli); + main_buttons->setLayout(mainLayout); + + QGroupBox * manage_buttons = new QGroupBox(this); + manage_buttons->setTitle("Management"); + QHBoxLayout *manageLayout = new QHBoxLayout; + manageLayout->addWidget(_stop_button); + manageLayout->addWidget(_delete_button); + manageLayout->addWidget(_restart_button); + manageLayout->addWidget(_edit_clone_button); + manage_buttons->setLayout(manageLayout); + + QGroupBox * refresh_buttons = new QGroupBox(this); + refresh_buttons->setTitle("Refresh"); + QHBoxLayout *refreshLayout = new QHBoxLayout; + refreshLayout->addWidget(_refresh_button); + refresh_buttons->setLayout(refreshLayout); + + QGridLayout * gridLayout = new QGridLayout; + gridLayout->addWidget(main_buttons, 0 ,0); + gridLayout->addWidget(manage_buttons, 0 ,1); + gridLayout->addWidget(refresh_buttons, 0 , 2); + setLayout(gridLayout); } BL::Buttons::~Buttons() @@ -59,12 +76,30 @@ BL::Buttons::setCreateButtonSlot(QObject * receiver, const char * name) connect(_create_button, SIGNAL(clicked()), receiver, name); } +void +BL::Buttons::setEditCloneButtonSlot(QObject * receiver, const char * name) +{ + connect(_edit_clone_button, SIGNAL(clicked()), receiver, name); +} + void BL::Buttons::setStartButtonSlot(QObject * receiver, const char * name) { connect(_start_button, SIGNAL(clicked()), receiver, name); } +void +BL::Buttons::setReStartButtonSlot(QObject * receiver, const char * name) +{ + connect(_restart_button, SIGNAL(clicked()), receiver, name); +} + +void +BL::Buttons::setStopButtonSlot(QObject * receiver, const char * name) +{ + connect(_stop_button, SIGNAL(clicked()), receiver, name); +} + void BL::Buttons::setDeleteButtonSlot(QObject * receiver, const char * name) { @@ -83,6 +118,18 @@ BL::Buttons::setGetResultsButtonSlot(QObject * receiver, const char * name) connect(_get_results_button, SIGNAL(clicked()), receiver, name); } +void +BL::Buttons::enable_edit_clone_button() +{ + _edit_clone_button->setEnabled(true); +} + +void +BL::Buttons::disable_edit_clone_button() +{ + _edit_clone_button->setEnabled(false); +} + void BL::Buttons::enable_start_button() { @@ -95,6 +142,30 @@ BL::Buttons::disable_start_button() _start_button->setEnabled(false); } +void +BL::Buttons::enable_restart_button() +{ + _restart_button->setEnabled(true); +} + +void +BL::Buttons::disable_restart_button() +{ + _restart_button->setEnabled(false); +} + +void +BL::Buttons::enable_stop_button() +{ + _stop_button->setEnabled(true); +} + +void +BL::Buttons::disable_stop_button() +{ + _stop_button->setEnabled(false); +} + void BL::Buttons::enable_delete_button() { diff --git a/src/genericgui/BL_Buttons.hxx b/src/genericgui/BL_Buttons.hxx index 866e96d..27d92cf 100644 --- a/src/genericgui/BL_Buttons.hxx +++ b/src/genericgui/BL_Buttons.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_BUTTONS_HXX_ @@ -26,7 +26,7 @@ namespace BL { - class Buttons: public QGroupBox + class Buttons: public QWidget { Q_OBJECT @@ -35,14 +35,26 @@ namespace BL virtual ~Buttons(); void setCreateButtonSlot(QObject * receiver, const char * name); + void setEditCloneButtonSlot(QObject * receiver, const char * name); void setStartButtonSlot(QObject * receiver, const char * name); + void setReStartButtonSlot(QObject * receiver, const char * name); + void setStopButtonSlot(QObject * receiver, const char * name); void setDeleteButtonSlot(QObject * receiver, const char * name); void setRefreshButtonSlot(QObject * receiver, const char * name); void setGetResultsButtonSlot(QObject * receiver, const char * name); + void enable_edit_clone_button(); + void disable_edit_clone_button(); + void enable_start_button(); void disable_start_button(); + void enable_restart_button(); + void disable_restart_button(); + + void enable_stop_button(); + void disable_stop_button(); + void enable_delete_button(); void disable_delete_button(); @@ -51,10 +63,13 @@ namespace BL protected: QPushButton * _create_button; + QPushButton * _edit_clone_button; QPushButton * _start_button; + QPushButton * _restart_button; QPushButton * _delete_button; QPushButton * _get_results_button; QPushButton * _refresh_button; + QPushButton * _stop_button; }; } diff --git a/src/genericgui/BL_CreateJobWizard.cxx b/src/genericgui/BL_CreateJobWizard.cxx index 99ae4ee..8b24f65 100644 --- a/src/genericgui/BL_CreateJobWizard.cxx +++ b/src/genericgui/BL_CreateJobWizard.cxx @@ -1,23 +1,35 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_CreateJobWizard.hxx" +#include "BL_JobsManager_QT.hxx" +#ifndef WNT +#include +#include +#endif +#include +#include +#include + +#ifdef WNT +#undef ERROR +#endif BL::CreateJobWizard::CreateJobWizard(BL::JobsManager_QT * jobs_manager, BL::SALOMEServices * salome_services) { @@ -25,30 +37,42 @@ BL::CreateJobWizard::CreateJobWizard(BL::JobsManager_QT * jobs_manager, BL::SALO BL_ASSERT(jobs_manager); BL_ASSERT(salome_services); _jobs_manager = jobs_manager; + _salome_services = salome_services; job_name = ""; yacs_file = ""; command = ""; + python_salome_file = ""; + env_file = ""; batch_directory = ""; - expected_during_time = ""; + maximum_duration = ""; expected_memory = ""; nb_proc = 1; result_directory = ""; - machine_choosed = ""; + resource_choosed = ""; + batch_queue = ""; start_job = false; + dump_yacs_state = -1; + ll_jobtype = ""; - setOptions(QWizard::IndependentPages | QWizard::NoBackButtonOnStartPage); + setOptions(QWizard::NoBackButtonOnStartPage); - setPage(Page_JobName, new BL::CreateJobWizard::JobNamePage(this, _jobs_manager)); - setPage(Page_YACSSchema, new BL::YACSSchemaPage(this)); - setPage(Page_BatchParameters, new BL::BatchParametersPage(this)); + // Common pages + _job_name_page = new BL::JobNamePage(this, _jobs_manager); + + setPage(Page_JobName, _job_name_page); + setPage(Page_BatchParameters, new BL::BatchParametersPage(this, salome_services)); setPage(Page_Files, new BL::FilesPage(this)); - setPage(Page_Command_Main_Definitions, new BL::CreateJobWizard::CommandMainPage(this)); - setPage(Page_Machine, new BL::MachinePage(this, salome_services)); - setPage(Page_Conclusion, new BL::CreateJobWizard::ConclusionPage(this)); + setPage(Page_Resource, new BL::ResourcePage(this, salome_services)); + setPage(Page_Conclusion, new BL::ConclusionPage(this)); + + // Specific pages + setPage(Page_YACSSchema, new BL::YACSSchemaPage(this)); + setPage(Page_Command_Main_Definitions, new BL::CommandMainPage(this)); + setPage(Page_PythonSalome_Main_Definitions, new BL::PythonSalomeMainPage(this)); setWindowTitle("Create Job Wizard"); connect(this, SIGNAL(finished(int)), this, SLOT(end(int))); @@ -59,6 +83,102 @@ BL::CreateJobWizard::~CreateJobWizard() DEBTRACE("Destroying BL::CreateJobWizard"); } +void +BL::CreateJobWizard::clone(const std::string & name) +{ + if (_jobs_manager->job_already_exist(name) == true) + { + BL::Job * job = _jobs_manager->getJob(name); + + // We can only edit a job in CREATED, ERROR, FAILED and NOT_CREATED + if (job->getState() == BL::Job::CREATED || + job->getState() == BL::Job::ERROR || + job->getState() == BL::Job::FAILED || + job->getState() == BL::Job::NOT_CREATED) + { + setField("job_name", QString(name.c_str())); + _job_name_page->_check_name = false; + } + + if (job->getType() == BL::Job::YACS_SCHEMA) + { + setField("yacs_file", QString(job->getJobFile().c_str())); + _job_name_page->_yacs_schema_button->click(); + setField("env_yacs_file", QString(job->getEnvFile().c_str())); + if (job->getDumpYACSState() != -1) + { + QString value; + value.setNum(job->getDumpYACSState()); + setField("dump_yacs_state", value); + } + } + else if (job->getType() == BL::Job::COMMAND) + { + setField("command", QString(job->getJobFile().c_str())); + _job_name_page->_command_button->click(); + setField("env_command_file", QString(job->getEnvFile().c_str())); + } + else if (job->getType() == BL::Job::PYTHON_SALOME) + { + setField("PythonSalome", QString(job->getJobFile().c_str())); + _job_name_page->_python_salome_button->click(); + setField("env_PythonSalome_file", QString(job->getEnvFile().c_str())); + } + + BL::Job::BatchParam batch_params = job->getBatchParameters(); + setField("batch_directory", QString(batch_params.batch_directory.c_str())); + QString proc_value; + proc_value.setNum(batch_params.nb_proc); + setField("proc_value", proc_value); + + if (batch_params.maximum_duration == "") + { + setField("duration_hour", 0); + setField("duration_min", 0); + } + else + { + std::size_t pos = batch_params.maximum_duration.find(":"); + std::string hour_str = batch_params.maximum_duration.substr(0, pos); + int hour; + std::istringstream iss_hour(hour_str); + iss_hour >> hour; + setField("duration_hour", hour); + + std::string min_str = batch_params.maximum_duration.substr(pos + 1, batch_params.maximum_duration.npos); + int min; + std::istringstream iss_min(min_str); + iss_min >> min; + setField("duration_min", min); + } + + std::string mem_type = batch_params.expected_memory.substr(batch_params.expected_memory.size() - 2, 2); + if (mem_type == "mb") + setField("mem_type", 0); + else + setField("mem_type", 1); + std::string mem_value = batch_params.expected_memory.substr(0, batch_params.expected_memory.find(mem_type)); + int mem_val; + std::istringstream iss_mem(mem_value); + iss_mem >> mem_val; + setField("mem_value", mem_val); + + BL::Job::FilesParam files_params = job->getFilesParameters(); + + std::list::iterator it = files_params.input_files_list.begin(); + for (; it != files_params.input_files_list.end(); it++) + _input_files_list->addItem(QString((*it).c_str())); + it = files_params.output_files_list.begin(); + for (; it != files_params.output_files_list.end(); it++) + _output_files_list->addItem(QString((*it).c_str())); + + setField("result_directory", QString(files_params.result_directory.c_str())); + setField("resource_choosed", QString(job->getResource().c_str())); + setField("batch_queue", QString(job->getBatchQueue().c_str())); + setField("ll_jobtype", QString(job->getLoadLevelerJobType().c_str())); + } +} + void BL::CreateJobWizard::setFilesList(QListWidget * input_files_list, QListWidget * output_files_list) { @@ -79,26 +199,47 @@ BL::CreateJobWizard::end(int result) // YACS Schema Panel QString f_yacs_file = field("yacs_file").toString(); yacs_file = f_yacs_file.toStdString(); - + dump_yacs_state = field("dump_yacs_state").toInt(); + // Command Panel QString f_command = field("command").toString(); command = f_command.toStdString(); - + + // Command Panel + QString f_python_salome_file = field("PythonSalome").toString(); + python_salome_file = f_python_salome_file.toStdString(); + + QString f_env_file; + if (yacs_file != "") + f_env_file = field("env_yacs_file").toString(); + else if (command != "") + f_env_file = field("env_command_file").toString(); + else if (python_salome_file != "") + f_env_file = field("env_PythonSalome_file").toString(); + env_file = f_env_file.toStdString(); + // Batch Panel QString f_batch_directory = field("batch_directory").toString(); batch_directory = f_batch_directory.toStdString(); QString time_hour; QString time_min; - if (field("during_time_hour").toInt() < 10) - time_hour = "0" + field("during_time_hour").toString(); - else - time_hour = field("during_time_hour").toString(); - if (field("during_time_min").toInt() < 10) - time_min = "0" + field("during_time_min").toString(); + if(field("duration_hour").toInt() == 0 && field("duration_min").toInt() == 0) + { + maximum_duration = ""; + } else - time_min = field("during_time_min").toString(); - expected_during_time = time_hour.toStdString() + ":" + time_min.toStdString() + ":00"; + { + if (field("duration_hour").toInt() < 10) + time_hour = "0" + field("duration_hour").toString(); + else + time_hour = field("duration_hour").toString(); + if (field("duration_min").toInt() < 10) + time_min = "0" + field("duration_min").toString(); + else + time_min = field("duration_min").toString(); + maximum_duration = time_hour.toStdString() + ":" + time_min.toStdString(); + } QString mem = field("mem_value").toString(); int mem_type_i = field("mem_type").toInt(); @@ -125,19 +266,37 @@ BL::CreateJobWizard::end(int result) output_files_list.push_back(item_text.toStdString()); } - // Machine list - QString f_machine_choosed = field("machine_choosed").toString(); - machine_choosed = f_machine_choosed.toStdString(); + // Resource list + QString f_resource_choosed = field("resource_choosed").toString(); + resource_choosed = f_resource_choosed.toStdString(); + + // Batch Queue + QString f_batch_queue = field("batch_queue").toString(); + batch_queue = f_batch_queue.toStdString(); + + // LoadLeveler JobType + BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed); + std::string batch = resource_descr.batch.c_str(); + if (batch == "ll") + { + QString f_ll_jobtype = field("ll_jobtype").toString(); + ll_jobtype = f_ll_jobtype.toStdString(); + } + else + { + ll_jobtype = ""; + } start_job = field("start_job").toBool(); } } // Job Name Page -BL::CreateJobWizard::JobNamePage::JobNamePage(QWidget * parent, BL::JobsManager_QT * jobs_manager) +BL::JobNamePage::JobNamePage(QWidget * parent, BL::JobsManager_QT * jobs_manager) : QWizardPage(parent) { _jobs_manager = jobs_manager; + _check_name = true; setTitle("Create a new job"); QLabel *label = new QLabel("Enter Job name, you cannot add two jobs with the same name"); @@ -147,16 +306,26 @@ BL::CreateJobWizard::JobNamePage::JobNamePage(QWidget * parent, BL::JobsManager_ registerField("job_name", _nameLineEdit); QLabel * label_type = new QLabel("Choose type of batch job:"); - QGroupBox *groupBox = new QGroupBox(); + QGroupBox *groupBox = new QGroupBox("Type of job"); _yacs_schema_button = new QRadioButton(tr("YACS Schema")); _yacs_schema_button->setChecked(true); - QRadioButton *radio2 = new QRadioButton(tr("Command")); + _command_button = new QRadioButton(tr("Command")); + _python_salome_button = new QRadioButton(tr("Python script in SALOME")); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(_yacs_schema_button); - vbox->addWidget(radio2); + vbox->addWidget(_command_button); + vbox->addWidget(_python_salome_button); vbox->addStretch(1); groupBox->setLayout(vbox); + QGroupBox * explanationBox = new QGroupBox("Explanation"); + QVBoxLayout *explanationvbox = new QVBoxLayout; + _explanation = new QLabel(); + _explanation->setWordWrap(true); + explanationvbox->addWidget(_explanation); + explanationvbox->addStretch(1); + explanationBox->setLayout(explanationvbox); + // Layouts QVBoxLayout * main_layout = new QVBoxLayout; main_layout->addWidget(label); @@ -166,16 +335,45 @@ BL::CreateJobWizard::JobNamePage::JobNamePage(QWidget * parent, BL::JobsManager_ main_layout->insertLayout(-1, layout); layout->addWidget(label_type, 2, 0); layout->addWidget(groupBox, 3, 0, 1, -1); + layout->addWidget(explanationBox, 4, 0, 1, -1); setLayout(main_layout); + + connect(_yacs_schema_button, SIGNAL(clicked(bool)), this, SLOT(yacs_schema_button(bool))); + connect(_command_button, SIGNAL(clicked(bool)), this, SLOT(command_button(bool))); + connect(_python_salome_button, SIGNAL(clicked(bool)), this, SLOT(python_salome_button(bool))); + + // Default button + yacs_schema_button(true); } -BL::CreateJobWizard::JobNamePage::~JobNamePage() +BL::JobNamePage::~JobNamePage() {} +void +BL::JobNamePage::yacs_schema_button(bool checked) +{ + if (checked) + _explanation->setText("This job permits to launch a YACS schema into a SALOME application"); +} + +void +BL::JobNamePage::command_button(bool checked) +{ + if (checked) + _explanation->setText("This job permits to launch a script into a distributed resource. This script is not launched into a SALOME application"); +} + +void +BL::JobNamePage::python_salome_button(bool checked) +{ + if (checked) + _explanation->setText("This job permits to launch a python script into a SALOME application"); +} + bool -BL::CreateJobWizard::JobNamePage::validatePage() +BL::JobNamePage::validatePage() { - DEBTRACE("Calling validatePage of BL::CreateJobWizard::JobNamePage"); + DEBTRACE("Calling validatePage of BL::JobNamePage"); bool return_value; QString job_name = field("job_name").toString(); @@ -188,7 +386,7 @@ BL::CreateJobWizard::JobNamePage::validatePage() // Check if job name already exists else { - if (_jobs_manager->job_already_exist(job_name.toStdString()) == false) + if (_jobs_manager->job_already_exist(job_name.toStdString()) == false || _check_name == false) { return_value = true; } @@ -204,42 +402,68 @@ BL::CreateJobWizard::JobNamePage::validatePage() return return_value; } -int -BL::CreateJobWizard::JobNamePage::nextId() const +int +BL::JobNamePage::nextId() const { - if (_yacs_schema_button->isChecked()) + if (_yacs_schema_button->isChecked()) { return BL::CreateJobWizard::Page_YACSSchema; } - else + else if (_command_button->isChecked()) { return BL::CreateJobWizard::Page_Command_Main_Definitions; } + else + { + return BL::CreateJobWizard::Page_PythonSalome_Main_Definitions; + } } BL::YACSSchemaPage::YACSSchemaPage(QWidget * parent) : QWizardPage(parent) { - setTitle("Choose YACS Schema"); + setTitle("Configure YACS Execution"); - QLabel *label = new QLabel("In this step you have to choose what YACS Schema you want to execute"); + QLabel *label = new QLabel("In this step you have to configure your YACS execution"); label->setWordWrap(true); - _yacs_file_button = new QPushButton(tr("Choose YACS Schema file")); - _yacs_file_button->show(); - connect(_yacs_file_button, SIGNAL(clicked()), this, SLOT(choose_file())); - + QGroupBox * files_param_box = new QGroupBox("YACS job files"); + QPushButton * yacs_file_button = new QPushButton(tr("Choose YACS Schema file")); + connect(yacs_file_button, SIGNAL(clicked()), this, SLOT(choose_file())); _yacs_file_text = new QLineEdit(this); _yacs_file_text->setText(""); registerField("yacs_file", _yacs_file_text); _yacs_file_text->setReadOnly(true); + QPushButton * command_env_file_button = new QPushButton(tr("Choose an environnement file")); + connect(command_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file())); + _line_env_file = new QLineEdit(this); + registerField("env_yacs_file", _line_env_file); + _line_env_file->setReadOnly(true); + QGridLayout * files_layout = new QGridLayout; + files_layout->addWidget(yacs_file_button, 0, 0); + files_layout->addWidget(_yacs_file_text, 0, 1); + files_layout->addWidget(command_env_file_button, 1, 0); + files_layout->addWidget(_line_env_file, 1, 1); + files_param_box->setLayout(files_layout); + + QGroupBox * spec_param_box = new QGroupBox("YACS specific parameters"); + QLabel * label_dump = new QLabel("Dump YACS state each secs (0 disable this feature)"); + QLabel * label_dump_warning = new QLabel("(WARNING: can only be used with SALOME >= 6.3.0)"); + QSpinBox * spin_dump = new QSpinBox(this); + spin_dump->setMinimum(0); + spin_dump->setMaximum(1000000); + registerField("dump_yacs_state", spin_dump); + QGridLayout * specific_layout = new QGridLayout; + specific_layout->addWidget(label_dump, 0, 0); + specific_layout->addWidget(spin_dump, 0, 1); + specific_layout->addWidget(label_dump_warning, 1, 0); + spec_param_box->setLayout(specific_layout); QVBoxLayout * main_layout = new QVBoxLayout; main_layout->addWidget(label); - QGridLayout *layout = new QGridLayout; - layout->addWidget(_yacs_file_button, 0, 0); - layout->addWidget(_yacs_file_text, 0, 1); - main_layout->insertLayout(-1, layout); + main_layout->addWidget(files_param_box); + main_layout->addWidget(spec_param_box); + setLayout(main_layout); }; @@ -267,20 +491,32 @@ void BL::YACSSchemaPage::choose_file() { QString yacs_file = QFileDialog::getOpenFileName(this, - tr("Open YACS files"), "", - tr("XML (*.xml);;All Files (*)")); + tr("Open YACS files"), "", + tr("XML (*.xml);;All Files (*)")); _yacs_file_text->setReadOnly(false); _yacs_file_text->setText(yacs_file); _yacs_file_text->setReadOnly(true); } +void +BL::YACSSchemaPage::choose_env_file() +{ + QString env_file = QFileDialog::getOpenFileName(this, + tr("Open environnement file"), "", + tr("sh (*.sh);;All Files (*)")); + _line_env_file->setReadOnly(false); + _line_env_file->setText(env_file); + _line_env_file->setReadOnly(true); +} + + int BL::YACSSchemaPage::nextId() const { - return BL::CreateJobWizard::Page_BatchParameters; + return BL::CreateJobWizard::Page_Resource; } -BL::CreateJobWizard::CommandMainPage::CommandMainPage(QWidget * parent) +BL::CommandMainPage::CommandMainPage(QWidget * parent) : QWizardPage(parent) { setTitle("Define command job"); @@ -288,13 +524,23 @@ BL::CreateJobWizard::CommandMainPage::CommandMainPage(QWidget * parent) label->setWordWrap(true); // command - QLabel * label_command = new QLabel("Command: "); - QLineEdit * line_command = new QLineEdit(this); - registerField("command", line_command); + QPushButton * command_file_button = new QPushButton(tr("Choose a command file")); + connect(command_file_button, SIGNAL(clicked()), this, SLOT(choose_command_file())); + _line_command = new QLineEdit(this); + registerField("command", _line_command); + _line_command->setReadOnly(true); + + QPushButton * command_env_file_button = new QPushButton(tr("Choose an environnement file")); + connect(command_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file())); + _line_env_file = new QLineEdit(this); + registerField("env_command_file", _line_env_file); + _line_env_file->setReadOnly(true); QGridLayout *layout = new QGridLayout; - layout->addWidget(label_command, 0, 0); - layout->addWidget(line_command, 0, 1); + layout->addWidget(command_file_button, 0, 0); + layout->addWidget(_line_command, 0, 1); + layout->addWidget(command_env_file_button, 1, 0); + layout->addWidget(_line_env_file, 1, 1); QVBoxLayout * main_layout = new QVBoxLayout; main_layout->addWidget(label); @@ -302,11 +548,33 @@ BL::CreateJobWizard::CommandMainPage::CommandMainPage(QWidget * parent) setLayout(main_layout); }; -BL::CreateJobWizard::CommandMainPage::~CommandMainPage() +BL::CommandMainPage::~CommandMainPage() {} +void +BL::CommandMainPage::choose_command_file() +{ + QString command_file = QFileDialog::getOpenFileName(this, + tr("Open command file"), "", + tr("sh (*.sh);;All Files (*)")); + _line_command->setReadOnly(false); + _line_command->setText(command_file); + _line_command->setReadOnly(true); +} + +void +BL::CommandMainPage::choose_env_file() +{ + QString env_file = QFileDialog::getOpenFileName(this, + tr("Open environnement file"), "", + tr("sh (*.sh);;All Files (*)")); + _line_env_file->setReadOnly(false); + _line_env_file->setText(env_file); + _line_env_file->setReadOnly(true); +} + bool -BL::CreateJobWizard::CommandMainPage::validatePage() +BL::CommandMainPage::validatePage() { QString command = field("command").toString(); if (command == "") @@ -319,15 +587,18 @@ BL::CreateJobWizard::CommandMainPage::validatePage() } int -BL::CreateJobWizard::CommandMainPage::nextId() const +BL::CommandMainPage::nextId() const { - return BL::CreateJobWizard::Page_BatchParameters; + return BL::CreateJobWizard::Page_Resource; } -BL::BatchParametersPage::BatchParametersPage(QWidget * parent) +BL::BatchParametersPage::BatchParametersPage(QWidget * parent, BL::SALOMEServices * salome_services) : QWizardPage(parent) { setTitle("Enter Batch Parameters"); + resource_choosed = ""; + + _salome_services = salome_services; QLabel *label = new QLabel("In this step you define the parameters of your job"); label->setWordWrap(true); @@ -335,22 +606,22 @@ BL::BatchParametersPage::BatchParametersPage(QWidget * parent) main_layout->addWidget(label); // batch_directory - QLabel * label_directory = new QLabel("Batch directory: "); + QLabel * label_directory = new QLabel("Remote work directory: "); QLineEdit * line_directory = new QLineEdit(this); registerField("batch_directory", line_directory); // exected during time - QLabel * label_during_time = new QLabel("Expected during time: "); - QSpinBox * spin_during_time_hour = new QSpinBox(this); - QLabel * label_during_time_hour = new QLabel("Hours"); - spin_during_time_hour->setMinimum(0); - spin_during_time_hour->setMaximum(1000000); - registerField("during_time_hour", spin_during_time_hour); - QSpinBox * spin_during_time_min = new QSpinBox(this); - QLabel * label_during_time_min = new QLabel("Minutes"); - spin_during_time_min->setMinimum(0); - spin_during_time_min->setMaximum(59); - registerField("during_time_min", spin_during_time_min); + QLabel * label_duration = new QLabel("Maximum during time: "); + QSpinBox * spin_duration_hour = new QSpinBox(this); + QLabel * label_duration_hour = new QLabel("Hours"); + spin_duration_hour->setMinimum(0); + spin_duration_hour->setMaximum(1000000); + registerField("duration_hour", spin_duration_hour); + QSpinBox * spin_duration_min = new QSpinBox(this); + QLabel * label_duration_min = new QLabel("Minutes"); + spin_duration_min->setMinimum(0); + spin_duration_min->setMaximum(59); + registerField("duration_min", spin_duration_min); // memory QLabel * label_memory = new QLabel("Memory per nodes expected: "); @@ -374,11 +645,11 @@ BL::BatchParametersPage::BatchParametersPage(QWidget * parent) QGridLayout *layout = new QGridLayout; layout->addWidget(label_directory, 0, 0); layout->addWidget(line_directory, 0, 1, 1, -1); - layout->addWidget(label_during_time, 1, 0); - layout->addWidget(spin_during_time_hour, 1, 1); - layout->addWidget(label_during_time_hour, 1, 2); - layout->addWidget(spin_during_time_min, 1, 3); - layout->addWidget(label_during_time_min, 1, 4); + layout->addWidget(label_duration, 1, 0); + layout->addWidget(spin_duration_hour, 1, 1); + layout->addWidget(label_duration_hour, 1, 2); + layout->addWidget(spin_duration_min, 1, 3); + layout->addWidget(label_duration_min, 1, 4); layout->addWidget(label_memory, 2, 0); layout->addWidget(spin_memory, 2, 1); layout->addWidget(combo_memory, 2, 2); @@ -393,6 +664,37 @@ BL::BatchParametersPage::BatchParametersPage(QWidget * parent) BL::BatchParametersPage::~BatchParametersPage() {} +void BL::BatchParametersPage::cleanupPage() {} + +void +BL::BatchParametersPage::initializePage() +{ + QString f_resource_choosed = field("resource_choosed").toString(); + if (f_resource_choosed != resource_choosed) + { + resource_choosed = f_resource_choosed; + // If choosed resource has a working_directory set + // Generates a default remote working directory + BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed.toStdString()); + QString res_work_dir = resource_descr.working_directory.c_str(); + if (res_work_dir != "") + { + time_t rawtime; + time(&rawtime); + std::string launch_date = ctime(&rawtime); + for (int i = 0; i < launch_date.size(); i++) + if (launch_date[i] == '/' || + launch_date[i] == '-' || + launch_date[i] == ':' || + launch_date[i] == ' ') + launch_date[i] = '_'; + launch_date.erase(--launch_date.end()); // Last caracter is a \n + QString date = launch_date.c_str(); + setField("batch_directory", res_work_dir + "/" + date); + } + } +} + bool BL::BatchParametersPage::validatePage() { @@ -403,14 +705,6 @@ BL::BatchParametersPage::validatePage() return false; } - int time_hour = field("during_time_hour").toInt(); - int time_min = field("during_time_min").toInt(); - if (time_hour == 0 and time_min == 0) - { - QMessageBox::warning(NULL, "Time Error", "Please enter an expected during time"); - return false; - } - int mem = field("mem_value").toInt(); if (mem == 0) { @@ -469,16 +763,32 @@ BL::FilesPage::FilesPage(BL::CreateJobWizard * parent) connect(_output_files_list, SIGNAL(itemSelectionChanged()), this, SLOT(output_itemSelectionChanged())); // Results Directory - QLabel * label_result_directory = new QLabel("Result directory: "); - QLineEdit * result_directory = new QLineEdit(this); - registerField("result_directory", result_directory); + QPushButton * button_result = new QPushButton("Local Result directory"); + connect(button_result, SIGNAL(clicked()), this, SLOT(choose_local_directory())); + _result_directory = new QLineEdit(this); + + // Default result directory is home directory (if we found it) + // First try -> HOME +#ifdef WNT + _result_directory->setText(getenv("HOME")); +#else + if (getenv("HOME")) + _result_directory->setText(getenv("HOME")); + else { + // Second try -> getpwuid + struct passwd * pass_struct = getpwuid(getuid()); + if (pass_struct) + _result_directory->setText(pass_struct->pw_dir); + } +#endif + registerField("result_directory", _result_directory); QGridLayout * output_box = new QGridLayout; output_box->addWidget(_output_files_button, 0, 0); output_box->addWidget(_remove_output_files_button, 0, 1); output_box->addWidget(_output_files_list, 1, 0, 1, -1); - output_box->addWidget(label_result_directory, 2, 0); - output_box->addWidget(result_directory, 2, 1, 1, -1); + output_box->addWidget(button_result, 2, 0); + output_box->addWidget(_result_directory, 2, 1, 1, -1); output_group_box->setLayout(output_box); QVBoxLayout * main_layout = new QVBoxLayout; @@ -508,18 +818,12 @@ BL::FilesPage::validatePage() } } - if (result_directory == "" and _output_files_list->count() != 0) + if (result_directory == "" && _output_files_list->count() != 0) { QMessageBox::warning(NULL, "Result Directory Error", "Please enter a result directory or remove output files"); return false; } - if (result_directory != "" and _output_files_list->count() == 0) - { - QMessageBox::warning(NULL, "Result Error", "Please add output files or erase result directory"); - return false; - } - return true; } @@ -527,8 +831,8 @@ void BL::FilesPage::choose_input_files() { QStringList files = QFileDialog::getOpenFileNames(this, - tr("Add input files"), "", - tr("All Files (*)")); + tr("Add input files"), "", + tr("All Files (*)")); for (int i = 0; i < files.size(); ++i) { if (_input_files_list->findItems(files.at(i), Qt::MatchFixedString).size() == 0) @@ -536,6 +840,18 @@ BL::FilesPage::choose_input_files() } } +void +BL::FilesPage::choose_local_directory() +{ + QString dir = QFileDialog::getExistingDirectory(this, tr("Choose local result directory"), + "", + QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks); + + if (dir != "") + _result_directory->setText(dir); +} + void BL::FilesPage::remove_input_files() { @@ -587,10 +903,10 @@ BL::FilesPage::output_itemSelectionChanged() int BL::FilesPage::nextId() const { - return BL::CreateJobWizard::Page_Machine; + return BL::CreateJobWizard::Page_Conclusion; } -BL::CreateJobWizard::ConclusionPage::ConclusionPage(QWidget * parent) +BL::ConclusionPage::ConclusionPage(QWidget * parent) : QWizardPage(parent) { setTitle("Job definition is finished"); @@ -601,86 +917,208 @@ BL::CreateJobWizard::ConclusionPage::ConclusionPage(QWidget * parent) setLayout(main_layout); }; -BL::CreateJobWizard::ConclusionPage::~ConclusionPage() +BL::ConclusionPage::~ConclusionPage() {} bool -BL::CreateJobWizard::ConclusionPage::validatePage() +BL::ConclusionPage::validatePage() { return true; } int -BL::CreateJobWizard::ConclusionPage::nextId() const +BL::ConclusionPage::nextId() const { return -1; } -BL::MachinePage::MachinePage(BL::CreateJobWizard * parent, BL::SALOMEServices * salome_services) +BL::ResourcePage::ResourcePage(BL::CreateJobWizard * parent, BL::SALOMEServices * salome_services) : QWizardPage(parent) { _salome_services = salome_services; - setTitle("Select a Machine"); + setTitle("Select a Resource"); - QLabel * main_label = new QLabel("In this step you select the machine of your job"); + QLabel * main_label = new QLabel("In this step you select the resource of your job"); main_label->setWordWrap(true); - // input_Machine - QGroupBox * machine_group_box = new QGroupBox("Machine List"); - _machine_list = new QListWidget(); - _machine_list->setSelectionMode(QAbstractItemView::SingleSelection); - std::list machine_list = _salome_services->getMachineList(); - std::list::iterator it; - for (it = machine_list.begin(); it != machine_list.end(); it++) - { - std::string machine = *it; - _machine_list->addItem(QString(machine.c_str())); - } - connect(_machine_list, SIGNAL(itemSelectionChanged()), this, SLOT(machine_itemSelectionChanged())); - QVBoxLayout * machine_list_layout = new QVBoxLayout(); - machine_list_layout->addWidget(_machine_list); - machine_group_box->setLayout(machine_list_layout); - - QLabel * machine_label = new QLabel("Machine selected: "); - _machine_choosed = new QLineEdit(); - _machine_choosed->setText(""); - _machine_choosed->setReadOnly(true); - registerField("machine_choosed", _machine_choosed); - - QGridLayout * main_layout = new QGridLayout; - main_layout->addWidget(machine_group_box, 0, 0, 1, -1); - main_layout->addWidget(machine_label, 1, 0); - main_layout->addWidget(_machine_choosed, 1, 1); - setLayout(main_layout); + // input_Resource + QGroupBox * resource_group_box = new QGroupBox("Resource List"); + _resource_list = new JM::ResourceCatalog(this, _salome_services); + connect(_resource_list->getQListWidget(), SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(itemSelected(QListWidgetItem*))); + + QVBoxLayout * resource_list_layout = new QVBoxLayout(); + resource_list_layout->addWidget(_resource_list); + resource_group_box->setLayout(resource_list_layout); + + QLabel * resource_label = new QLabel("Resource selected: "); + _resource_choosed = new QLineEdit(); + _resource_choosed->setText(""); + _resource_choosed->setReadOnly(true); + registerField("resource_choosed", _resource_choosed); + + QLabel * bqLabel = new QLabel("Batch Queue (could be optional):"); + QLineEdit * _bqLineEdit = new QLineEdit(this); + registerField("batch_queue", _bqLineEdit); + + _ll_label = new QLabel("LoadLeveler JobType:", this); + _ll_value = new QLineEdit(this); + registerField("ll_jobtype", _ll_value); + _ll_label->hide(); + _ll_value->hide(); + + _main_layout = new QGridLayout; + _main_layout->addWidget(resource_group_box, 0, 0, 1, -1); + _main_layout->addWidget(resource_label, 1, 0); + _main_layout->addWidget(_resource_choosed, 1, 1); + _main_layout->addWidget(bqLabel, 2, 0); + _main_layout->addWidget(_bqLineEdit, 2, 1); + setLayout(_main_layout); + }; -BL::MachinePage::~MachinePage() +BL::ResourcePage::~ResourcePage() {} +void +BL::ResourcePage::initializePage() +{ + if (field("ll_jobtype").toString() != "") + { + _main_layout->addWidget(_ll_label, 3, 0); + _main_layout->addWidget(_ll_value, 3, 1); + _ll_label->show(); + _ll_value->show(); + } +} + bool -BL::MachinePage::validatePage() +BL::ResourcePage::validatePage() { - QString machine_choosed = field("machine_choosed").toString(); - if (machine_choosed == "") + QString resource_choosed = field("resource_choosed").toString(); + if (resource_choosed == "") { - QMessageBox::warning(NULL, "Machine Error", "Please choose a machine"); + QMessageBox::warning(NULL, "Resource Error", "Please choose a resource"); return false; } + + BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed.toStdString()); + std::string batch = resource_descr.batch.c_str(); + if (batch == "ll") + { + QString ll_jobtype = field("ll_jobtype").toString(); + if (ll_jobtype == "") + { + QMessageBox::warning(NULL, "LoadLeveler Error", "Please define a LoadLeveler JobType"); + return false; + } + } return true; } void -BL::MachinePage::machine_itemSelectionChanged() +BL::ResourcePage::itemSelected(QListWidgetItem * item) +{ + _resource_choosed->setReadOnly(false); + _resource_choosed->setText(item->text()); + _resource_choosed->setReadOnly(true); + + //Specific parameters for LoadLeveler + BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(item->text().toStdString()); + std::string batch = resource_descr.batch.c_str(); + if (batch == "ll") + { + _main_layout->addWidget(_ll_label, 3, 0); + _main_layout->addWidget(_ll_value, 3, 1); + _ll_label->show(); + _ll_value->show(); + } + else + { + _main_layout->removeWidget(_ll_value); + _main_layout->removeWidget(_ll_label); + _ll_label->hide(); + _ll_value->hide(); + } +} + +int +BL::ResourcePage::nextId() const +{ + return BL::CreateJobWizard::Page_BatchParameters; +} + +BL::PythonSalomeMainPage::PythonSalomeMainPage(QWidget * parent) +: QWizardPage(parent) +{ + setTitle("Define a Python script in SALOME job"); + QLabel *label = new QLabel("Enter the Python script that will be executed into the resource"); + label->setWordWrap(true); + + // PythonSalome + QPushButton * PythonSalome_file_button = new QPushButton(tr("Choose a Python file")); + connect(PythonSalome_file_button, SIGNAL(clicked()), this, SLOT(choose_PythonSalome_file())); + _line_PythonSalome = new QLineEdit(this); + registerField("PythonSalome", _line_PythonSalome); + _line_PythonSalome->setReadOnly(true); + + QPushButton * PythonSalome_env_file_button = new QPushButton(tr("Choose an environnement file")); + connect(PythonSalome_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file())); + _line_env_file = new QLineEdit(this); + registerField("env_PythonSalome_file", _line_env_file); + _line_env_file->setReadOnly(true); + + QGridLayout *layout = new QGridLayout; + layout->addWidget(PythonSalome_file_button, 0, 0); + layout->addWidget(_line_PythonSalome, 0, 1); + layout->addWidget(PythonSalome_env_file_button, 1, 0); + layout->addWidget(_line_env_file, 1, 1); + + QVBoxLayout * main_layout = new QVBoxLayout; + main_layout->addWidget(label); + main_layout->insertLayout(-1, layout); + setLayout(main_layout); +}; + +BL::PythonSalomeMainPage::~PythonSalomeMainPage() +{} + +void +BL::PythonSalomeMainPage::choose_PythonSalome_file() +{ + QString PythonSalome_file = QFileDialog::getOpenFileName(this, + tr("Open Python script file"), "", + tr("py (*.py);;All Files (*)")); + _line_PythonSalome->setReadOnly(false); + _line_PythonSalome->setText(PythonSalome_file); + _line_PythonSalome->setReadOnly(true); +} + +void +BL::PythonSalomeMainPage::choose_env_file() { - _machine_choosed->setReadOnly(false); - QList list = _machine_list->selectedItems(); - QListWidgetItem * item = list.at(0); - _machine_choosed->setText(item->text()); - _machine_choosed->setReadOnly(true); + QString env_file = QFileDialog::getOpenFileName(this, + tr("Open environnement file"), "", + tr("sh (*.sh);;All Files (*)")); + _line_env_file->setReadOnly(false); + _line_env_file->setText(env_file); + _line_env_file->setReadOnly(true); +} + +bool +BL::PythonSalomeMainPage::validatePage() +{ + QString PythonSalome = field("PythonSalome").toString(); + if (PythonSalome == "") + { + QMessageBox::warning(NULL, "Python script in SALOME Error", "Please enter a Python script"); + return false; + } + + return true; } int -BL::MachinePage::nextId() const +BL::PythonSalomeMainPage::nextId() const { - return BL::CreateJobWizard::Page_Conclusion; + return BL::CreateJobWizard::Page_Resource; } diff --git a/src/genericgui/BL_CreateJobWizard.hxx b/src/genericgui/BL_CreateJobWizard.hxx index ede4b4b..b664914 100644 --- a/src/genericgui/BL_CreateJobWizard.hxx +++ b/src/genericgui/BL_CreateJobWizard.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_CREATEJOBWIZARD_HXX_ @@ -23,8 +23,8 @@ #include #include "BL_Traces.hxx" -#include "BL_JobsManager_QT.hxx" #include "BL_SALOMEServices.hxx" +#include "JM_ResourceCatalog.hxx" #include #include @@ -32,6 +32,7 @@ namespace BL{ class JobsManager_QT; + class JobNamePage; class CreateJobWizard: virtual public QWizard { Q_OBJECT @@ -42,6 +43,8 @@ namespace BL{ void setFilesList(QListWidget * input_files_list, QListWidget * output_files_list); + void clone(const std::string & name); + public slots: void end(int result); @@ -52,16 +55,21 @@ namespace BL{ QListWidget * _input_files_list; QListWidget * _output_files_list; + BL::JobNamePage * _job_name_page; + BL::SALOMEServices * _salome_services; + public: // Results std::string job_name; - - std::string yacs_file; + std::string yacs_file; std::string command; + std::string python_salome_file; + + std::string env_file; std::string batch_directory; - std::string expected_during_time; + std::string maximum_duration; std::string expected_memory; int nb_proc; @@ -69,67 +77,61 @@ namespace BL{ std::list input_files_list; std::list output_files_list; - std::string machine_choosed; + std::string resource_choosed; + std::string batch_queue; bool start_job; + int dump_yacs_state; + std::string ll_jobtype; public: - enum {Page_JobName, Page_YACSSchema, Page_BatchParameters, Page_Files, - Page_Command_Main_Definitions, Page_Machine, Page_Conclusion}; - - class JobNamePage: virtual public QWizardPage - { - public: - JobNamePage(QWidget * parent, BL::JobsManager_QT * jobs_manager); - virtual ~JobNamePage(); - - virtual bool validatePage(); - virtual int nextId() const ; - - private: - BL::JobsManager_QT * _jobs_manager; - QRadioButton * _yacs_schema_button; - }; - - - class CommandMainPage: virtual public QWizardPage - { - public: - CommandMainPage(QWidget * parent); - virtual ~CommandMainPage(); - - virtual bool validatePage(); - virtual int nextId() const ; - }; - - class ConclusionPage: virtual public QWizardPage - { - public: - ConclusionPage(QWidget * parent); - virtual ~ConclusionPage(); - - virtual bool validatePage(); - virtual int nextId() const ; - }; + enum {Page_JobName, + Page_YACSSchema, + Page_Command_Main_Definitions, + Page_PythonSalome_Main_Definitions, + Page_BatchParameters, + Page_Files, + Page_Resource, + Page_Conclusion}; }; - class YACSSchemaPage: virtual public QWizardPage + class JobNamePage: virtual public QWizardPage { Q_OBJECT public: - YACSSchemaPage(QWidget * parent); - virtual ~YACSSchemaPage(); + JobNamePage(QWidget * parent, BL::JobsManager_QT * jobs_manager); + virtual ~JobNamePage(); virtual bool validatePage(); virtual int nextId() const ; + virtual void cleanupPage() {} public slots: - void choose_file(); + void yacs_schema_button(bool checked); + void command_button(bool checked); + void python_salome_button(bool checked); private: - QPushButton * _yacs_file_button; - QLineEdit * _yacs_file_text; + BL::JobsManager_QT * _jobs_manager; + QLabel * _explanation; + + public: + QRadioButton * _yacs_schema_button; + QRadioButton * _command_button; + QRadioButton * _python_salome_button; + bool _check_name; + }; + + class ConclusionPage: virtual public QWizardPage + { + public: + ConclusionPage(QWidget * parent); + virtual ~ConclusionPage(); + + virtual bool validatePage(); + virtual int nextId() const ; + virtual void cleanupPage() {} }; class BatchParametersPage: virtual public QWizardPage @@ -137,11 +139,17 @@ namespace BL{ Q_OBJECT public: - BatchParametersPage(QWidget * parent); + BatchParametersPage(QWidget * parent, BL::SALOMEServices * salome_services); virtual ~BatchParametersPage(); virtual bool validatePage(); virtual int nextId() const; + virtual void cleanupPage(); + virtual void initializePage(); + + private: + BL::SALOMEServices * _salome_services; + QString resource_choosed; }; class FilesPage: virtual public QWizardPage @@ -154,11 +162,13 @@ namespace BL{ virtual int nextId() const; virtual bool validatePage(); + virtual void cleanupPage() {} public slots: void choose_input_files(); void remove_input_files(); void input_itemSelectionChanged(); + void choose_local_directory(); void add_output_file(); void remove_output_files(); @@ -168,30 +178,100 @@ namespace BL{ QPushButton * _input_files_button; QPushButton * _remove_input_files_button; QListWidget * _input_files_list; + QLineEdit * _result_directory; QPushButton * _output_files_button; QPushButton * _remove_output_files_button; QListWidget * _output_files_list; }; - class MachinePage: virtual public QWizardPage + class ResourcePage: virtual public QWizardPage { Q_OBJECT public: - MachinePage(BL::CreateJobWizard * parent, BL::SALOMEServices * salome_services); - virtual ~MachinePage(); + ResourcePage(BL::CreateJobWizard * parent, BL::SALOMEServices * salome_services); + virtual ~ResourcePage(); virtual int nextId() const; virtual bool validatePage(); + virtual void initializePage(); + virtual void cleanupPage() {} public slots: - void machine_itemSelectionChanged(); + void itemSelected(QListWidgetItem * item); private: - QListWidget * _machine_list; - QLineEdit * _machine_choosed; + JM::ResourceCatalog * _resource_list; + QLineEdit * _resource_choosed; BL::SALOMEServices * _salome_services; + + QLabel * _ll_label; + QLineEdit * _ll_value; + QGridLayout * _main_layout; + }; + + class YACSSchemaPage: virtual public QWizardPage + { + Q_OBJECT + + public: + YACSSchemaPage(QWidget * parent); + virtual ~YACSSchemaPage(); + + virtual bool validatePage(); + virtual int nextId() const ; + virtual void cleanupPage() {} + + public slots: + void choose_file(); + void choose_env_file(); + + private: + QLineEdit * _yacs_file_text; + QLineEdit * _line_env_file; + }; + + class CommandMainPage: virtual public QWizardPage + { + Q_OBJECT + + public: + CommandMainPage(QWidget * parent); + virtual ~CommandMainPage(); + + virtual bool validatePage(); + virtual int nextId() const ; + virtual void cleanupPage() {} + + public slots: + void choose_command_file(); + void choose_env_file(); + + private: + QLineEdit * _line_command; + QLineEdit * _line_env_file; + }; + + class PythonSalomeMainPage: virtual public QWizardPage + { + Q_OBJECT + + public: + PythonSalomeMainPage(QWidget * parent); + virtual ~PythonSalomeMainPage(); + + virtual bool validatePage(); + virtual int nextId() const ; + virtual void cleanupPage() {} + + public slots: + void choose_PythonSalome_file(); + void choose_env_file(); + + private: + QLineEdit * _line_PythonSalome; + QLineEdit * _line_env_file; }; } diff --git a/src/genericgui/BL_GenericGui.cxx b/src/genericgui/BL_GenericGui.cxx index 49d37af..b195661 100644 --- a/src/genericgui/BL_GenericGui.cxx +++ b/src/genericgui/BL_GenericGui.cxx @@ -1,147 +1,195 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_GenericGui.hxx" +#ifdef WNT +#undef ERROR +#endif + BL::GenericGui::GenericGui(BL::MainWindows_Wrap * wrapper) : QObject(wrapper->getDockParent()) { DEBTRACE("Creating BL::GenericGui"); BL_ASSERT(wrapper); _wrapper = wrapper; - _row_selected = -1; _job_name_selected = ""; _dock_parent = _wrapper->getDockParent(); - _tab_parent = _wrapper->getTabParent(); + // _salome_services is a servant + // POA wil destroy it at the end of the application _salome_services = new BL::SALOMEServices(); - if (_salome_services->initNS() == false) - DEBMSG("WARNING !!!!! SALOME IS NOT REACHABLE !!!!"); - _jobs_manager = new BL::JobsManager_QT(_dock_parent, _salome_services); - _model_manager = new BL::QModelManager(this, _jobs_manager); +} +BL::GenericGui::~GenericGui() +{ + DEBTRACE("Destroying BL::GenericGui"); + _salome_services->end(); +} + +void +BL::GenericGui::createDockWidgets() +{ + DEBTRACE("createDockWidgets BL::GenericGui"); + _jobs_manager = new BL::JobsManager_QT(_dock_parent, this, _salome_services); + _model_manager = new BL::QModelManager(this, _jobs_manager); _model = _model_manager->getModel(); - // ---- Adding different GUI parts + /* Summary */ + _dw_summary = new QDockWidget(_dock_parent); + _dw_summary->setWindowTitle("Summary"); + _summary = new BL::Summary(_dw_summary, _jobs_manager); + _summary->setModel(_model); + QScrollArea * scroll_widget_summary = new QScrollArea(_dw_summary); + scroll_widget_summary->setWidget(_summary); + scroll_widget_summary->setWidgetResizable(true); + _dw_summary->setWidget(scroll_widget_summary); + + /* ResourceCatalog */ + _dw_resource_catalog = new QDockWidget(_dock_parent); + _dw_resource_catalog->setWindowTitle("Resource Catalog"); + _resource_catalog = new JM::ResourceCatalog(_dw_resource_catalog, _salome_services); + QScrollArea * scroll_widget_resource = new QScrollArea(_dw_resource_catalog); + scroll_widget_resource->setWidget(_resource_catalog); + scroll_widget_resource->setWidgetResizable(true); + _dw_resource_catalog->setWidget(scroll_widget_resource); + + /* Main Dock Window */ + _dock_parent->addDockWidget(Qt::RightDockWidgetArea, _jobs_manager); + _dock_parent->addDockWidget(Qt::RightDockWidgetArea, _dw_summary); + _dock_parent->addDockWidget(Qt::RightDockWidgetArea, _dw_resource_catalog); + _dock_parent->splitDockWidget(_jobs_manager, _dw_summary, Qt::Vertical); + _dock_parent->tabifyDockWidget(_dw_summary, _dw_resource_catalog); + /* Signals and Slots */ + // JobsManager -> Model + connect(_jobs_manager, SIGNAL(new_job_added(QString)), _model_manager, SLOT(new_job_added(QString))); + connect(_jobs_manager, SIGNAL(job_state_changed(QString)), _model_manager, SLOT(job_state_changed(QString))); + connect(_jobs_manager, SIGNAL(job_state_changed(QString)), this, SLOT(job_state_changed(QString))); + // Model -> summary + connect(_model, SIGNAL(rowsInserted(QModelIndex, int, int)), _summary, SLOT(rowsInserted(QModelIndex, int, int))); + connect(_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), _summary, SLOT(rowsRemoved(QModelIndex, int, int))); + connect(_model, SIGNAL(itemChanged(QStandardItem*)), _summary, SLOT(itemChanged(QStandardItem*))); + + // Init at the end to be able to get jobs already in Launcher + if (_salome_services->initNS() == false) + DEBMSG("WARNING !!!!! SALOME IS NOT REACHABLE !!!!"); + // refresh at the beacause we need that _salome_services be + // initialized + _resource_catalog->refresh_resource_list(); +} + +void +BL::GenericGui::createCentralWidget() +{ + DEBTRACE("createCentralWidget BL::GenericGui"); + + _tab_parent = _wrapper->getTabParent(); + /* Tab Central Widget */ /* Buttons */ _buttons = new BL::Buttons(_tab_parent); _buttons->setCreateButtonSlot(this, SLOT(create_job())); + _buttons->setEditCloneButtonSlot(this, SLOT(edit_clone_job())); _buttons->setStartButtonSlot(this, SLOT(start_job())); + _buttons->setReStartButtonSlot(this, SLOT(restart_job())); _buttons->setDeleteButtonSlot(this, SLOT(delete_job())); + _buttons->setStopButtonSlot(this, SLOT(stop_job())); _buttons->setRefreshButtonSlot(this, SLOT(refresh_job())); _buttons->setGetResultsButtonSlot(this, SLOT(get_results_job())); /* Jobs Table */ _jobs_table = new BL::JobsTable(_tab_parent); _jobs_table->setModel(_model); + _jobs_table->set_main_gui(this); /* Job Tab */ _job_tab = new BL::JobTab(_tab_parent, _jobs_manager); _job_tab->setModel(_model); - /* Tab Central Widget */ + // Central Widget QWidget * central_widget = new QWidget(_tab_parent); - - QSplitter * tab_central_widget = new QSplitter(Qt::Vertical, central_widget); + QSplitter * tab_central_widget = new QSplitter(Qt::Vertical, _tab_parent); tab_central_widget->addWidget(_jobs_table); tab_central_widget->addWidget(_job_tab); tab_central_widget->setChildrenCollapsible(false); - QVBoxLayout * central_layout = new QVBoxLayout; central_layout->addWidget(_buttons); central_layout->addWidget(tab_central_widget); central_widget->setLayout(central_layout); - _tab_parent->setCentralWidget(central_widget); - // Test tab - //QDockWidget * dw_main = new QDockWidget(_tab_parent); - //dw_main->setWidget(central_widget); - //_tab_parent->addDockWidget(Qt::LeftDockWidgetArea, dw_main); - - /* Summary */ - _dw_summary = new QDockWidget(_dock_parent); - _dw_summary->setWindowTitle("Summary"); - _summary = new BL::Summary(_dock_parent, _jobs_manager); - _summary->setModel(_model); - _dw_summary->setWidget(_summary); - - /* MachineCatalog */ - _dw_machine_catalog = new QDockWidget(_dock_parent); - _dw_machine_catalog->setWindowTitle("Machine Catalog"); - _machine_catalog = new BL::MachineCatalog(_dock_parent, _salome_services); - _dw_machine_catalog->setWidget(_machine_catalog); - - /* Main Dock Window */ - _dock_parent->addDockWidget(Qt::RightDockWidgetArea, _jobs_manager); - _dock_parent->addDockWidget(Qt::RightDockWidgetArea, _dw_summary); - _dock_parent->addDockWidget(Qt::RightDockWidgetArea, _dw_machine_catalog); - _dock_parent->splitDockWidget(_jobs_manager, _dw_summary, Qt::Vertical); - _dock_parent->tabifyDockWidget(_dw_summary, _dw_machine_catalog); + // Adding a scroll area for low resolution + QScrollArea * scroll_central_widget = new QScrollArea(_tab_parent); + scroll_central_widget->setWidget(central_widget); + scroll_central_widget->setWidgetResizable(true); + _tab_parent->setCentralWidget(scroll_central_widget); /* Signals and Slots */ - - // JobsManager -> Model - connect(_jobs_manager, SIGNAL(new_job_added(QString)), _model_manager, SLOT(new_job_added(QString))); - connect(_jobs_manager, SIGNAL(job_state_changed(QString)), _model_manager, SLOT(job_state_changed(QString))); - connect(_jobs_manager, SIGNAL(job_state_changed(QString)), this, SLOT(job_state_changed(QString))); - - // Model -> X - connect(_model, SIGNAL(rowsInserted(QModelIndex, int, int)), _summary, SLOT(rowsInserted(QModelIndex, int, int))); - connect(_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), _summary, SLOT(rowsRemoved(QModelIndex, int, int))); - connect(_model, SIGNAL(itemChanged(QStandardItem*)), _summary, SLOT(itemChanged(QStandardItem*))); + // Model -> JobTab connect(_model, SIGNAL(itemChanged(QStandardItem*)), _job_tab, SLOT(itemChanged(QStandardItem*))); // TableView -> X - connect(_jobs_table, SIGNAL(clicked(QModelIndex)), _job_tab, SLOT(job_selected(QModelIndex))); connect(_jobs_table, SIGNAL(clicked(QModelIndex)), this, SLOT(job_selected(QModelIndex))); - connect(_jobs_table, SIGNAL(clicked(QModelIndex)), _model_manager, SLOT(job_selected(QModelIndex))); - - // Delete Job -> X - connect(this, SIGNAL(job_deleted(QString)), _job_tab, SLOT(reset(QString))); + connect(_jobs_table, SIGNAL(activated(QModelIndex)), this, SLOT(job_activated(QModelIndex))); } -BL::GenericGui::~GenericGui() +void +BL::GenericGui::deleteDockWidget() { - DEBTRACE("Destroying BL::GenericGui"); - - delete _salome_services; + // Specific for SALOME... + _dock_parent->removeDockWidget(_dw_summary); + delete _dw_summary; + _dock_parent->removeDockWidget(_dw_resource_catalog); + delete _dw_resource_catalog; + _dock_parent->removeDockWidget(_jobs_manager); + delete _jobs_manager; } void BL::GenericGui::showDockWidgets(bool isVisible) { DEBTRACE("BL::GenericGui::showDockWidgets " << isVisible); - if (_jobs_manager) _jobs_manager->setVisible(isVisible); - if (_dw_summary) _dw_summary->setVisible(isVisible); - if (_dw_machine_catalog) _dw_machine_catalog->setVisible(isVisible); + if (_jobs_manager) { + _jobs_manager->setVisible(isVisible); + _jobs_manager->toggleViewAction()->setVisible(isVisible); + } + if (_dw_summary) { + _dw_summary->setVisible(isVisible); + _dw_summary->toggleViewAction()->setVisible(isVisible); + } + if (_dw_resource_catalog) { + _dw_resource_catalog->setVisible(isVisible); + _dw_resource_catalog->toggleViewAction()->setVisible(isVisible); + } } void BL::GenericGui::createActions() { DEBTRACE("CreateActions BL::GenericGui"); - _create_job_action = _wrapper->createAction("Create Job", QIcon(), "Create Job", "Create Job", 0, _dock_parent, false, this, SLOT(create_job())); - _start_job_action = _wrapper->createAction("Start Job", QIcon(), "Start Job", "Start Job", 0, _dock_parent, false, this, SLOT(start_job())); - _delete_job_action = _wrapper->createAction("Delete Job", QIcon(), "Delete Job", "Delete Job", 0, _dock_parent, false, this, SLOT(delete_job())); - _refresh_job_action = _wrapper->createAction("Refresh Job", QIcon(), "Refresh Job", "Refresh Job", 0, _dock_parent, false, this, SLOT(refresh_job())); + _create_job_action = _wrapper->createAction("Create a Job", QIcon(), "Create a Job", "Create a Job", 0, _dock_parent, false, this, SLOT(create_job())); + _edit_clone_job_action = _wrapper->createAction("Edit/Clone a Job", QIcon(), "Edit/Clone a Job", "Edit/Clone a Job", 0, _dock_parent, false, this, SLOT(edit_clone_job())); + _start_job_action = _wrapper->createAction("Start a Job", QIcon(), "Start a Job", "Start a Job", 0, _dock_parent, false, this, SLOT(start_job())); + _restart_job_action = _wrapper->createAction("Restart a Job", QIcon(), "Restart a Job", "Restart a Job", 0, _dock_parent, false, this, SLOT(restart_job())); + _delete_job_action = _wrapper->createAction("Delete a Job", QIcon(), "Delete a Job", "Delete a Job", Qt::Key_Delete, _dock_parent, false, this, SLOT(delete_job())); + _refresh_job_action = _wrapper->createAction("Refresh Jobs", QIcon(), "Refresh Jobs", "Refresh Jobs", 0, _dock_parent, false, this, SLOT(refresh_job())); _get_results_job_action = _wrapper->createAction("Get Job Results", QIcon(), "Get Job Results", "Get Job Results", 0, _dock_parent, false, this, SLOT(refresh_job())); + _stop_job_action = _wrapper->createAction("Stop a Job", QIcon(), "Stop a Job", "Stop a Job", 0, _dock_parent, false, this, SLOT(stop_job())); } void @@ -150,7 +198,10 @@ BL::GenericGui::createMenus() DEBTRACE("CreateMenus BL::GenericGui"); int menu_id = _wrapper->createTopMenu("JobManager"); _wrapper->addActionToMenu(_create_job_action, menu_id); + _wrapper->addActionToMenu(_edit_clone_job_action, menu_id); _wrapper->addActionToMenu(_start_job_action, menu_id); + _wrapper->addActionToMenu(_restart_job_action, menu_id); + _wrapper->addActionToMenu(_stop_job_action, menu_id); _wrapper->addActionToMenu(_delete_job_action, menu_id); _wrapper->addActionToMenu(_get_results_job_action, menu_id); _wrapper->addActionToMenu(_refresh_job_action, menu_id); @@ -160,7 +211,14 @@ void BL::GenericGui::create_job() { DEBTRACE("Create Job Slot BL::GenericGui"); - _jobs_manager->create_job_wizard(); + _jobs_manager->create_job(); +} + +void +BL::GenericGui::edit_clone_job() +{ + DEBTRACE("Edit/Clone Job Slot BL::GenericGui"); + _jobs_manager->edit_clone_job(_job_name_selected.toStdString()); } void @@ -171,6 +229,14 @@ BL::GenericGui::start_job() updateButtonsStates(); } +void +BL::GenericGui::restart_job() +{ + DEBTRACE("Restart Job Slot BL::GenericGui"); + _jobs_manager->restart_job(_job_name_selected.toStdString()); + updateButtonsStates(); +} + void BL::GenericGui::refresh_job() { @@ -182,51 +248,226 @@ void BL::GenericGui::get_results_job() { DEBTRACE("Get Results Job Slot BL::GenericGui"); - _jobs_manager->get_results_job(_job_name_selected.toStdString()); + if (!_jobs_table->isMultipleSelected()) + { + _jobs_manager->get_results_job(_job_name_selected.toStdString()); + } + else + { + QModelIndexList selected_rows = _jobs_table->selectionModel()->selectedRows(); + for (int i = 0; i < selected_rows.length(); ++i) + { + QString job_name = _model->itemFromIndex(selected_rows[i])->text(); + _jobs_manager->get_results_job(job_name.toStdString()); + } + } } +void +BL::GenericGui::stop_job() +{ + DEBTRACE("Stop Job Slot BL::GenericGui"); + if (!_jobs_table->isMultipleSelected()) + { + _jobs_manager->stop_job(_job_name_selected.toStdString()); + } + else + { + QModelIndexList selected_rows = _jobs_table->selectionModel()->selectedRows(); + for (int i = 0; i < selected_rows.length(); ++i) + { + QString job_name = _model->itemFromIndex(selected_rows[i])->text(); + _jobs_manager->stop_job(job_name.toStdString()); + } + } +} + + void BL::GenericGui::delete_job() { DEBTRACE("Delete Job Slot BL::GenericGui"); - int ret = QMessageBox::warning(NULL, "Delete a job", "Do you really want to delete this job ?", - QMessageBox::Ok|QMessageBox::Cancel, - QMessageBox::Ok); + int ret = QMessageBox::Cancel; + + if (!_jobs_table->isMultipleSelected()) + { + ret = QMessageBox::warning(NULL, "Delete a job", "Do you really want to delete job " + _job_name_selected + " ? ", + QMessageBox::Ok|QMessageBox::Cancel, + QMessageBox::Ok); + } + else + { + ret = QMessageBox::warning(NULL, "Delete jobs", "Do you really want to delete these jobs ?", + QMessageBox::Ok|QMessageBox::Cancel, + QMessageBox::Ok); + } if (ret == QMessageBox::Ok) { - _jobs_manager->delete_job(_job_name_selected); - _model_manager->deleteJob(_row_selected); - emit job_deleted(_job_name_selected); - _row_selected = -1; + delete_job_internal(); + } +} + +void +BL::GenericGui::delete_job_external(const QString & name) +{ + DEBTRACE("Delete Job External"); + _jobs_manager->delete_job(name); + if (!_jobs_table->selectCurrent()) + { _job_name_selected = ""; updateButtonsStates(); } } +void +BL::GenericGui::delete_job_internal() +{ + if (!_jobs_table->isMultipleSelected()) + { + QModelIndexList selected_list = _jobs_table->getSelectedIndexes(); + QString job_name_to_delete = _model->itemFromIndex(selected_list[0])->text(); + DEBTRACE("Single Deleting job: " << job_name_to_delete.toStdString()); + _jobs_manager->delete_job(job_name_to_delete); + if (!_jobs_table->selectCurrent()) + { + _job_name_selected = ""; + updateButtonsStates(); + } + } + else + { + QModelIndexList selected_list = _jobs_table->getSelectedIndexes(); + QString job_name = _model->itemFromIndex(selected_list[0])->text(); + DEBTRACE("Multiple Deleting job: " << job_name.toStdString()); + _jobs_manager->delete_job(job_name); + delete_job_internal(); // Recursive delete + } +} + +void +BL::GenericGui::reset_job_selection() +{ + _job_name_selected = ""; + _job_tab->reset(""); + updateButtonsStates(); +} + void BL::GenericGui::job_selected(const QModelIndex & index) { - DEBTRACE("BL::GenericGui::job_selected slot"); - QStandardItem * item = _model->itemFromIndex(index); - QStandardItem * item_name = _model->item(item->row()); - _row_selected = item->row(); - _job_name_selected = item_name->text(); + DEBTRACE("BL::GenericGui::job_selected"); + + //Find if a job is selected (ignore index) + //If Multiple job are selected, take first job + QItemSelectionModel * selection_model = _jobs_table->selectionModel(); + QModelIndexList selected_rows = selection_model->selectedRows(); + if (selected_rows.length() >= 1) + { + QModelIndex idx = selected_rows[0]; + QStandardItem * item = _model->itemFromIndex(idx); + QStandardItem * item_name = _model->item(item->row()); + _job_name_selected = item_name->text(); + _job_tab->job_selected(idx); + DEBTRACE("BL::GenericGui::job_selected name is " << _job_name_selected.toStdString()); + } + else + { + _job_name_selected = ""; + _job_tab->reset(""); + DEBTRACE("BL::GenericGui::job_selected - no jobs are selected"); + } updateButtonsStates(); } -void +void +BL::GenericGui::job_activated(const QModelIndex & index) +{ + DEBTRACE("BL::GenericGui::job_activated slot"); + job_selected(index); +} + +void BL::GenericGui::job_state_changed(const QString & name) { if (name == _job_name_selected) updateButtonsStates(); } + void BL::GenericGui::updateButtonsStates() { - DEBTRACE("BL::GenericGui::updateButtonsStates slot"); + if (!_jobs_table->isMultipleSelected()) + { + updateButtonsStatesSingleSelection(); + } + else + { + _start_job_action->setEnabled(false); + _edit_clone_job_action->setEnabled(false); + _restart_job_action->setEnabled(false); + _buttons->disable_start_button(); + _buttons->disable_edit_clone_button(); + _buttons->disable_restart_button(); + + // You can always delete jobs + _delete_job_action->setEnabled(true); + _buttons->enable_delete_button(); + + // Enable stop ? + bool enable_stop = true; + QModelIndexList selected_rows = _jobs_table->selectionModel()->selectedRows(); + for (int i = 0; i < selected_rows.length(); ++i) + { + QString job_name = _model->itemFromIndex(selected_rows[i])->text(); + BL::Job * job = _jobs_manager->getJob(job_name.toStdString()); + BL::Job::State job_state = job->getState(); + if (job_state != BL::Job::QUEUED && + job_state != BL::Job::RUNNING && + job_state != BL::Job::PAUSED) + enable_stop = false; + } + if (enable_stop) + { + _stop_job_action->setEnabled(true); + _buttons->enable_stop_button(); + } + else + { + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); + } + + // Enable get_results ? + bool enable_results = true; + for (int i = 0; i < selected_rows.length(); ++i) + { + QString job_name = _model->itemFromIndex(selected_rows[i])->text(); + BL::Job * job = _jobs_manager->getJob(job_name.toStdString()); + BL::Job::State job_state = job->getState(); + if (job_state != BL::Job::FINISHED && + job_state != BL::Job::FAILED) + enable_results= false; + } + if (enable_results) + { + _get_results_job_action->setEnabled(true); + _buttons->enable_get_results_button(); + } + else + { + _get_results_job_action->setEnabled(false); + _buttons->disable_get_results_button(); + } + } +} + +void +BL::GenericGui::updateButtonsStatesSingleSelection() +{ + DEBTRACE("BL::GenericGui::updateButtonsStatesSingleSelection slot"); // First case: no job selected - if (_job_name_selected == "" and _row_selected == -1) + if (_job_name_selected == "") { _start_job_action->setEnabled(false); _delete_job_action->setEnabled(false); @@ -234,12 +475,20 @@ BL::GenericGui::updateButtonsStates() _buttons->disable_start_button(); _buttons->disable_delete_button(); _buttons->disable_get_results_button(); + _edit_clone_job_action->setEnabled(false); + _buttons->disable_edit_clone_button(); + _restart_job_action->setEnabled(false); + _buttons->disable_restart_button(); + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); } - else if (_job_name_selected != "" and _row_selected != -1) + else if (_job_name_selected != "") { BL::Job * job = _jobs_manager->getJob(_job_name_selected.toStdString()); BL::Job::State job_state = job->getState(); + _edit_clone_job_action->setEnabled(true); + _buttons->enable_edit_clone_button(); switch (job_state) { case BL::Job::CREATED: @@ -249,6 +498,10 @@ BL::GenericGui::updateButtonsStates() _buttons->enable_start_button(); _buttons->enable_delete_button(); _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(false); + _buttons->disable_restart_button(); + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); break; case BL::Job::IN_PROCESS: @@ -258,6 +511,10 @@ BL::GenericGui::updateButtonsStates() _buttons->disable_delete_button(); _get_results_job_action->setEnabled(false); _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(false); + _buttons->disable_restart_button(); + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); break; case BL::Job::QUEUED: @@ -267,6 +524,10 @@ BL::GenericGui::updateButtonsStates() _buttons->enable_delete_button(); _get_results_job_action->setEnabled(false); _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(false); + _buttons->disable_restart_button(); + _stop_job_action->setEnabled(true); + _buttons->enable_stop_button(); break; case BL::Job::RUNNING: @@ -276,6 +537,10 @@ BL::GenericGui::updateButtonsStates() _buttons->enable_delete_button(); _get_results_job_action->setEnabled(false); _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(false); + _buttons->disable_restart_button(); + _stop_job_action->setEnabled(true); + _buttons->enable_stop_button(); break; case BL::Job::PAUSED: @@ -285,6 +550,10 @@ BL::GenericGui::updateButtonsStates() _buttons->enable_delete_button(); _get_results_job_action->setEnabled(false); _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(false); + _buttons->disable_restart_button(); + _stop_job_action->setEnabled(true); + _buttons->enable_stop_button(); break; case BL::Job::ERROR: @@ -294,6 +563,10 @@ BL::GenericGui::updateButtonsStates() _buttons->enable_delete_button(); _get_results_job_action->setEnabled(false); _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(true); + _buttons->enable_restart_button(); + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); break; case BL::Job::FINISHED: @@ -303,6 +576,36 @@ BL::GenericGui::updateButtonsStates() _buttons->enable_delete_button(); _get_results_job_action->setEnabled(true); _buttons->enable_get_results_button(); + _restart_job_action->setEnabled(true); + _buttons->enable_restart_button(); + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); + break; + + case BL::Job::FAILED: + _start_job_action->setEnabled(false); + _buttons->disable_start_button(); + _delete_job_action->setEnabled(true); + _buttons->enable_delete_button(); + _get_results_job_action->setEnabled(true); + _buttons->enable_get_results_button(); + _restart_job_action->setEnabled(true); + _buttons->enable_restart_button(); + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); + break; + + case BL::Job::NOT_CREATED: + _start_job_action->setEnabled(false); + _buttons->disable_start_button(); + _delete_job_action->setEnabled(true); + _buttons->enable_delete_button(); + _get_results_job_action->setEnabled(false); + _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(true); + _buttons->enable_restart_button(); + _stop_job_action->setEnabled(false); + _buttons->disable_stop_button(); break; } } diff --git a/src/genericgui/BL_GenericGui.hxx b/src/genericgui/BL_GenericGui.hxx index 161a24e..6310175 100644 --- a/src/genericgui/BL_GenericGui.hxx +++ b/src/genericgui/BL_GenericGui.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_GENERICGUI_HXX_ @@ -22,6 +22,8 @@ #include +#include "BL_GenericGuiDefines.hxx" + #include "BL_Traces.hxx" #include "BL_SALOMEServices.hxx" @@ -34,11 +36,11 @@ #include "BL_JobTab.hxx" #include "BL_Buttons.hxx" #include "BL_Summary.hxx" -#include "BL_MachineCatalog.hxx" +#include "JM_ResourceCatalog.hxx" namespace BL { - class GenericGui: public QObject + class BL_GenericGui_EXPORT GenericGui: public QObject { Q_OBJECT @@ -46,25 +48,41 @@ namespace BL GenericGui(BL::MainWindows_Wrap * wrapper); virtual ~GenericGui(); + void createDockWidgets(); + void createCentralWidget(); + void showDockWidgets(bool isVisible); void createActions(); void createMenus(); + void delete_job_internal(); + + void deleteDockWidget(); + void delete_job_external(const QString & name); + + void reset_job_selection(); + + public slots: void create_job(); + void edit_clone_job(); void start_job(); + void restart_job(); void delete_job(); void refresh_job(); + void stop_job(); void get_results_job(); void job_selected(const QModelIndex & index); + void job_activated(const QModelIndex & index); void job_state_changed(const QString & name); void updateButtonsStates(); + void updateButtonsStatesSingleSelection(); - signals: - void job_deleted(QString job_name); + public: + BL::JobTab * _job_tab; + BL::JobsTable * _jobs_table; protected: - BL::MainWindows_Wrap * _wrapper; BL::SALOMEServices * _salome_services; @@ -72,25 +90,25 @@ namespace BL QMainWindow * _dock_parent; QMainWindow * _tab_parent; QDockWidget * _dw_summary; - QDockWidget * _dw_machine_catalog; - + QDockWidget * _dw_resource_catalog; + BL::Buttons * _buttons; - BL::JobsTable * _jobs_table; - BL::JobTab * _job_tab; BL::Summary * _summary; QAction * _create_job_action; + QAction * _edit_clone_job_action; QAction * _start_job_action; + QAction * _restart_job_action; QAction * _delete_job_action; + QAction * _stop_job_action; QAction * _get_results_job_action; QAction * _refresh_job_action; BL::JobsManager_QT * _jobs_manager; BL::QModelManager * _model_manager; QStandardItemModel * _model; - BL::MachineCatalog * _machine_catalog; + JM::ResourceCatalog * _resource_catalog; - int _row_selected; QString _job_name_selected; }; } diff --git a/src/genericgui/BL_GenericGuiDefines.hxx b/src/genericgui/BL_GenericGuiDefines.hxx new file mode 100755 index 0000000..186b80e --- /dev/null +++ b/src/genericgui/BL_GenericGuiDefines.hxx @@ -0,0 +1,32 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef __BL_GENERICGUIDEFINES_HXX__ +#define __BL_GENERICGUIDEFINES_HXX__ + +#ifdef WNT +# if defined BL_GenericGui_EXPORTS +# define BL_GenericGui_EXPORT __declspec( dllexport ) +# else +# define BL_GenericGui_EXPORT __declspec( dllimport ) +# endif +#else +# define BL_GenericGui_EXPORT +#endif + +#endif diff --git a/src/genericgui/BL_JobTab.cxx b/src/genericgui/BL_JobTab.cxx index 5f139cc..91fbfd6 100644 --- a/src/genericgui/BL_JobTab.cxx +++ b/src/genericgui/BL_JobTab.cxx @@ -1,25 +1,29 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_JobTab.hxx" #include "BL_Traces.hxx" +#ifdef WNT +#undef ERROR +#endif + BL::JobTab::JobTab(QWidget *parent, BL::JobsManager_QT * jobs_manager) : QTabWidget(parent) { DEBTRACE("Creating BL::JobTab"); @@ -31,9 +35,6 @@ BL::JobTab::JobTab(QWidget *parent, BL::JobsManager_QT * jobs_manager) : QTabWid createJobSummaryTab(); createJobFilesTab(); - - addTab(_summary_tab, "Job Summary"); - addTab(_files_tab, "Job Files"); } BL::JobTab::~JobTab() @@ -61,19 +62,30 @@ BL::JobTab::createJobSummaryTab() _job_type_label_value = new QLabel(""); QLabel * job_state_label = new QLabel("State:"); _job_state_label_value = new QLabel(""); - QLabel * job_machine_label = new QLabel("Machine:"); - _job_machine_label_value = new QLabel(""); - _job_command_label = new QLabel("Schema or Command:"); - _job_command_label_value = new QLabel(""); + QLabel * job_launcher_label = new QLabel("Launcher Id:"); + _job_launcher_label_value = new QLabel(""); + QLabel * job_resource_label = new QLabel("Resource:"); + _job_resource_label_value = new QLabel(""); + QLabel * job_jobfile_label = new QLabel("Job File:"); + _job_jobfile_label_value = new QLabel(""); + QLabel * job_envfile_label = new QLabel("Env File:"); + _job_envfile_label_value = new QLabel(""); + + + // Specific values + _yacs_dump_state_label = new QLabel("YACS dump state:"); + _yacs_dump_state_value = new QLabel(""); QGroupBox * main_values_box = new QGroupBox("Main values"); - QFormLayout * values_form = new QFormLayout; - values_form->insertRow(0, job_name_label, _job_name_label_value); - values_form->insertRow(1, job_type_label, _job_type_label_value); - values_form->insertRow(2, job_state_label, _job_state_label_value); - values_form->insertRow(3, job_machine_label, _job_machine_label_value); - values_form->insertRow(4, _job_command_label, _job_command_label_value); - main_values_box->setLayout(values_form); + _main_values_form = new QFormLayout; + _main_values_form->insertRow(0, job_name_label, _job_name_label_value); + _main_values_form->insertRow(1, job_type_label, _job_type_label_value); + _main_values_form->insertRow(2, job_state_label, _job_state_label_value); + _main_values_form->insertRow(3, job_launcher_label, _job_launcher_label_value); + _main_values_form->insertRow(4, job_resource_label, _job_resource_label_value); + _main_values_form->insertRow(5, job_jobfile_label, _job_jobfile_label_value); + _main_values_form->insertRow(6, job_envfile_label, _job_envfile_label_value); + main_values_box->setLayout(_main_values_form); QLabel * job_nif_label = new QLabel("Number of Input Files:"); _job_nif_label_value = new QLabel(""); @@ -84,39 +96,49 @@ BL::JobTab::createJobSummaryTab() QLabel * job_rd_label = new QLabel("Result directory:"); _job_rd_label_value = new QLabel(""); - QLabel * job_edt_label = new QLabel("Expected during time:"); - _job_edt_label_value = new QLabel(""); + QLabel * job_mdt_label = new QLabel("Maximum duration:"); + _job_mdt_label_value = new QLabel(""); QLabel * job_em_label = new QLabel("Expected memory:"); _job_em_label_value = new QLabel(""); QLabel * job_nop_label = new QLabel("Number of processors:"); _job_nop_label_value = new QLabel(""); + // Specific values + _batch_queue_label = new QLabel("Batch queue:"); + _batch_queue_value = new QLabel(""); + _ll_jobtype_label = new QLabel("LoadLeveler JobType:"); + _ll_jobtype_value = new QLabel(""); + QGroupBox * run_values_box = new QGroupBox("Run values"); - QFormLayout * run_values_form = new QFormLayout; - run_values_form->insertRow(0, job_nif_label, _job_nif_label_value); - run_values_form->insertRow(1, job_nof_label, _job_nof_label_value); - run_values_form->insertRow(2, job_bd_label, _job_bd_label_value); - run_values_form->insertRow(3, job_rd_label, _job_rd_label_value); - QFormLayout * other_run_values_form = new QFormLayout; - other_run_values_form->insertRow(0, job_edt_label, _job_edt_label_value); - other_run_values_form->insertRow(1, job_em_label, _job_em_label_value); - other_run_values_form->insertRow(2, job_nop_label, _job_nop_label_value); + _run_values_form = new QFormLayout; + _run_values_form->insertRow(0, job_nif_label, _job_nif_label_value); + _run_values_form->insertRow(1, job_nof_label, _job_nof_label_value); + _run_values_form->insertRow(2, job_bd_label, _job_bd_label_value); + _run_values_form->insertRow(3, job_rd_label, _job_rd_label_value); + _other_run_values_form = new QFormLayout; + _other_run_values_form->insertRow(0, job_mdt_label, _job_mdt_label_value); + _other_run_values_form->insertRow(1, job_em_label, _job_em_label_value); + _other_run_values_form->insertRow(2, job_nop_label, _job_nop_label_value); QHBoxLayout * box_layout = new QHBoxLayout(); - box_layout->addLayout(run_values_form); - box_layout->addLayout(other_run_values_form); + box_layout->addLayout(_run_values_form); + box_layout->addLayout(_other_run_values_form); run_values_box->setLayout(box_layout); QVBoxLayout * mainLayout = new QVBoxLayout(); mainLayout->addWidget(main_values_box); mainLayout->addWidget(run_values_box); _summary_tab->setLayout(mainLayout); + + removeTab(0); + insertTab(0, _summary_tab, "Job Summary"); + setCurrentIndex(0); } void BL::JobTab::createJobFilesTab() { _files_tab = new QWidget(this); - + _input_files_list = new QListWidget(this); _input_files_list->setSelectionMode(QAbstractItemView::NoSelection); QGroupBox * input_files_box = new QGroupBox("Input Files"); @@ -135,6 +157,8 @@ BL::JobTab::createJobFilesTab() mainLayout->addWidget(input_files_box); mainLayout->addWidget(output_files_box); _files_tab->setLayout(mainLayout); + + insertTab(1, _files_tab, "Job Files"); } void @@ -147,6 +171,8 @@ BL::JobTab::job_selected(const QModelIndex & index) { BL::Job * job = _jobs_manager->getJob(item_name->text().toStdString()); + reset(""); + _job_name_label_value->setText(QString(job->getName().c_str())); if (job->getState() == BL::Job::CREATED) @@ -161,23 +187,24 @@ BL::JobTab::job_selected(const QModelIndex & index) _job_state_label_value->setText("Paused"); else if (job->getState() == BL::Job::ERROR) _job_state_label_value->setText("Error"); + else if (job->getState() == BL::Job::FAILED) + _job_state_label_value->setText("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + _job_state_label_value->setText("Not Created"); else _job_state_label_value->setText("Finished"); + _job_launcher_label_value->setText(QVariant(job->getSalomeLauncherId()).toString()); + _job_jobfile_label_value->setText(QString(job->getJobFile().c_str())); + _job_envfile_label_value->setText(QString(job->getEnvFile().c_str())); if (job->getType() == BL::Job::YACS_SCHEMA) - { - _job_command_label->setText("Schema:"); - _job_command_label_value->setText(QString(job->getYACSFile().c_str())); _job_type_label_value->setText("YACS_Schema"); - } - else - { - _job_command_label->setText("Command:"); - _job_command_label_value->setText(QString(job->getCommand().c_str())); + else if (job->getType() == BL::Job::COMMAND) _job_type_label_value->setText("Command"); - } + else if (job->getType() == BL::Job::PYTHON_SALOME) + _job_type_label_value->setText("Python_Salome"); - _job_machine_label_value->setText(QString(job->getMachine().c_str())); + _job_resource_label_value->setText(QString(job->getResource().c_str())); BL::Job::BatchParam batch_params = job->getBatchParameters(); @@ -189,10 +216,12 @@ BL::JobTab::job_selected(const QModelIndex & index) _job_bd_label_value->setText(QString(batch_params.batch_directory.c_str())); _job_rd_label_value->setText(QString(files_params.result_directory.c_str())); - _job_edt_label_value->setText(QString(batch_params.expected_during_time.c_str())); + _job_mdt_label_value->setText(QString(batch_params.maximum_duration.c_str())); _job_em_label_value->setText(QString(batch_params.expected_memory.c_str())); _job_nop_label_value->setText(QVariant(batch_params.nb_proc).toString()); + _input_files_list->clear(); + _output_files_list->clear(); std::list::iterator it; for (it = files_params.input_files_list.begin(); it != files_params.input_files_list.end(); it++) { @@ -205,6 +234,23 @@ BL::JobTab::job_selected(const QModelIndex & index) _output_files_list->addItem(QString(file.c_str())); } + // Specific parameters management + if (job->getDumpYACSState() > 0) + { + // Add widget in the layout + _yacs_dump_state_value->setText(QVariant(job->getDumpYACSState()).toString()); + _main_values_form->insertRow(7, _yacs_dump_state_label, _yacs_dump_state_value); + } + if (job->getBatchQueue() != "") + { + _batch_queue_value->setText(QVariant(job->getBatchQueue().c_str()).toString()); + _other_run_values_form->insertRow(_other_run_values_form->rowCount(), _batch_queue_label, _batch_queue_value); + } + if (job->getLoadLevelerJobType() != "") + { + _ll_jobtype_value->setText(QVariant(job->getLoadLevelerJobType().c_str()).toString()); + _other_run_values_form->insertRow(_other_run_values_form->rowCount(), _ll_jobtype_label, _ll_jobtype_value); + } } else DEBTRACE ("itemFromIndex returns 0 !"); @@ -232,6 +278,10 @@ BL::JobTab::itemChanged(QStandardItem * item) _job_state_label_value->setText("Paused"); else if (job->getState() == BL::Job::ERROR) _job_state_label_value->setText("Error"); + else if (job->getState() == BL::Job::FAILED) + _job_state_label_value->setText("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + _job_state_label_value->setText("Not Created"); else _job_state_label_value->setText("Finished"); } @@ -240,20 +290,28 @@ BL::JobTab::itemChanged(QStandardItem * item) void BL::JobTab::reset(QString job_name) { - _job_name_label_value->setText(""); - _job_type_label_value->setText(""); - _job_state_label_value->setText(""); - _job_machine_label_value->setText(""); - _job_nif_label_value->setText(""); - _job_nof_label_value->setText(""); - _job_bd_label_value->setText(""); - _job_rd_label_value->setText(""); - _job_edt_label_value->setText(""); - _job_em_label_value->setText(""); - _job_nop_label_value->setText(""); - _job_command_label->setText("Schema or Command:"); - _job_command_label_value->setText(""); - - _input_files_list->clear(); - _output_files_list->clear(); + if (job_name == _job_name_label_value->text() || job_name == "") + { + _job_name_label_value->setText(""); + _job_type_label_value->setText(""); + _job_state_label_value->setText(""); + _job_launcher_label_value->setText(""); + _job_resource_label_value->setText(""); + _job_nif_label_value->setText(""); + _job_nof_label_value->setText(""); + _job_bd_label_value->setText(""); + _job_rd_label_value->setText(""); + _job_mdt_label_value->setText(""); + _job_em_label_value->setText(""); + _job_nop_label_value->setText(""); + _job_jobfile_label_value->setText(""); + _job_envfile_label_value->setText(""); + + _input_files_list->clear(); + _output_files_list->clear(); + + _yacs_dump_state_value->setText(""); + _batch_queue_value->setText(""); + _ll_jobtype_value->setText(""); + } } diff --git a/src/genericgui/BL_JobTab.hxx b/src/genericgui/BL_JobTab.hxx index 2f68cc0..44f5854 100644 --- a/src/genericgui/BL_JobTab.hxx +++ b/src/genericgui/BL_JobTab.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_JOBTAB_HXX_ @@ -24,7 +24,7 @@ #include "BL_JobsManager_QT.hxx" -namespace BL +namespace BL { class JobTab: public QTabWidget { @@ -38,9 +38,9 @@ namespace BL void createJobSummaryTab(); void createJobFilesTab(); + void job_selected(const QModelIndex & index); public slots: - void job_selected(const QModelIndex & index); void itemChanged(QStandardItem * item); void reset(QString job_name); @@ -50,24 +50,36 @@ namespace BL BL::JobsManager_QT * _jobs_manager; QWidget * _summary_tab; + QWidget * _files_tab; + // Main Values + QFormLayout * _main_values_form; QLabel * _job_name_label_value; QLabel * _job_type_label_value; QLabel * _job_state_label_value; - QLabel * _job_machine_label_value; - QLabel * _job_command_label; - QLabel * _job_command_label_value; + QLabel * _job_launcher_label_value; + QLabel * _job_resource_label_value; + QLabel * _job_jobfile_label_value; + QLabel * _job_envfile_label_value; // Run Values + QFormLayout * _run_values_form; + QFormLayout * _other_run_values_form; QLabel * _job_nif_label_value; QLabel * _job_nof_label_value; QLabel * _job_bd_label_value; QLabel * _job_rd_label_value; - QLabel * _job_edt_label_value; + QLabel * _job_mdt_label_value; QLabel * _job_em_label_value; QLabel * _job_nop_label_value; - QWidget * _files_tab; + // Specific Values + QLabel * _yacs_dump_state_label; + QLabel * _yacs_dump_state_value; + QLabel * _batch_queue_label; + QLabel * _batch_queue_value; + QLabel * _ll_jobtype_label; + QLabel * _ll_jobtype_value; QListWidget * _input_files_list; QListWidget * _output_files_list; diff --git a/src/genericgui/BL_JobsManager_QT.cxx b/src/genericgui/BL_JobsManager_QT.cxx index 04cc1b5..5e83edd 100644 --- a/src/genericgui/BL_JobsManager_QT.cxx +++ b/src/genericgui/BL_JobsManager_QT.cxx @@ -1,23 +1,24 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_JobsManager_QT.hxx" +#include "BL_GenericGui.hxx" BL::JobManagerEvent::JobManagerEvent(const std::string & action_i, const std::string & event_name_i, @@ -32,11 +33,13 @@ BL::JobManagerEvent::JobManagerEvent(const std::string & action_i, BL::JobManagerEvent::~JobManagerEvent() {} -BL::JobsManager_QT::JobsManager_QT(QWidget * parent, BL::SALOMEServices * salome_services) : +BL::JobsManager_QT::JobsManager_QT(QWidget * parent, BL::GenericGui * main_gui, BL::SALOMEServices * salome_services) : QDockWidget(parent), BL::JobsManager(salome_services) { DEBTRACE("Creating BL::JobsManager_QT"); + _main_gui = main_gui; setObserver(this); + _model_manager = NULL; // Widget Part @@ -44,6 +47,9 @@ BL::JobsManager_QT::JobsManager_QT(QWidget * parent, BL::SALOMEServices * salome _load_jobs = new QPushButton("Load Jobs"); _save_jobs = new QPushButton("Save Jobs"); + connect(_load_jobs, SIGNAL(clicked()), this, SLOT(load_jobs_button())); + connect(_save_jobs, SIGNAL(clicked()), this, SLOT(save_jobs_button())); + _auto_refresh_jobs = new QPushButton("Auto Refresh: no"); _timer = new QTimer(this); _timer->stop(); @@ -77,7 +83,10 @@ BL::JobsManager_QT::JobsManager_QT(QWidget * parent, BL::SALOMEServices * salome mainLayout->addWidget(message_box); main_widget->setLayout(mainLayout); - setWidget(main_widget); + QScrollArea * scroll_widget = new QScrollArea(this); + scroll_widget->setWidget(main_widget); + scroll_widget->setWidgetResizable(true); + setWidget(scroll_widget); setWindowTitle("Job Manager"); } @@ -86,6 +95,59 @@ BL::JobsManager_QT::~JobsManager_QT() DEBTRACE("Destroying BL::JobsManager_QT"); } +void +BL::JobsManager_QT::set_model_manager(BL::QModelManager * model_manager) +{ + _model_manager = model_manager; +} + +void +BL::JobsManager_QT::load_jobs_button() +{ + DEBTRACE("load_jobs"); + QString jobs_file = QFileDialog::getOpenFileName(this, + tr("Choose an xml jobs file"), "", + tr("xml (*.xml);;All Files (*)")); + if (jobs_file == "") + { + write_normal_text("Load jobs action cancelled\n"); + } + else + load_jobs(jobs_file.toStdString()); +} + +void +BL::JobsManager_QT::save_jobs_button() +{ + DEBTRACE("save_jobs"); + QFileDialog dialog(this, "Save jobs file"); + QStringList filters; + filters << "XML files (*.xml)" + << "Any files (*)"; + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setFilters(filters); + dialog.selectFilter("(*.xml)"); + dialog.setDefaultSuffix("xml"); + dialog.setConfirmOverwrite(true); + dialog.setAcceptMode(QFileDialog::AcceptSave); + QString jobs_file(""); + QStringList fileNames; + fileNames.clear(); + if (bool ret = dialog.exec()) + { + DEBTRACE(ret << " " << dialog.confirmOverwrite()); + fileNames = dialog.selectedFiles(); + if (!fileNames.isEmpty()) + jobs_file= fileNames.first(); + } + if (jobs_file == "") + { + write_normal_text("Save jobs action cancelled\n"); + } + else + save_jobs(jobs_file.toStdString()); +} + void BL::JobsManager_QT::RefreshJobs() { @@ -147,54 +209,51 @@ BL::JobsManager_QT::one_hour_refresh() _timer->start(1 * 60 * 60 * 1000); } +void +BL::JobsManager_QT::restart_job(const std::string & name) +{ + DEBTRACE("Restart job with name: " << name); + BL::CreateJobWizard wizard(this, _salome_services); + wizard.clone(name); + wizard.end(1); + wizard.job_name = name; + wizard.start_job = true; + _main_gui->delete_job_internal(); + create_job_with_wizard(wizard); +} + +void +BL::JobsManager_QT::edit_clone_job(const std::string & name) +{ + BL::CreateJobWizard wizard(this, _salome_services); + wizard.clone(name); + wizard.exec(); + + // Check if the job has the same name + if (name == wizard.job_name) + { + DEBTRACE("Job " << name << " has been edited"); + _main_gui->delete_job_internal(); + } + + if (wizard.job_name != "") + { + create_job_with_wizard(wizard); + } + else + { + DEBTRACE("User cancel Create Job Wizard"); + } +} + void -BL::JobsManager_QT::create_job_wizard() +BL::JobsManager_QT::create_job() { BL::CreateJobWizard wizard(this, _salome_services); wizard.exec(); - if (wizard.job_name != "") { - BL::Job * new_job = addNewJob(wizard.job_name); - if (wizard.yacs_file != "") - { - // YACS schema job - new_job->setType(BL::Job::YACS_SCHEMA); - new_job->setYACSFile(wizard.yacs_file); - BL::Job::BatchParam param; - param.batch_directory = wizard.batch_directory; - param.expected_during_time = wizard.expected_during_time; - param.expected_memory = wizard.expected_memory; - param.nb_proc = wizard.nb_proc; - new_job->setBatchParameters(param); - BL::Job::FilesParam files_params; - files_params.result_directory = wizard.result_directory; - files_params.input_files_list = wizard.input_files_list; - files_params.output_files_list = wizard.output_files_list; - new_job->setFilesParameters(files_params); - new_job->setMachine(wizard.machine_choosed); - } - else - { - // Command Job - new_job->setType(BL::Job::COMMAND); - new_job->setCommand(wizard.command); - BL::Job::BatchParam param; - param.batch_directory = wizard.batch_directory; - param.expected_during_time = wizard.expected_during_time; - param.expected_memory = wizard.expected_memory; - param.nb_proc = wizard.nb_proc; - new_job->setBatchParameters(param); - BL::Job::FilesParam files_params; - files_params.result_directory = wizard.result_directory; - files_params.input_files_list = wizard.input_files_list; - files_params.output_files_list = wizard.output_files_list; - new_job->setFilesParameters(files_params); - new_job->setMachine(wizard.machine_choosed); - } - emit new_job_added(QString::fromStdString(wizard.job_name)); - if (wizard.start_job) - start_job(wizard.job_name); + create_job_with_wizard(wizard); } else { @@ -202,10 +261,64 @@ BL::JobsManager_QT::create_job_wizard() } } +void +BL::JobsManager_QT::create_job_with_wizard(BL::CreateJobWizard & wizard) +{ + BL::Job * new_job = createJob(wizard.job_name); + if (wizard.yacs_file != "") + { + // YACS schema job + new_job->setType(BL::Job::YACS_SCHEMA); + new_job->setJobFile(wizard.yacs_file); + new_job->setDumpYACSState(wizard.dump_yacs_state); + } + else if (wizard.command != "") + { + // Command Job + new_job->setType(BL::Job::COMMAND); + new_job->setJobFile(wizard.command); + } + else if (wizard.python_salome_file != "") + { + // Command Job + new_job->setType(BL::Job::PYTHON_SALOME); + new_job->setJobFile(wizard.python_salome_file); + } + + // For all jobs + new_job->setEnvFile(wizard.env_file); + BL::Job::BatchParam param; + param.batch_directory = wizard.batch_directory; + param.maximum_duration = wizard.maximum_duration; + param.expected_memory = wizard.expected_memory; + param.nb_proc = wizard.nb_proc; + new_job->setBatchParameters(param); + BL::Job::FilesParam files_params; + files_params.result_directory = wizard.result_directory; + files_params.input_files_list = wizard.input_files_list; + files_params.output_files_list = wizard.output_files_list; + new_job->setFilesParameters(files_params); + new_job->setResource(wizard.resource_choosed); + new_job->setBatchQueue(wizard.batch_queue); + new_job->setLoadLevelerJobType(wizard.ll_jobtype); + + // End + addJobToLauncher(wizard.job_name); + emit new_job_added(QString::fromStdString(wizard.job_name)); + QStandardItemModel * model = _model_manager->getModel(); + QList item_list = model->findItems(QString::fromStdString(wizard.job_name)); + QStandardItem * job_state_item = model->item(item_list.at(0)->row(), 2); + _main_gui->_jobs_table->selectRow(item_list.at(0)->row()); + if (wizard.start_job) + start_job(wizard.job_name); +} + void BL::JobsManager_QT::delete_job(QString job_name) { BL::JobsManager::removeJob(job_name.toStdString()); + _model_manager->delete_job(job_name); + _main_gui->_job_tab->reset(job_name); } void @@ -233,7 +346,24 @@ BL::JobsManager_QT::event(QEvent * e) << event->event_name << " " << event->job_name << " " << event->data); - if (event->action == "start_job") + + if (event->action == "create_job") + { + if (event->event_name == "Ok") + { + QString str((event->job_name).c_str()); + write_normal_text("Job " + str + " created\n"); + } + else + { + QString str((event->job_name).c_str()); + write_error_text("Error in creating job: " + str + "\n"); + write_error_text("*** "); + write_error_text((event->data).c_str()); + write_error_text(" ***\n"); + } + } + else if (event->action == "start_job") { if (event->event_name == "Ok") { @@ -254,8 +384,10 @@ BL::JobsManager_QT::event(QEvent * e) { if (event->event_name == "Ok") { - QString str((event->job_name).c_str()); - write_normal_text("Job " + str + " state changed\n"); + QString name((event->job_name).c_str()); + QString state((event->data).c_str()); + state = state.toLower(); + write_normal_text("Job " + name + " new state is " + state + "\n"); emit job_state_changed(QString((event->job_name).c_str())); } else @@ -299,6 +431,66 @@ BL::JobsManager_QT::event(QEvent * e) write_error_text(" ***\n"); } } + else if (event->action == "stop_job") + { + if (event->event_name == "Ok") + { + QString str((event->job_name).c_str()); + write_normal_text("Job " + str + " is stopped\n"); + } + else + { + QString str((event->job_name).c_str()); + write_error_text("Error when trying to stop job: " + str + "\n"); + write_error_text("*** "); + write_error_text((event->data).c_str()); + write_error_text(" ***\n"); + } + } + else if (event->action == "save_jobs") + { + if (event->event_name == "Error") + { + write_error_text("Error in saving jobs: \n"); + write_error_text("*** "); + write_error_text((event->data).c_str()); + write_error_text(" ***\n"); + } + else + { + QString str((event->data).c_str()); + write_normal_text("Jobs saved in file " + str + "\n"); + } + } + else if (event->action == "load_jobs") + { + if (event->event_name == "Error") + { + write_error_text("Error in loading jobs: \n"); + write_error_text("*** "); + write_error_text((event->data).c_str()); + write_error_text(" ***\n"); + } + else + { + QString str((event->data).c_str()); + write_normal_text("Jobs loaded from file " + str + "\n"); + } + } + else if (event->action == "add_job") + { + if (event->event_name == "Ok") + { + QString str((event->job_name).c_str()); + write_normal_text("New job added " + str + "\n"); + emit new_job_added(str); + } + } + else if (event->action == "to_remove_job") + { + if (event->event_name == "Ok") + _main_gui->delete_job_external((event->job_name).c_str()); + } else { QString str((event->action).c_str()); @@ -322,9 +514,11 @@ BL::JobsManager_QT::write_normal_text(const QString & text) void BL::JobsManager_QT::write_error_text(const QString & text) { + _log->setReadOnly(false); QTextCursor cursor = _log->textCursor(); QTextCharFormat text_format; text_format.setForeground(Qt::red); cursor.insertText(text, text_format); _log->setTextCursor(cursor); + _log->setReadOnly(true); } diff --git a/src/genericgui/BL_JobsManager_QT.hxx b/src/genericgui/BL_JobsManager_QT.hxx index b1b0980..d26d689 100644 --- a/src/genericgui/BL_JobsManager_QT.hxx +++ b/src/genericgui/BL_JobsManager_QT.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_JOBSMANAGER_QT_HXX_ @@ -25,6 +25,8 @@ #include "BL_Traces.hxx" #include "BL_JobsManager.hxx" #include "BL_CreateJobWizard.hxx" +#include "BL_JobsManager.hxx" +#include "BL_QModelManager.hxx" #include @@ -34,9 +36,9 @@ namespace BL{ { public: JobManagerEvent(const std::string & action_i, - const std::string & event_name_i, - const std::string & job_name_i, - const std::string & data_i); + const std::string & event_name_i, + const std::string & job_name_i, + const std::string & data_i); virtual ~JobManagerEvent(); public: @@ -46,28 +48,37 @@ namespace BL{ std::string data; }; + class GenericGui; class JobsManager_QT: virtual public QDockWidget, - virtual public BL::JobsManager, - virtual public BL::Observer + virtual public BL::JobsManager, + virtual public BL::Observer { Q_OBJECT public: - JobsManager_QT(QWidget * parent, BL::SALOMEServices * salome_services); + JobsManager_QT(QWidget * parent, BL::GenericGui * main_gui, BL::SALOMEServices * salome_services); virtual ~JobsManager_QT(); void delete_job(QString job_name); - void create_job_wizard(); + + void create_job(); + void edit_clone_job(const std::string & name); + void restart_job(const std::string & name); virtual void sendEvent(const std::string & action, - const std::string & event_name, - const std::string & job_name, - const std::string & data); + const std::string & event_name, + const std::string & job_name, + const std::string & data); bool event(QEvent * e); void write_normal_text(const QString & text); void write_error_text(const QString & text); + void set_model_manager(BL::QModelManager * model_manager); + + protected: + void create_job_with_wizard(BL::CreateJobWizard & wizard); + public slots: void RefreshJobs(); void no_auto_refresh(); @@ -77,6 +88,8 @@ namespace BL{ void five_minutes_refresh(); void thirty_minutes_refresh(); void one_hour_refresh(); + void load_jobs_button(); + void save_jobs_button(); signals: void new_job_added(const QString & name); @@ -88,6 +101,8 @@ namespace BL{ QPushButton * _auto_refresh_jobs; QTimer * _timer; QTextEdit * _log; + BL::GenericGui * _main_gui; + BL::QModelManager * _model_manager; }; } diff --git a/src/genericgui/BL_JobsTable.cxx b/src/genericgui/BL_JobsTable.cxx index 8a1f3fb..fe4b856 100644 --- a/src/genericgui/BL_JobsTable.cxx +++ b/src/genericgui/BL_JobsTable.cxx @@ -1,39 +1,43 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_JobsTable.hxx" #include "BL_Traces.hxx" +#include "BL_GenericGui.hxx" BL::JobsTable::JobsTable(QWidget *parent) : QTableView(parent) { DEBTRACE("Creating BL::JobsTable"); BL_ASSERT(parent); _parent = parent; + _main_gui = NULL; // Init setShowGrid(false); setCornerButtonEnabled(false); setEditTriggers(QAbstractItemView::NoEditTriggers); - setSelectionBehavior(QAbstractItemView::SelectRows); setAlternatingRowColors(true); setSortingEnabled(true); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ExtendedSelection); + QHeaderView * header_view = verticalHeader(); header_view->setClickable(false); } @@ -42,3 +46,80 @@ BL::JobsTable::~JobsTable() { DEBTRACE("Destroying BL::JobsTable"); } + +bool +BL::JobsTable::selectCurrent() +{ + QModelIndex idx = currentIndex(); + if (idx.row() > -1) + if (!isMultipleSelected()) + { + DEBTRACE("SELECT CURRENT ACTIVATION !!!"); + setCurrentIndex(idx); + activated(idx); + return true; + } + return false; +} + +void +BL::JobsTable::set_main_gui(BL::GenericGui * main_gui) +{ + _main_gui = main_gui; +} + +void +BL::JobsTable::selectionChanged ( const QItemSelection & selected, const QItemSelection & deselected ) +{ + QTableView::selectionChanged(selected, deselected); + DEBTRACE("selection changed"); + QModelIndexList selected_rows = selectionModel()->selectedRows(); + if (selected_rows.length() == 0) + { + _main_gui->reset_job_selection(); + } + else if (selected_rows.length() == 1) + { + DEBTRACE("SELECTED CHANGED ACTIVATION !!!"); + DEBTRACE("ROW NUMBER: " << selected_rows[0].row()); + QModelIndex current = selected_rows[0]; + if (!selectionModel()->isSelected(current)) + { + setCurrentIndex(current); + } + activated(current); + } + DEBTRACE("Number of selected rows selection: " << selected_rows.length()); +} + +void +BL::JobsTable::currentChanged(const QModelIndex & current, const QModelIndex & previous) +{ + QTableView::currentChanged(current, previous); + DEBTRACE("current changed"); + DEBTRACE("current row: " << current.row()); + if (current.row() > -1) + if (!isMultipleSelected()) + { + DEBTRACE("CURRENT CHANGED ACTIVATION !!!"); + //setCurrentIndex(current); + //activated(current); + } +} + +bool +BL::JobsTable::isMultipleSelected() +{ + QModelIndexList selected_rows = selectionModel()->selectedRows(); + DEBTRACE("Number of selected rows: " << selected_rows.length()); + if (selected_rows.length() > 1) + return true; + else + return false; +} + +QModelIndexList +BL::JobsTable::getSelectedIndexes() +{ + return selectedIndexes(); +} diff --git a/src/genericgui/BL_JobsTable.hxx b/src/genericgui/BL_JobsTable.hxx index ace8b2f..2a356e3 100644 --- a/src/genericgui/BL_JobsTable.hxx +++ b/src/genericgui/BL_JobsTable.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_JOBSTABLE_HXX_ @@ -22,8 +22,9 @@ #include -namespace BL +namespace BL { + class GenericGui; class JobsTable: public QTableView { Q_OBJECT @@ -32,9 +33,20 @@ namespace BL JobsTable(QWidget *parent); virtual ~JobsTable(); + bool selectCurrent(); + bool isMultipleSelected(); + QModelIndexList getSelectedIndexes(); + void set_main_gui(BL::GenericGui * main_gui); + protected: QWidget* _parent; + protected slots: + void selectionChanged ( const QItemSelection & selected, const QItemSelection & deselected ); + void currentChanged(const QModelIndex & current, const QModelIndex & previous); + + private: + BL::GenericGui * _main_gui; }; } diff --git a/src/genericgui/BL_MachineCatalog.cxx b/src/genericgui/BL_MachineCatalog.cxx deleted file mode 100644 index eae8ded..0000000 --- a/src/genericgui/BL_MachineCatalog.cxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "BL_MachineCatalog.hxx" -#include "BL_Traces.hxx" - -BL::MachineCatalog::MachineCatalog(QWidget *parent, BL::SALOMEServices * salome_services) : QWidget(parent) -{ - DEBTRACE("Creating BL::MachineCatalog"); - BL_ASSERT(parent); - BL_ASSERT(salome_services); - _parent = parent; - _salome_services = salome_services; - - _refresh_button = new QPushButton("Refresh Machine List"); - _refresh_button->show(); - connect(_refresh_button, SIGNAL(clicked()), this, SLOT(refresh_machine_list())); - _machine_files_list = new QListWidget(this); - _machine_files_list->setSelectionMode(QAbstractItemView::NoSelection); - std::list machine_list = _salome_services->getMachineList(); - std::list::iterator it; - for (it = machine_list.begin(); it != machine_list.end(); it++) - { - std::string machine = *it; - _machine_files_list->addItem(QString(machine.c_str())); - } - - QVBoxLayout * mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(_refresh_button); - mainLayout->addWidget(_machine_files_list); - setLayout(mainLayout); -} - -BL::MachineCatalog::~MachineCatalog() -{ - DEBTRACE("Destroying BL::MachineCatalog"); -} - -void -BL::MachineCatalog::refresh_machine_list() -{ - _machine_files_list->clear(); - std::list machine_list = _salome_services->getMachineList(); - std::list::iterator it; - for (it = machine_list.begin(); it != machine_list.end(); it++) - { - std::string machine = *it; - _machine_files_list->addItem(QString(machine.c_str())); - } -} diff --git a/src/genericgui/BL_MachineCatalog.hxx b/src/genericgui/BL_MachineCatalog.hxx deleted file mode 100644 index 95355b4..0000000 --- a/src/genericgui/BL_MachineCatalog.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _BL_MACHINECATALOG_HXX_ -#define _BL_MACHINECATALOG_HXX_ - -#include - -#include "BL_SALOMEServices.hxx" - -#include -#include - -namespace BL -{ - class MachineCatalog: public QWidget - { - Q_OBJECT - - public: - MachineCatalog(QWidget *parent, BL::SALOMEServices * salome_services); - virtual ~MachineCatalog(); - - public slots: - void refresh_machine_list(); - - protected: - QWidget* _parent; - BL::SALOMEServices * _salome_services; - - QPushButton * _refresh_button; - QListWidget * _machine_files_list; - }; -} - -#endif - - diff --git a/src/genericgui/BL_MainButtons.cxx b/src/genericgui/BL_MainButtons.cxx deleted file mode 100644 index e69de29..0000000 diff --git a/src/genericgui/BL_MainButtons.hxx b/src/genericgui/BL_MainButtons.hxx deleted file mode 100644 index e69de29..0000000 diff --git a/src/genericgui/BL_QModelManager.cxx b/src/genericgui/BL_QModelManager.cxx index 6412dd2..a8324ec 100644 --- a/src/genericgui/BL_QModelManager.cxx +++ b/src/genericgui/BL_QModelManager.cxx @@ -1,23 +1,28 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_QModelManager.hxx" +#include "BL_JobsManager_QT.hxx" + +#ifdef WNT +#undef ERROR +#endif BL::QModelManager::QModelManager(QObject * parent, BL::JobsManager_QT * jobs_manager) : QObject(parent) { @@ -26,8 +31,9 @@ BL::QModelManager::QModelManager(QObject * parent, BL::JobsManager_QT * jobs_man _jobs_manager = jobs_manager; _model = new QStandardItemModel(this); + jobs_manager->set_model_manager(this); QStringList headers; - headers << "Job Name" << "Type" << "State" << "Machine"; + headers << "Job Name" << "Type" << "State" << "Resource" << "Launcher Id"; _model->setHorizontalHeaderLabels(headers); } @@ -47,14 +53,17 @@ BL::QModelManager::getModel() void BL::QModelManager::new_job_added(const QString & name) { + DEBTRACE("Adding new job in the model manager"); BL::Job * job = _jobs_manager->getJob(name.toStdString()); QStandardItem * new_job_name = new QStandardItem(name); QStandardItem * new_job_type; if (job->getType() == BL::Job::YACS_SCHEMA) new_job_type = new QStandardItem("YACS_Schema"); - else + else if (job->getType() == BL::Job::COMMAND) new_job_type = new QStandardItem("Command"); + else if (job->getType() == BL::Job::PYTHON_SALOME) + new_job_type = new QStandardItem("Python_Salome"); QStandardItem * new_job_state; if (job->getState() == BL::Job::CREATED) @@ -67,16 +76,24 @@ BL::QModelManager::new_job_added(const QString & name) new_job_state = new QStandardItem("Paused"); else if (job->getState() == BL::Job::ERROR) new_job_state = new QStandardItem("Error"); + else if (job->getState() == BL::Job::FAILED) + new_job_state = new QStandardItem("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + new_job_state = new QStandardItem("Not Created"); else new_job_state = new QStandardItem("Finished"); - QStandardItem * new_job_machine = new QStandardItem(job->getMachine().c_str()); + QStandardItem * new_job_resource = new QStandardItem(job->getResource().c_str()); + QString id_str; + id_str.setNum(job->getSalomeLauncherId()); + QStandardItem * new_job_id = new QStandardItem(id_str); int row = _model->rowCount(); _model->setItem(row, 0, new_job_name); _model->setItem(row, 1, new_job_type); _model->setItem(row, 2, new_job_state); - _model->setItem(row, 3, new_job_machine); + _model->setItem(row, 3, new_job_resource); + _model->setItem(row, 4, new_job_id); } void @@ -98,34 +115,23 @@ BL::QModelManager::job_state_changed(const QString & name) job_state_item->setText("Paused"); else if (job->getState() == BL::Job::ERROR) job_state_item->setText("Error"); + else if (job->getState() == BL::Job::FAILED) + job_state_item->setText("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + job_state_item->setText("Not Created"); else job_state_item->setText("Finished"); } void -BL::QModelManager::deleteJob(int row) +BL::QModelManager::delete_job(const QString & name) { - _model->removeRow(row); -} - -void -BL::QModelManager::job_selected(const QModelIndex & index) -{ - DEBTRACE("BL::QModelManager::job_selected slot"); - QStandardItem * item = _model->itemFromIndex(index); - int row = item->row(); - - // Algo un peu bourrin.... - for (int i = 0; i < _model->rowCount(); i++) - for (int j = 0; j < _model->columnCount(); j++) - { - _model->item(i,j)->setBackground(QBrush(Qt::white)); - _model->item(i,j)->setForeground(QBrush(Qt::black)); - } - - for (int j = 0; j < _model->columnCount(); j++) + QList list = _model->findItems(name); + if (list.size() != 1) { - _model->item(row,j)->setBackground(QBrush(Qt::darkBlue)); - _model->item(row,j)->setForeground(QBrush(Qt::white)); + DEBMSG("LIST SIZE IS :" << list.size()); + DEBMSG("FOR NAME :" << name.toStdString()); } + if (list.size() > 0) + _model->removeRow(list[0]->row()); } diff --git a/src/genericgui/BL_QModelManager.hxx b/src/genericgui/BL_QModelManager.hxx index 868d93a..d5dfee5 100644 --- a/src/genericgui/BL_QModelManager.hxx +++ b/src/genericgui/BL_QModelManager.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_QMODELMANAGER_HXX_ @@ -23,10 +23,10 @@ #include #include "BL_Job.hxx" -#include "BL_JobsManager_QT.hxx" namespace BL{ + class JobsManager_QT; class QModelManager: virtual public QObject { Q_OBJECT @@ -37,12 +37,11 @@ namespace BL{ QStandardItemModel * getModel(); - void deleteJob(int row); + void delete_job(const QString & name); public slots: void new_job_added(const QString & name); void job_state_changed(const QString & name); - void job_selected(const QModelIndex & index); private: QStandardItemModel * _model; diff --git a/src/genericgui/BL_Summary.cxx b/src/genericgui/BL_Summary.cxx index 4cb67fc..cd58ab8 100644 --- a/src/genericgui/BL_Summary.cxx +++ b/src/genericgui/BL_Summary.cxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "BL_Summary.hxx" diff --git a/src/genericgui/BL_Summary.hxx b/src/genericgui/BL_Summary.hxx index b972388..9cf5fcd 100644 --- a/src/genericgui/BL_Summary.hxx +++ b/src/genericgui/BL_Summary.hxx @@ -1,20 +1,20 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #ifndef _BL_SUMMARY_HXX_ diff --git a/src/genericgui/JM_EditSalomeResource.cxx b/src/genericgui/JM_EditSalomeResource.cxx new file mode 100644 index 0000000..9d1edf6 --- /dev/null +++ b/src/genericgui/JM_EditSalomeResource.cxx @@ -0,0 +1,391 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "JM_EditSalomeResource.hxx" +#include "BL_Traces.hxx" + +JM::EditSalomeResource::EditSalomeResource(QWidget *parent, BL::SALOMEServices * salome_services, + const std::string & resource_name) : QDialog(parent) +{ + DEBTRACE("Creating JM::EditSalomeResource"); + BL_ASSERT(parent); + BL_ASSERT(salome_services); + _parent = parent; + _salome_services = salome_services; + _resource_name = resource_name; + + //setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + // Widget code + + // Part 1 + QGroupBox * main_groupBox = new QGroupBox("Main values"); + QLabel * name_label = new QLabel("Name:"); + _name_line = new QLineEdit(this); + QLabel * hostname_label = new QLabel("Hostname:"); + _hostname_line = new QLineEdit(this); + QLabel * username_label = new QLabel("Username:"); + _username_line = new QLineEdit(this); + QLabel * applipath_label = new QLabel("Applipath:"); + _applipath_line = new QLineEdit(this); + + QLabel * protocol_label = new QLabel("Protocol:"); + _protocol_line = new QComboBox(this); + _protocol_line->addItem("ssh"); + _protocol_line->addItem("rsh"); + _protocol_line->addItem("srun"); + _protocol_line->addItem("pbsdsh"); + _protocol_line->addItem("blaunch"); + _protocol_line->setCurrentIndex(-1); + + QLabel * componentList_label = new QLabel("Component List:"); + _add_button = new QPushButton("Add"); + _remove_button = new QPushButton("Remove"); + _remove_button->setEnabled(false); + QWidget * component_widget = new QWidget(this); + _componentList = new QListWidget(this); + _componentList->setSelectionMode(QAbstractItemView::MultiSelection); + QGridLayout * input_box = new QGridLayout(this); + input_box->addWidget(_add_button, 0, 0); + input_box->addWidget(_remove_button, 0, 1); + input_box->addWidget(_componentList, 1, 0, 1, -1); + component_widget->setLayout(input_box); + connect(_add_button, SIGNAL(clicked()), this, SLOT(add_component())); + connect(_remove_button, SIGNAL(clicked()), this, SLOT(remove_components())); + connect(_componentList, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); + + QLabel * working_directory_label = new QLabel("Working Directory:"); + _working_directory = new QLineEdit(this); + QLabel * is_cluster_head_label = new QLabel("Is Cluster Head:"); + _is_cluster_head = new QPushButton(this); + _is_cluster_head->setCheckable(true); + connect(_is_cluster_head, SIGNAL(toggled(bool)), this, SLOT(toggle_is_cluster_head(bool))); + toggle_is_cluster_head(false); // Default is false + + QGridLayout * m_layout = new QGridLayout; + m_layout->addWidget(name_label, 0, 0); + m_layout->addWidget(_name_line, 0, 1); + m_layout->addWidget(hostname_label, 1, 0); + m_layout->addWidget(_hostname_line, 1, 1); + m_layout->addWidget(protocol_label, 2, 0); + m_layout->addWidget(_protocol_line, 2, 1); + m_layout->addWidget(username_label, 3, 0); + m_layout->addWidget(_username_line, 3, 1); + m_layout->addWidget(applipath_label, 4, 0); + m_layout->addWidget(_applipath_line, 4, 1); + m_layout->addWidget(componentList_label, 5, 0); + m_layout->addWidget(component_widget, 5, 1); + m_layout->addWidget(is_cluster_head_label, 6, 0); + m_layout->addWidget(_is_cluster_head, 6, 1); + m_layout->addWidget(working_directory_label, 7, 0); + m_layout->addWidget(_working_directory, 7, 1); + main_groupBox->setLayout(m_layout); + + // Part 2 + QGroupBox * config_groupBox = new QGroupBox("Configuration values"); + QLabel * os_label = new QLabel("OS:"); + _os_line = new QLineEdit(this); + + QLabel * mem_mb_label = new QLabel("Memory (mb):"); + _mem_mb_line = new QSpinBox(this); + _mem_mb_line->setMinimum(0); + _mem_mb_line->setMaximum(1000000); + _mem_mb_line->setValue(0); + QLabel * cpu_clock_label = new QLabel("CPU Clock:"); + _cpu_clock_line = new QSpinBox(this); + _cpu_clock_line->setMinimum(0); + _cpu_clock_line->setMaximum(1000000); + _cpu_clock_line->setValue(0); + QLabel * nb_node_label = new QLabel("Nb node:"); + _nb_node_line = new QSpinBox(this); + _nb_node_line->setMinimum(1); + _nb_node_line->setMaximum(1000000); + _nb_node_line->setValue(1); + QLabel * nb_proc_per_node_label = new QLabel("Nb proc/node:"); + _nb_proc_per_node_line = new QSpinBox(this); + _nb_proc_per_node_line->setMinimum(1); + _nb_proc_per_node_line->setMaximum(1000000); + _nb_proc_per_node_line->setValue(1); + + QLabel * iprotocol_label = new QLabel("Internal protocol:"); + _iprotocol_line = new QComboBox(this); + _iprotocol_line->addItem("ssh"); + _iprotocol_line->addItem("rsh"); + _iprotocol_line->addItem("srun"); + _iprotocol_line->addItem("pbsdsh"); + _iprotocol_line->addItem("blaunch"); + _iprotocol_line->setCurrentIndex(-1); + + QLabel * batch_label = new QLabel("Batch:"); + _batch_line = new QComboBox(this); + _batch_line->addItem("pbs"); + _batch_line->addItem("lsf"); + _batch_line->addItem("sge"); + _batch_line->addItem("ssh"); + _batch_line->addItem("ccc"); + _batch_line->addItem("slurm"); + _batch_line->addItem("ll"); + _batch_line->addItem("vishnu"); + _batch_line->setCurrentIndex(-1); + + QLabel * mpiImpl_label = new QLabel("MPI impl:"); + _mpiImpl_line = new QComboBox(this); + _mpiImpl_line->addItem("lam"); + _mpiImpl_line->addItem("mpich1"); + _mpiImpl_line->addItem("mpich2"); + _mpiImpl_line->addItem("openmpi"); + _mpiImpl_line->addItem("slurmmpi"); + _mpiImpl_line->addItem("prun"); + _mpiImpl_line->setCurrentIndex(-1); + + QGridLayout * c_layout = new QGridLayout; + c_layout->addWidget(os_label, 0, 0); + c_layout->addWidget(_os_line, 0, 1); + c_layout->addWidget(mem_mb_label, 1, 0); + c_layout->addWidget(_mem_mb_line, 1, 1); + c_layout->addWidget(cpu_clock_label, 2, 0); + c_layout->addWidget(_cpu_clock_line, 2, 1); + c_layout->addWidget(nb_node_label, 3, 0); + c_layout->addWidget(_nb_node_line, 3, 1); + c_layout->addWidget(nb_proc_per_node_label, 4, 0); + c_layout->addWidget(_nb_proc_per_node_line, 4, 1); + c_layout->addWidget(batch_label, 5, 0); + c_layout->addWidget(_batch_line, 5, 1); + c_layout->addWidget(mpiImpl_label, 6, 0); + c_layout->addWidget(_mpiImpl_line, 6, 1); + c_layout->addWidget(iprotocol_label, 7, 0); + c_layout->addWidget(_iprotocol_line, 7, 1); + config_groupBox->setLayout(c_layout); + + // Part 3 + QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok + | QDialogButtonBox::Cancel); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + // Main Layout + QVBoxLayout * mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(main_groupBox); + mainLayout->addWidget(config_groupBox); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + + setWindowTitle("Edit/Add a resource"); + if (_resource_name != "") + get_infos(); +} + +JM::EditSalomeResource::~EditSalomeResource() +{ + DEBTRACE("Destroying JM::EditSalomeResource"); +} + +void +JM::EditSalomeResource::get_infos() +{ + BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(_resource_name); + + _name_line->setText(QString(resource_descr.name.c_str())); + _hostname_line->setText(QString(resource_descr.hostname.c_str())); + _username_line->setText(QString(resource_descr.username.c_str())); + _applipath_line->setText(QString(resource_descr.applipath.c_str())); + _os_line->setText(QString(resource_descr.OS.c_str())); + _working_directory->setText(QString(resource_descr.working_directory.c_str())); + _is_cluster_head->setChecked(resource_descr.is_cluster_head); + + std::string protocol = resource_descr.protocol.c_str(); + if (protocol == "ssh") + _protocol_line->setCurrentIndex(0); + else if(protocol == "rsh") + _protocol_line->setCurrentIndex(1); + else if(protocol == "srun") + _protocol_line->setCurrentIndex(2); + else if(protocol == "pbsdsh") + _protocol_line->setCurrentIndex(3); + else if(protocol == "blaunch") + _protocol_line->setCurrentIndex(4); + else + _protocol_line->setCurrentIndex(-1); + + std::string iprotocol = resource_descr.iprotocol.c_str(); + if (iprotocol == "ssh") + _iprotocol_line->setCurrentIndex(0); + else if (iprotocol == "rsh") + _iprotocol_line->setCurrentIndex(1); + else if (iprotocol == "srun") + _iprotocol_line->setCurrentIndex(2); + else if (iprotocol == "pbsdsh") + _iprotocol_line->setCurrentIndex(3); + else if (iprotocol == "blaunch") + _iprotocol_line->setCurrentIndex(4); + else + _iprotocol_line->setCurrentIndex(-1); + + std::string batch = resource_descr.batch.c_str(); + if (batch == "pbs") + _batch_line->setCurrentIndex(0); + else if (batch == "lsf") + _batch_line->setCurrentIndex(1); + else if (batch == "sge") + _batch_line->setCurrentIndex(2); + else if (batch == "ssh") + _batch_line->setCurrentIndex(3); + else if (batch == "ccc") + _batch_line->setCurrentIndex(4); + else if (batch == "slurm") + _batch_line->setCurrentIndex(5); + else if (batch == "ll") + _batch_line->setCurrentIndex(6); + else if (batch == "vishnu") + _batch_line->setCurrentIndex(7); + else + _batch_line->setCurrentIndex(-1); + + std::string mpiImpl = resource_descr.mpiImpl.c_str(); + if (mpiImpl == "lam") + _mpiImpl_line->setCurrentIndex(0); + else if (mpiImpl == "mpich1") + _mpiImpl_line->setCurrentIndex(1); + else if (mpiImpl == "mpich2") + _mpiImpl_line->setCurrentIndex(2); + else if (mpiImpl == "openmpi") + _mpiImpl_line->setCurrentIndex(3); + else if (mpiImpl == "slurmmpi") + _mpiImpl_line->setCurrentIndex(4); + else if (mpiImpl == "prun") + _mpiImpl_line->setCurrentIndex(5); + else + _mpiImpl_line->setCurrentIndex(-1); + + int value = resource_descr.mem_mb; + if (value > 0) + _mem_mb_line->setValue(value); + value = resource_descr.cpu_clock; + if (value > 0) + _cpu_clock_line->setValue(value); + value = resource_descr.nb_node; + if (value > 1) + _nb_node_line->setValue(value); + value = resource_descr.nb_proc_per_node; + if (value > 1) + _nb_proc_per_node_line->setValue(value); + + std::list::iterator it = resource_descr.componentList.begin(); + for(; it != resource_descr.componentList.end(); it++) + _componentList->addItem(QString((*it).c_str())); + + // Better if string's length is bigger than the widget + _name_line->setCursorPosition(0); + _hostname_line->setCursorPosition(0); + _username_line->setCursorPosition(0); + _applipath_line->setCursorPosition(0); + _os_line->setCursorPosition(0); + _working_directory->setCursorPosition(0); +} + + +void +JM::EditSalomeResource::itemSelectionChanged() +{ + if (_componentList->selectedItems().size() > 0) + _remove_button->setEnabled(true); + else + _remove_button->setEnabled(false); +} + +void +JM::EditSalomeResource::add_component() +{ + bool ok; + QString text = QInputDialog::getText(this, "Add a component", + "Component name:", QLineEdit::Normal, + "", &ok); + if (ok && !text.isEmpty()) + _componentList->addItem(text); +} + +void +JM::EditSalomeResource::remove_components() +{ + QList list = _componentList->selectedItems(); + for (int i = 0; i < list.size(); ++i) + { + int row = _componentList->row( list.at(i) ); + delete _componentList->takeItem(row); + } +} + +void +JM::EditSalomeResource::accept() +{ + BL::ResourceDescr resource; + + // Text + resource.name = _name_line->text().toStdString(); + resource.hostname = _hostname_line->text().toStdString(); + resource.username = _username_line->text().toStdString(); + resource.applipath = _applipath_line->text().toStdString(); + resource.OS = _os_line->text().toStdString(); + resource.working_directory = _working_directory->text().toStdString(); + if (_is_cluster_head->isChecked()) + resource.is_cluster_head = true; + else + resource.is_cluster_head = false; + + // Components + int count = _componentList->count(); + for (int i = 0; i < count; i++) + resource.componentList.push_back(_componentList->item(i)->text().toStdString()); + + // ComboBox + resource.protocol = _protocol_line->currentText().toStdString(); + resource.iprotocol = _iprotocol_line->currentText().toStdString(); + resource.batch = _batch_line->currentText().toStdString(); + if (resource.batch == "ssh") + resource.batch = "ssh_batch"; + resource.mpiImpl = _mpiImpl_line->currentText().toStdString(); + + // QSpinBox + resource.mem_mb = _mem_mb_line->value(); + resource.cpu_clock = _cpu_clock_line->value(); + resource.nb_node = _nb_node_line->value(); + resource.nb_proc_per_node = _nb_proc_per_node_line->value(); + + if (resource.name != "" && + resource.hostname != "" && + resource.protocol != "") + { + _salome_services->addResource(resource); + QDialog::accept(); + } + else + { + QMessageBox::warning(NULL, "Values missing", "name, hostname and protocol are mandatory! Cancel or add values!"); + } +} + +void +JM::EditSalomeResource::toggle_is_cluster_head(bool checked) +{ + if (checked) + _is_cluster_head->setText("true"); + else + _is_cluster_head->setText("false"); +} diff --git a/src/genericgui/JM_EditSalomeResource.hxx b/src/genericgui/JM_EditSalomeResource.hxx new file mode 100644 index 0000000..0938ca8 --- /dev/null +++ b/src/genericgui/JM_EditSalomeResource.hxx @@ -0,0 +1,80 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _JM_EDITSALOMERESOURCE_HXX_ +#define _JM_EDITSALOMERESOURCE_HXX_ + +#include +#include +#include "BL_SALOMEServices.hxx" + +namespace JM +{ + class EditSalomeResource: public QDialog + { + Q_OBJECT + + public: + EditSalomeResource(QWidget *parent, + BL::SALOMEServices * salome_services, + const std::string & resource_name = ""); + virtual ~EditSalomeResource(); + + void get_infos(); + + public slots: + virtual void accept(); + void add_component(); + void remove_components(); + void itemSelectionChanged(); + void toggle_is_cluster_head(bool checked); + + protected: + QWidget* _parent; + BL::SALOMEServices * _salome_services; + std::string _resource_name; + + // widget + QLineEdit * _name_line; + QLineEdit * _hostname_line; + QLineEdit * _username_line; + QLineEdit * _applipath_line; + QListWidget * _componentList; + QLineEdit * _os_line; + + QComboBox * _protocol_line; + QComboBox * _iprotocol_line; + QComboBox * _batch_line; + QComboBox * _mpiImpl_line; + + QSpinBox * _mem_mb_line; + QSpinBox * _cpu_clock_line; + QSpinBox * _nb_node_line; + QSpinBox * _nb_proc_per_node_line; + + QLineEdit * _working_directory; + QPushButton * _is_cluster_head; + + QPushButton * _add_button; + QPushButton * _remove_button; + }; +} + +#endif + diff --git a/src/genericgui/JM_ResourceCatalog.cxx b/src/genericgui/JM_ResourceCatalog.cxx new file mode 100644 index 0000000..749f0af --- /dev/null +++ b/src/genericgui/JM_ResourceCatalog.cxx @@ -0,0 +1,171 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "JM_ResourceCatalog.hxx" +#include "BL_Traces.hxx" +#include "JM_SalomeResource.hxx" +#include "JM_EditSalomeResource.hxx" + +JM::ResourceCatalog::ResourceCatalog(QWidget *parent, BL::SALOMEServices * salome_services) : QWidget(parent) +{ + DEBTRACE("Creating JM::ResourceCatalog"); + BL_ASSERT(parent); + BL_ASSERT(salome_services); + _parent = parent; + _salome_services = salome_services; + + _refresh_button = new QPushButton("Refresh Resource List"); + _refresh_button->show(); + _resource_files_list = new QListWidget(this); + _resource_files_list->setSelectionMode(QAbstractItemView::SingleSelection); + std::list resource_list = _salome_services->getResourceList(); + std::list::iterator it; + for (it = resource_list.begin(); it != resource_list.end(); it++) + { + std::string resource = *it; + _resource_files_list->addItem(QString(resource.c_str())); + } + + _show_button = new QPushButton("Show"); + _show_button->setEnabled(false); + _edit_button = new QPushButton("Edit"); + _edit_button->setEnabled(false); + _add_button = new QPushButton("Add"); + _remove_button = new QPushButton("Remove"); + _remove_button->setEnabled(false); + + QHBoxLayout * button_layout = new QHBoxLayout(this); + button_layout->addWidget(_show_button); + button_layout->addWidget(_edit_button); + button_layout->addWidget(_add_button); + button_layout->addWidget(_remove_button); + QWidget * layout_widget = new QWidget(this); + layout_widget->setLayout(button_layout); + + QVBoxLayout * mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(_refresh_button); + mainLayout->addWidget(_resource_files_list); + mainLayout->addWidget(layout_widget); + setLayout(mainLayout); + + // Buttons + connect(_refresh_button, SIGNAL(clicked()), this, SLOT(refresh_resource_list())); + connect(_show_button, SIGNAL(clicked()), this, SLOT(show_button())); + connect(_edit_button, SIGNAL(clicked()), this, SLOT(edit_button())); + connect(_add_button, SIGNAL(clicked()), this, SLOT(add_button())); + connect(_remove_button, SIGNAL(clicked()), this, SLOT(remove_button())); + // Double click on an item + connect(_resource_files_list, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(item_choosed(QListWidgetItem*))); + // Selection management + connect(_resource_files_list, SIGNAL(itemSelectionChanged()), this, SLOT(buttons_management())); +} + +JM::ResourceCatalog::~ResourceCatalog() +{ + DEBTRACE("Destroying JM::ResourceCatalog"); +} + +QListWidget * +JM::ResourceCatalog::getQListWidget() +{ + return _resource_files_list; +} + +void +JM::ResourceCatalog::refresh_resource_list() +{ + _resource_files_list->clear(); + std::list resource_list = _salome_services->getResourceList(); + std::list::iterator it; + for (it = resource_list.begin(); it != resource_list.end(); it++) + { + std::string resource = *it; + _resource_files_list->addItem(QString(resource.c_str())); + } +} + +void +JM::ResourceCatalog::item_choosed(QListWidgetItem * item) +{ + DEBTRACE("JM::ResourceCatalog::item_choosed"); + JM::SalomeResource * resource_widget = new JM::SalomeResource(this, + _salome_services, + item->text().toStdString()); + resource_widget->exec(); + delete resource_widget; +} + +void +JM::ResourceCatalog::buttons_management() +{ + QList item_list = _resource_files_list->selectedItems(); + + // Test if an item is selected + if (item_list.size() == 0) + { + _show_button->setEnabled(false); + _edit_button->setEnabled(false); + _remove_button->setEnabled(false); + } + else + { + _show_button->setEnabled(true); + _edit_button->setEnabled(true); + _remove_button->setEnabled(true); + } +} + +void +JM::ResourceCatalog::show_button() +{ + QList item_list = _resource_files_list->selectedItems(); + item_choosed(item_list.at(0)); +} + +void +JM::ResourceCatalog::add_button() +{ + JM::EditSalomeResource * resource_widget = new JM::EditSalomeResource(this, + _salome_services); + resource_widget->exec(); + delete resource_widget; + refresh_resource_list(); +} + +void +JM::ResourceCatalog::remove_button() +{ + QList item_list = _resource_files_list->selectedItems(); + QString item_name = item_list.at(0)->text(); + _salome_services->removeResource(item_name.toStdString()); + refresh_resource_list(); +} + +void +JM::ResourceCatalog::edit_button() +{ + QList item_list = _resource_files_list->selectedItems(); + QString item_name = item_list.at(0)->text(); + JM::EditSalomeResource * resource_widget = new JM::EditSalomeResource(this, + _salome_services, + item_name.toStdString()); + resource_widget->exec(); + delete resource_widget; + refresh_resource_list(); +} diff --git a/src/genericgui/JM_ResourceCatalog.hxx b/src/genericgui/JM_ResourceCatalog.hxx new file mode 100644 index 0000000..2d1b2f5 --- /dev/null +++ b/src/genericgui/JM_ResourceCatalog.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _JM_RESOURCECATALOG_HXX_ +#define _JM_RESOURCECATALOG_HXX_ + +#include + +#include "BL_SALOMEServices.hxx" + +#include +#include + +namespace JM +{ + class ResourceCatalog: public QWidget + { + Q_OBJECT + + public: + ResourceCatalog(QWidget *parent, BL::SALOMEServices * salome_services); + virtual ~ResourceCatalog(); + + void get_infos(); + + QListWidget * getQListWidget(); + + public slots: + void refresh_resource_list(); + void item_choosed(QListWidgetItem * item); + void buttons_management(); + void show_button(); + void edit_button(); + void add_button(); + void remove_button(); + + protected: + QWidget* _parent; + BL::SALOMEServices * _salome_services; + + QPushButton * _refresh_button; + QPushButton * _show_button; + QPushButton * _edit_button; + QPushButton * _add_button; + QPushButton * _remove_button; + QListWidget * _resource_files_list; + }; +} + +#endif + + diff --git a/src/genericgui/JM_SalomeResource.cxx b/src/genericgui/JM_SalomeResource.cxx new file mode 100644 index 0000000..6c2cb9c --- /dev/null +++ b/src/genericgui/JM_SalomeResource.cxx @@ -0,0 +1,189 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "JM_SalomeResource.hxx" +#include "BL_Traces.hxx" + +JM::SalomeResource::SalomeResource(QWidget *parent, BL::SALOMEServices * salome_services, + const std::string & resource_name) : QDialog(parent) +{ + DEBTRACE("Creating JM::SalomeResource"); + BL_ASSERT(parent); + BL_ASSERT(salome_services); + _parent = parent; + _salome_services = salome_services; + _resource_name = resource_name; + + // Widget code + QGroupBox * main_groupBox = new QGroupBox("Main values"); + QLabel * name_label = new QLabel("Name:"); + _name_line = new QLineEdit(this); + QLabel * hostname_label = new QLabel("Hostname:"); + _hostname_line = new QLineEdit(this); + QLabel * protocol_label = new QLabel("Protocol:"); + _protocol_line = new QLineEdit(this); + QLabel * username_label = new QLabel("Username:"); + _username_line = new QLineEdit(this); + QLabel * applipath_label = new QLabel("Applipath:"); + _applipath_line = new QLineEdit(this); + QLabel * componentList_label = new QLabel("Component List:"); + _componentList = new QListWidget(this); + _componentList->setViewMode(QListView::ListMode); + QLabel * working_directory_label = new QLabel("Working Directory:"); + _working_directory = new QLineEdit(this); + QLabel * is_cluster_head_label = new QLabel("Is Cluster Head:"); + _is_cluster_head = new QPushButton(this); + toggle_is_cluster_head(false); // Default is false + QGridLayout * m_layout = new QGridLayout; + m_layout->addWidget(name_label, 0, 0); + m_layout->addWidget(_name_line, 0, 1); + m_layout->addWidget(hostname_label, 1, 0); + m_layout->addWidget(_hostname_line, 1, 1); + m_layout->addWidget(protocol_label, 2, 0); + m_layout->addWidget(_protocol_line, 2, 1); + m_layout->addWidget(username_label, 3, 0); + m_layout->addWidget(_username_line, 3, 1); + m_layout->addWidget(applipath_label, 4, 0); + m_layout->addWidget(_applipath_line, 4, 1); + m_layout->addWidget(componentList_label, 5, 0); + m_layout->addWidget(_componentList, 5, 1); + m_layout->addWidget(is_cluster_head_label, 6, 0); + m_layout->addWidget(_is_cluster_head, 6, 1); + m_layout->addWidget(working_directory_label, 7, 0); + m_layout->addWidget(_working_directory, 7, 1); + main_groupBox->setLayout(m_layout); + + QGroupBox * config_groupBox = new QGroupBox("Configuration values"); + QLabel * os_label = new QLabel("OS:"); + _os_line = new QLineEdit(this); + QLabel * mem_mb_label = new QLabel("Memory (mb):"); + _mem_mb_line = new QLineEdit(this); + QLabel * cpu_clock_label = new QLabel("CPU Clock:"); + _cpu_clock_line = new QLineEdit(this); + QLabel * nb_node_label = new QLabel("Nb node:"); + _nb_node_line = new QLineEdit(this); + QLabel * nb_proc_per_node_label = new QLabel("Nb proc/node:"); + _nb_proc_per_node_line = new QLineEdit(this); + QLabel * batch_label = new QLabel("Batch:"); + _batch_line = new QLineEdit(this); + QLabel * mpiImpl_label = new QLabel("MPI impl:"); + _mpiImpl_line = new QLineEdit(this); + QLabel * iprotocol_label = new QLabel("Internal proctocol:"); + _iprotocol_line = new QLineEdit(this); + QGridLayout * c_layout = new QGridLayout; + c_layout->addWidget(os_label, 0, 0); + c_layout->addWidget(_os_line, 0, 1); + c_layout->addWidget(mem_mb_label, 1, 0); + c_layout->addWidget(_mem_mb_line, 1, 1); + c_layout->addWidget(cpu_clock_label, 2, 0); + c_layout->addWidget(_cpu_clock_line, 2, 1); + c_layout->addWidget(nb_node_label, 3, 0); + c_layout->addWidget(_nb_node_line, 3, 1); + c_layout->addWidget(nb_proc_per_node_label, 4, 0); + c_layout->addWidget(_nb_proc_per_node_line, 4, 1); + c_layout->addWidget(batch_label, 5, 0); + c_layout->addWidget(_batch_line, 5, 1); + c_layout->addWidget(mpiImpl_label, 6, 0); + c_layout->addWidget(_mpiImpl_line, 6, 1); + c_layout->addWidget(iprotocol_label, 7, 0); + c_layout->addWidget(_iprotocol_line, 7, 1); + config_groupBox->setLayout(c_layout); + + // Main Layout + QVBoxLayout * mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(main_groupBox); + mainLayout->addWidget(config_groupBox); + setLayout(mainLayout); + + setWindowTitle("Resource"); + get_infos(); + + // Line cannot be changed + _name_line->setCursorPosition(0); + _hostname_line->setCursorPosition(0); + _protocol_line->setCursorPosition(0); + _username_line->setCursorPosition(0); + _applipath_line->setCursorPosition(0); + _os_line->setCursorPosition(0); + _mem_mb_line->setCursorPosition(0); + _cpu_clock_line->setCursorPosition(0); + _nb_node_line->setCursorPosition(0); + _nb_proc_per_node_line->setCursorPosition(0); + _batch_line->setCursorPosition(0); + _mpiImpl_line->setCursorPosition(0); + _iprotocol_line->setCursorPosition(0); + _working_directory->setCursorPosition(0); + + _name_line->setReadOnly(true); + _hostname_line->setReadOnly(true); + _protocol_line->setReadOnly(true); + _username_line->setReadOnly(true); + _applipath_line->setReadOnly(true); + _os_line->setReadOnly(true); + _mem_mb_line->setReadOnly(true); + _cpu_clock_line->setReadOnly(true); + _nb_node_line->setReadOnly(true); + _nb_proc_per_node_line->setReadOnly(true); + _batch_line->setReadOnly(true); + _mpiImpl_line->setReadOnly(true); + _iprotocol_line->setReadOnly(true); + _working_directory->setReadOnly(true); +} + +JM::SalomeResource::~SalomeResource() +{ + DEBTRACE("Destroying JM::SalomeResource"); +} + +void +JM::SalomeResource::get_infos() +{ + BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(_resource_name); + + _name_line->setText(QString(resource_descr.name.c_str())); + _hostname_line->setText(QString(resource_descr.hostname.c_str())); + _protocol_line->setText(QString(resource_descr.protocol.c_str())); + _username_line->setText(QString(resource_descr.username.c_str())); + _applipath_line->setText(QString(resource_descr.applipath.c_str())); + _os_line->setText(QString(resource_descr.OS.c_str())); + _batch_line->setText(QString(resource_descr.batch.c_str())); + _mpiImpl_line->setText(QString(resource_descr.mpiImpl.c_str())); + _iprotocol_line->setText(QString(resource_descr.iprotocol.c_str())); + _working_directory->setText(QString(resource_descr.working_directory.c_str())); + toggle_is_cluster_head(resource_descr.is_cluster_head); + + QString value; + _mem_mb_line->setText(value.setNum(resource_descr.mem_mb)); + _cpu_clock_line->setText(value.setNum(resource_descr.cpu_clock)); + _nb_node_line->setText(value.setNum(resource_descr.nb_node)); + _nb_proc_per_node_line->setText(value.setNum(resource_descr.nb_proc_per_node)); + + std::list::iterator it = resource_descr.componentList.begin(); + for(; it != resource_descr.componentList.end(); it++) + _componentList->addItem(QString((*it).c_str())); +} + +void +JM::SalomeResource::toggle_is_cluster_head(bool checked) +{ + if (checked) + _is_cluster_head->setText("true"); + else + _is_cluster_head->setText("false"); +} diff --git a/src/genericgui/JM_SalomeResource.hxx b/src/genericgui/JM_SalomeResource.hxx new file mode 100644 index 0000000..dc80b1c --- /dev/null +++ b/src/genericgui/JM_SalomeResource.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _JM_SALOMERESOURCE_HXX_ +#define _JM_SALOMERESOURCE_HXX_ + +#include +#include "BL_SALOMEServices.hxx" + +#include + +namespace JM +{ + class SalomeResource: public QDialog + { + Q_OBJECT + + public: + SalomeResource(QWidget *parent, BL::SALOMEServices * salome_services, + const std::string & resource_name); + virtual ~SalomeResource(); + + void get_infos(); + + void toggle_is_cluster_head(bool checked); + + protected: + QWidget* _parent; + BL::SALOMEServices * _salome_services; + std::string _resource_name; + + // widget + QLineEdit * _name_line; + QLineEdit * _hostname_line; + QLineEdit * _protocol_line; + QLineEdit * _username_line; + QLineEdit * _applipath_line; + QListWidget * _componentList; + QPushButton * _is_cluster_head; + QLineEdit * _working_directory; + QLineEdit * _os_line; + QLineEdit * _mem_mb_line; + QLineEdit * _cpu_clock_line; + QLineEdit * _nb_node_line; + QLineEdit * _nb_proc_per_node_line; + QLineEdit * _batch_line; + QLineEdit * _mpiImpl_line; + QLineEdit * _iprotocol_line; + }; +} + +#endif + diff --git a/src/genericgui/Makefile.am b/src/genericgui/Makefile.am index c039365..0e68146 100644 --- a/src/genericgui/Makefile.am +++ b/src/genericgui/Makefile.am @@ -1,27 +1,28 @@ -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # libdir = $(prefix)/lib/salome lib_LTLIBRARIES = libBL_GenericGui.la -libBL_GenericGui_la_SOURCES = BL_GenericGui.hxx BL_GenericGui.cxx \ +libBL_GenericGui_la_SOURCES = BL_GenericGuiDefines.hxx \ + BL_GenericGui.hxx BL_GenericGui.cxx \ BL_JobsTable.hxx BL_JobsTable.cxx \ BL_JobTab.hxx BL_JobTab.cxx \ BL_Buttons.hxx BL_Buttons.cxx \ @@ -29,23 +30,30 @@ libBL_GenericGui_la_SOURCES = BL_GenericGui.hxx BL_GenericGui.cxx \ BL_QModelManager.hxx BL_QModelManager.cxx \ BL_CreateJobWizard.hxx BL_CreateJobWizard.cxx \ BL_Summary.hxx BL_Summary.cxx \ - BL_MachineCatalog.hxx BL_MachineCatalog.cxx + JM_ResourceCatalog.hxx JM_ResourceCatalog.cxx \ + JM_SalomeResource.hxx JM_SalomeResource.cxx \ + JM_EditSalomeResource.hxx JM_EditSalomeResource.cxx -nodist_libBL_GenericGui_la_SOURCES = BL_GenericGui_moc.cxx BL_JobsTable_moc.cxx \ +MOC_FILES = BL_GenericGui_moc.cxx BL_JobsTable_moc.cxx \ BL_JobTab_moc.cxx \ BL_Buttons_moc.cxx BL_JobsManager_QT_moc.cxx \ BL_QModelManager_moc.cxx BL_CreateJobWizard_moc.cxx \ - BL_Summary_moc.cxx BL_MachineCatalog_moc.cxx + BL_Summary_moc.cxx JM_ResourceCatalog_moc.cxx \ + JM_SalomeResource_moc.cxx JM_EditSalomeResource_moc.cxx + +nodist_libBL_GenericGui_la_SOURCES = $(MOC_FILES) libBL_GenericGui_la_CXXFLAGS = $(qt4_cppflags) \ -I$(top_srcdir)/src/bases \ -I$(top_srcdir)/src/engine \ -I$(KERNEL_ROOT_DIR)/include/salome \ + $(OMNIORB_INCLUDES) $(OMNIORB_CXXFLAGS) \ + -I../../idl \ -I$(top_srcdir)/src/wrappers libBL_GenericGui_la_LDFLAGS = $(qt4_ldflags) -libBL_GenericGui_la_LIBADD = -lQtGui -lQtCore -lQtWebKit \ +libBL_GenericGui_la_LIBADD = -lQtGui -lQtCore \ $(top_builddir)/src/bases/libBL_Bases.la \ $(top_builddir)/src/engine/libBL_Engine.la diff --git a/src/salomegui/BL_SalomeGui.cxx b/src/salomegui/BL_SalomeGui.cxx index 5895d94..b71fd64 100644 --- a/src/salomegui/BL_SalomeGui.cxx +++ b/src/salomegui/BL_SalomeGui.cxx @@ -1,22 +1,24 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com #include "BL_SalomeGui.hxx" +#include "JOBMANAGER_version.h" BL::SalomeGui::SalomeGui() : MainWindows_SALOME("JobManager"), SalomeApp_Module("JobManager"), @@ -29,6 +31,10 @@ BL::SalomeGui::SalomeGui() : MainWindows_SALOME("JobManager"), BL::SalomeGui::~SalomeGui() { DEBTRACE("Destroying BL::SalomeGui"); + if (getApp()) + disconnect(getApp(), SIGNAL(studyClosed()), this, SLOT(studyClosed())); + if (_gengui) + delete _gengui; } void @@ -36,12 +42,22 @@ BL::SalomeGui::initialize(CAM_Application* app) { DEBTRACE("Entering in initialize"); SalomeApp_Module::initialize(app); // MANDATORY -> Otherwise SISEGV... - BL::MainWindows_SALOME::initialize(getApp()); + connect( getApp(), SIGNAL(studyClosed()), this, SLOT(studyClosed())); + if ( app && app->desktop() ) + connect( app->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), + this, SLOT(onWindowActivated( SUIT_ViewWindow* )) ); +} - _gengui = new BL::GenericGui(this); - _gengui->createActions(); - _gengui->createMenus(); - _gengui->updateButtonsStates(); +void +BL::SalomeGui::studyClosed() +{ + if (_gengui) + { + _gengui->deleteDockWidget(); + delete _gengui; + _gengui = NULL; + _viewWin = NULL; + } } bool @@ -49,10 +65,32 @@ BL::SalomeGui::activateModule(SUIT_Study* theStudy) { DEBTRACE("Entering in BL::SalomeGui::activateModule"); - bool bOk = SalomeApp_Module::activateModule(theStudy); - setMenuShown(true); + if (!_gengui) + { + BL::MainWindows_SALOME::initialize(getApp()); + BL::MainWindows_SALOME::createView(); + _gengui = new BL::GenericGui(this); + _gengui->createDockWidgets(); + _gengui->createCentralWidget(); + _gengui->createActions(); + _gengui->createMenus(); + _gengui->updateButtonsStates(); + } + else + { + // Test main view + if (!BL::MainWindows_SALOME::restoreViewFocus()) + { + // We need to recreate QT objects and the view + BL::MainWindows_SALOME::createView(); + _gengui->createCentralWidget(); + } + } + + setMenuShown(true); _gengui->showDockWidgets(true); + bool bOk = SalomeApp_Module::activateModule(theStudy); return bOk; } @@ -68,18 +106,35 @@ bool BL::SalomeGui::deactivateModule(SUIT_Study* theStudy) { DEBTRACE("Entering in BL::SalomeGui::deactivateModule"); - setMenuShown(false); - _gengui->showDockWidgets(false); + if (_gengui) + _gengui->showDockWidgets(false); bool bOk = SalomeApp_Module::deactivateModule(theStudy); return bOk; } +void +BL::SalomeGui::onWindowActivated( SUIT_ViewWindow* svw) +{ + DEBTRACE("BL::SalomeGui::onWindowActivated"); + DEBTRACE("activeModule()->moduleName() " << (getApp()->activeModule() ? getApp()->activeModule()->moduleName().toStdString() : "") ); + + if (_viewWin) // Be sure to have a _viewWindow + if (svw->getId() == _viewWin->getId()) // Same Id ? + if (!getApp()->activeModule() || getApp()->activeModule()->moduleName() != "JobManager") // JobManager already activated ? + if ( !getApp()->activateModule("JobManager") ) return; +} + // --- Export the module extern "C" { - CAM_Module* createModule() + JOBMANAGER_EXPORT CAM_Module* createModule() { return new BL::SalomeGui(); } + + char* getModuleVersion() + { + return (char*)JOBMANAGER_VERSION_STR; + } } diff --git a/src/salomegui/BL_SalomeGui.hxx b/src/salomegui/BL_SalomeGui.hxx index c72142d..a1f24af 100644 --- a/src/salomegui/BL_SalomeGui.hxx +++ b/src/salomegui/BL_SalomeGui.hxx @@ -1,24 +1,35 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com #ifndef _BL_SALOMEGUI_HXX_ #define _BL_SALOMEGUI_HXX_ +#ifdef WNT +# if defined JOBMANAGER_EXPORTS +# define JOBMANAGER_EXPORT __declspec( dllexport ) +# else +# define JOBMANAGER_EXPORT __declspec( dllimport ) +# endif +#else +# define JOBMANAGER_EXPORT +#endif + #include #include @@ -44,6 +55,10 @@ namespace BL public slots: bool deactivateModule( SUIT_Study* theStudy); bool activateModule( SUIT_Study* theStudy); + void studyClosed(); + + protected slots: + void onWindowActivated( SUIT_ViewWindow* svw); protected: BL::GenericGui * _gengui; diff --git a/src/salomegui/JOBMANAGER_version.h.in b/src/salomegui/JOBMANAGER_version.h.in new file mode 100644 index 0000000..5621203 --- /dev/null +++ b/src/salomegui/JOBMANAGER_version.h.in @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : JOBMANAGER_version.h +// Author : Vadim SANDLER +// Module : SALOME +// +#if !defined(__JOBMANAGER_VERSION_H__) +#define __JOBMANAGER_VERSION_H__ + +/* + JOBMANAGER_VERSION is (major << 16) + (minor << 8) + patch. +*/ + +#define JOBMANAGER_VERSION_STR "@VERSION@" +#define JOBMANAGER_VERSION @XVERSION@ + +#endif // __JOBMANAGER_VERSION_H__ diff --git a/src/salomegui/Makefile.am b/src/salomegui/Makefile.am index c916702..8a01eab 100644 --- a/src/salomegui/Makefile.am +++ b/src/salomegui/Makefile.am @@ -1,20 +1,20 @@ -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # include $(top_srcdir)/src/bases/make_begin.am @@ -28,7 +28,10 @@ dist_libJOBMANAGER_la_SOURCES = BL_SalomeGui.hxx BL_SalomeGui.cxx nodist_libJOBMANAGER_la_SOURCES = $(MOC_FILES) libJOBMANAGER_la_CXXFLAGS = $(qt4_cppflags) \ - $(OMNIORB_INCLUDES) \ + $(BOOST_CPPFLAGS) \ + $(OMNIORB_INCLUDES) $(OMNIORB_CXXFLAGS) \ + -I$(top_builddir)/idl \ + -I. \ -I$(KERNEL_ROOT_DIR)/include/salome \ -I$(GUI_ROOT_DIR)/include/salome \ -I$(top_srcdir)/src/genericgui \ @@ -41,6 +44,8 @@ libJOBMANAGER_la_LDFLAGS = -L$(GUI_ROOT_DIR)/lib/salome \ $(qt4_ldflags) libJOBMANAGER_la_LIBADD = $(qt4_libs) \ + $(top_builddir)/idl/libJOBMANAGER_IDL.la \ + @OMNIORB_LIBS@ \ $(top_builddir)/src/bases/libBL_Bases.la \ $(top_builddir)/src/engine/libBL_Engine.la \ $(top_builddir)/src/genericgui/libBL_GenericGui.la \ @@ -48,11 +53,14 @@ libJOBMANAGER_la_LIBADD = $(qt4_libs) \ -lSalomeApp salomeinclude_HEADERS = BL_SalomeGui.hxx +salomeinclude_DATA = JOBMANAGER_version.h # resources files -LIBICONS = SalomeApp.xml jobmanager.png +ICONS = resources/jobmanager.png + +nodist_salomeres_SCRIPTS = resources/SalomeApp.xml + dist_salomeres_DATA = ${ICONS} -ICONS = $(LIBICONS:%=resources/%) # -------------------------------------------- # *.h --> *_moc.cxx diff --git a/src/salomegui/resources/SalomeApp.xml b/src/salomegui/resources/SalomeApp.xml.in similarity index 69% rename from src/salomegui/resources/SalomeApp.xml rename to src/salomegui/resources/SalomeApp.xml.in index c8e0933..bc8bb87 100644 --- a/src/salomegui/resources/SalomeApp.xml +++ b/src/salomegui/resources/SalomeApp.xml.in @@ -1,5 +1,5 @@ + +
- + +
+
+ +
diff --git a/src/standalone/Makefile.am b/src/standalone/Makefile.am index e6c5d75..a747dff 100644 --- a/src/standalone/Makefile.am +++ b/src/standalone/Makefile.am @@ -1,3 +1,22 @@ +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + bin_PROGRAMS = jobmanager_gui bin_SCRIPTS = start_jobmanager.sh @@ -8,6 +27,8 @@ jobmanager_gui_CXXFLAGS = $(qt4_cppflags) \ -I$(top_srcdir)/src/bases \ -I$(top_srcdir)/src/engine \ -I$(KERNEL_ROOT_DIR)/include/salome \ + $(OMNIORB_INCLUDES) $(OMNIORB_CXXFLAGS) \ + -I../../idl \ -I$(top_srcdir)/src/wrappers \ -I$(top_srcdir)/src/genericgui @@ -18,6 +39,7 @@ jobmanager_gui_LDADD = -lQtGui -lQtCore \ $(top_builddir)/src/engine/libBL_Engine.la \ $(top_builddir)/src/wrappers/libBL_Wrappers_Qt.la \ @OMNIORB_LIBS@ \ + $(top_builddir)/idl/libJOBMANAGER_IDL.la \ -L$(KERNEL_ROOT_DIR)/lib/salome -lSalomeLifeCycleCORBA -lSalomeIDLKernel -lSalomeNS EXTRA_DIST = start_jobmanager.sh.in diff --git a/src/standalone/main.cxx b/src/standalone/main.cxx index baf07c6..a33ff39 100644 --- a/src/standalone/main.cxx +++ b/src/standalone/main.cxx @@ -1,3 +1,22 @@ +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + #include #include "BL_GenericGui.hxx" #include "BL_MainWindows_Qt.hxx" diff --git a/src/standalone/start_jobmanager.sh.in b/src/standalone/start_jobmanager.sh.in index 4b94938..ab69850 100644 --- a/src/standalone/start_jobmanager.sh.in +++ b/src/standalone/start_jobmanager.sh.in @@ -1,21 +1,21 @@ #!/bin/bash -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # usage() diff --git a/src/wrappers/BL_MainWindows_Qt.cxx b/src/wrappers/BL_MainWindows_Qt.cxx index ea7e5a2..e8b0305 100644 --- a/src/wrappers/BL_MainWindows_Qt.cxx +++ b/src/wrappers/BL_MainWindows_Qt.cxx @@ -1,20 +1,21 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com #include "BL_MainWindows_Qt.hxx" @@ -48,11 +49,12 @@ BL::MainWindows_Qt::createAction(const QString& toolTip, const QIcon& icon, const QString& menu, const QString& status, - const int shortCut, + const int accel, QObject* parent, bool checkable, QObject* receiver, - const char* member) + const char* member, + const QString& shortCut) { QAction * action = new QAction(icon, menu, parent); action->setStatusTip(status); diff --git a/src/wrappers/BL_MainWindows_Qt.hxx b/src/wrappers/BL_MainWindows_Qt.hxx index 550d6c5..c50e8f3 100644 --- a/src/wrappers/BL_MainWindows_Qt.hxx +++ b/src/wrappers/BL_MainWindows_Qt.hxx @@ -1,31 +1,42 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com #ifndef _BL_MAINWINDOWS_QT_HXX_ #define _BL_MAINWINDOWS_QT_HXX_ +#ifdef WNT +# if defined BL_Wrappers_Qt_EXPORTS +# define BL_Wrappers_Qt_EXPORT __declspec( dllexport ) +# else +# define BL_Wrappers_Qt_EXPORT __declspec( dllimport ) +# endif +#else +# define BL_Wrappers_Qt_EXPORT +#endif + #include "BL_MainWindows_Wrap.hxx" #include namespace BL { - class MainWindows_Qt : public MainWindows_Wrap, public QObject + class BL_Wrappers_Qt_EXPORT MainWindows_Qt : public MainWindows_Wrap, public QObject { public: MainWindows_Qt(QMainWindow * main_window); @@ -38,11 +49,12 @@ namespace BL const QIcon& icon, const QString& menu, const QString& status, - const int shortCut, + const int accel, QObject* parent =0, bool checkable = false, QObject* receiver =0, - const char* member =0); + const char* member =0, + const QString& shortCut=QString()); virtual int createTopMenu(const QString & menu_name); virtual void addActionToMenu(QAction * action, int menu_id); diff --git a/src/wrappers/BL_MainWindows_SALOME.cxx b/src/wrappers/BL_MainWindows_SALOME.cxx index 6a604b7..a3fc934 100644 --- a/src/wrappers/BL_MainWindows_SALOME.cxx +++ b/src/wrappers/BL_MainWindows_SALOME.cxx @@ -1,22 +1,24 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com #include "BL_MainWindows_SALOME.hxx" +#include BL::MainWindows_SALOME::MainWindows_SALOME(const QString & module_name) : SalomeApp_Module(module_name), @@ -24,6 +26,8 @@ BL::MainWindows_SALOME::MainWindows_SALOME(const QString & module_name) : { DEBTRACE("Creating BL::MainWindows_SALOME"); _actionId = 190; + _currentViewId = -1; + _svm = 0; } void @@ -31,28 +35,69 @@ BL::MainWindows_SALOME::initialize(SalomeApp_Application * appli) { DEBTRACE("Initialize BL::MainWindows_SALOME"); BL_ASSERT(appli); - _appli = appli; - _svm = new SUIT_ViewManager(_appli->activeStudy(), _appli->desktop(), new SUIT_ViewModel()); - _appli->addViewManager(_svm); - _viewWin = _svm->createViewWindow(); +} + + +void +BL::MainWindows_SALOME::createView() +{ + DEBTRACE("BL::MainWindows_SALOME CreateView"); + QString vmType = "JobManager View"; + + // Get JobManager View Manager + _svm = _appli->getViewManager( vmType, true ); + if (!_svm) { + // view manager not found + QTextEdit* w = new QTextEdit; + _svm = _appli->createViewManager( vmType, w ); + } + + // Create a view + _viewWin = _svm->getActiveView(); + _viewWin->setClosable( false ); + _currentViewId = _viewWin->getId(); + DEBTRACE("End of BL::MainWindows_SALOME CreateView"); +} + +bool +BL::MainWindows_SALOME::restoreViewFocus() +{ + bool result = false; + SUIT_ViewWindow* resWnd = 0; + + // Search window + QList wndlist = _appli->desktop()->windows(); + SUIT_ViewWindow* wnd; + for (int i = 0; i < wndlist.size(); ++i) + { + wnd = wndlist.at(i); + if (_currentViewId == wnd->getId()) {resWnd = wnd;} + if (resWnd) {break;} + } - if (_viewWin && _appli->desktop()) - _viewWin->resize((int)(_appli->desktop()->width() * 0.6), (int)(_appli->desktop()->height() * 0.6 )); + if (resWnd) + { + wnd->setFocus(); + result = true; + } + return result; } QString BL::MainWindows_SALOME::engineIOR() const { DEBTRACE("Entering in BL::SalomeGui::engineIOR"); - return _appli->defaultEngineIOR(); + QString anEngineIOR = SalomeApp_Engine_i::EngineIORForComponent( "JOBMANAGER", true ).c_str(); + return anEngineIOR; } void BL::MainWindows_SALOME::viewManagers(QStringList& list) const { DEBTRACE("Entering in BL::SalomeGui::viewManagers"); - list.append(_svm->getType()); + if (_svm) + list.append(_svm->getType()); } @@ -78,19 +123,20 @@ BL::MainWindows_SALOME::createAction(const QString& toolTip, const QIcon& icon, const QString& menu, const QString& status, - const int shortCut, + const int accel, QObject* parent, bool checkable, QObject* receiver, - const char* member) + const char* member, + const QString & shortCut) { - return SalomeApp_Module::createAction(getActionId(), toolTip, icon, menu, status, shortCut, parent, checkable, receiver, member); + return SalomeApp_Module::createAction(getActionId(), toolTip, icon, menu, status, accel, parent, checkable, receiver, member, shortCut); } int BL::MainWindows_SALOME::createTopMenu(const QString & menu_name) { - return createMenu(menu_name, -1); + return createMenu(menu_name, -1, -1, 30 ); } void diff --git a/src/wrappers/BL_MainWindows_SALOME.hxx b/src/wrappers/BL_MainWindows_SALOME.hxx index ec2ee35..11a939c 100644 --- a/src/wrappers/BL_MainWindows_SALOME.hxx +++ b/src/wrappers/BL_MainWindows_SALOME.hxx @@ -1,25 +1,36 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com #ifndef _BL_MAINWINDOWS_SALOME_HXX_ #define _BL_MAINWINDOWS_SALOME_HXX_ +#ifdef WNT +# if defined BL_Wrappers_SALOME_EXPORTS +# define BL_Wrappers_SALOME_EXPORT __declspec( dllexport ) +# else +# define BL_Wrappers_SALOME_EXPORT __declspec( dllimport ) +# endif +#else +# define BL_Wrappers_SALOME_EXPORT +#endif + #include "BL_MainWindows_Wrap.hxx" #include @@ -32,8 +43,8 @@ namespace BL { - class MainWindows_SALOME : virtual public MainWindows_Wrap, - virtual public SalomeApp_Module + class BL_Wrappers_SALOME_EXPORT MainWindows_SALOME : virtual public MainWindows_Wrap, + virtual public SalomeApp_Module { public: MainWindows_SALOME(const QString & module_name); @@ -50,26 +61,30 @@ namespace BL virtual QMainWindow * getTabParent(); virtual QAction* createAction(const QString& toolTip, - const QIcon& icon, - const QString& menu, - const QString& status, - const int shortCut, - QObject* parent =0, - bool checkable = false, - QObject* receiver =0, - const char* member =0); + const QIcon& icon, + const QString& menu, + const QString& status, + const int accel, + QObject* parent =0, + bool checkable = false, + QObject* receiver =0, + const char* member =0, + const QString& shortCut=QString()); virtual int createTopMenu(const QString & menu_name); virtual void addActionToMenu(QAction * action, int menu_id); // Usefull methods virtual void initialize(SalomeApp_Application * appli); + bool restoreViewFocus(); + void createView(); protected: SalomeApp_Application * _appli; SalomeApp_Module * _module; SUIT_ViewManager * _svm; SUIT_ViewWindow * _viewWin; + int _currentViewId; int _actionId; int getActionId() { return _actionId++; } diff --git a/src/wrappers/BL_MainWindows_Wrap.hxx b/src/wrappers/BL_MainWindows_Wrap.hxx index 3d16e98..333b3fe 100644 --- a/src/wrappers/BL_MainWindows_Wrap.hxx +++ b/src/wrappers/BL_MainWindows_Wrap.hxx @@ -1,20 +1,21 @@ -// Copyright (C) 2009 CEA/DEN, EDF R&D +// Copyright (C) 2009-2012 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com #ifndef _BL_MAINWINDOWS_WRAP_HXX_ @@ -39,11 +40,12 @@ namespace BL const QIcon& icon, const QString& menu, const QString& status, - const int shortCut, + const int accel, QObject* parent =0, bool checkable = false, QObject* receiver =0, - const char* member =0) = 0; + const char* member =0, + const QString& shortCut=QString()) = 0; virtual int createTopMenu(const QString & menu_name) = 0; virtual void addActionToMenu(QAction * action, int menu_id) = 0; diff --git a/src/wrappers/Makefile.am b/src/wrappers/Makefile.am index 773d02e..a787dec 100644 --- a/src/wrappers/Makefile.am +++ b/src/wrappers/Makefile.am @@ -1,20 +1,20 @@ -# Copyright (C) 2009 CEA/DEN, EDF R&D +# Copyright (C) 2009-2012 CEA/DEN, EDF R&D # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # libdir = $(prefix)/lib/salome @@ -44,11 +44,12 @@ libBL_Wrappers_SALOME_la_SOURCES = BL_MainWindows_Wrap.hxx \ nodist_libBL_Wrappers_SALOME_la_SOURCES = libBL_Wrappers_SALOME_la_CXXFLAGS = $(qt4_cppflags) -I$(top_srcdir)/src/bases \ - $(OMNIORB_INCLUDES) \ + $(OMNIORB_INCLUDES) $(OMNIORB_CXXFLAGS) $(BOOST_CPPFLAGS) \ -I$(KERNEL_ROOT_DIR)/include/salome \ -I$(GUI_ROOT_DIR)/include/salome libBL_Wrappers_SALOME_la_LDFLAGS = $(qt4_ldflags) -libBL_Wrappers_SALOME_la_LIBADD = -lQtGui -lQtCore $(top_builddir)/src/bases/libBL_Bases.la +libBL_Wrappers_SALOME_la_LIBADD = -lQtGui -lQtCore $(top_builddir)/src/bases/libBL_Bases.la $(OMNIORB_LIBS) \ + $(KERNEL_LDFLAGS) -lSalomeIDLKernel $(GUI_LDFLAGS) -lLightApp -lSalomeApp -lSalomeSession -lCAM -lsuit -- 2.39.2