From: Nabil Ghodbane Date: Tue, 26 Feb 2019 14:36:27 +0000 (+0100) Subject: Mise à jour du template PythonComponent X-Git-Tag: 5.4.0~11^2~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=458ca3d65199bf618d286a5d252916eb186ff031;p=tools%2Fsat.git Mise à jour du template PythonComponent --- diff --git a/commands/template.py b/commands/template.py index 1a2d457..23eddb0 100644 --- a/commands/template.py +++ b/commands/template.py @@ -461,11 +461,11 @@ def run(args, runner, logger): logger.write("\n", 1) return 1 - if "APPLICATION" in runner.cfg: - msg = _("Error: this command does not use a product.") - logger.write(src.printcolors.printcError(msg), 1) - logger.write("\n", 1) - return 1 + # if "APPLICATION" in runner.cfg: + # msg = _("Error: this command does not use a product.") + # logger.write(src.printcolors.printcError(msg), 1) + # logger.write("\n", 1) + # return 1 if options.info: return get_template_info(runner.cfg, options.template, logger) diff --git a/data/templates/PythonComponent/CMakeLists.txt b/data/templates/PythonComponent/CMakeLists.txt new file mode 100644 index 0000000..1911d00 --- /dev/null +++ b/data/templates/PythonComponent/CMakeLists.txt @@ -0,0 +1,215 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8 FATAL_ERROR) +PROJECT(Salome:sat:{PYCMP} C CXX) + +# Ensure a proper linker behavior: +CMAKE_POLICY(SET CMP0003 NEW) + +# Versioning +# =========== +# Project name, upper case +STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) + +SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 4) +SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) +SET(${PROJECT_NAME_UC}_VERSION + ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) +SET(${PROJECT_NAME_UC}_VERSION_DEV 0) + +# Common CMake macros +# =================== +SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files") +IF(EXISTS ${CONFIGURATION_ROOT_DIR}) + LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake") + INCLUDE(SalomeMacros) +ELSE() + MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !") +ENDIF() + +# Find KERNEL +# =========== +SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR} CACHE PATH "Path to the Salome KERNEL") +IF(EXISTS ${KERNEL_ROOT_DIR}) + LIST(APPEND CMAKE_MODULE_PATH "${KERNEL_ROOT_DIR}/salome_adm/cmake_files") + INCLUDE(SalomeMacros) + FIND_PACKAGE(SalomeKERNEL REQUIRED) + KERNEL_WITH_CORBA() # check whether KERNEL builded with CORBA +ELSE(EXISTS ${KERNEL_ROOT_DIR}) + MESSAGE(FATAL_ERROR "We absolutely need a Salome KERNEL, please define KERNEL_ROOT_DIR") +ENDIF(EXISTS ${KERNEL_ROOT_DIR}) + +# Platform setup +# ============== +INCLUDE(SalomeSetupPlatform) # From KERNEL +# Always build libraries as shared objects: +SET(BUILD_SHARED_LIBS TRUE) +# Local macros: +LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/adm_local/cmake_files") + +# User options +# ============ +OPTION(SALOME_BUILD_TESTS "Build SALOME tests" ON) +OPTION(SALOME_BUILD_DOC "Generate SALOME :sat:{PYCMP} documentation" ON) + +IF(SALOME_BUILD_TESTS) + ENABLE_TESTING() +ENDIF() +IF(SALOME_BUILD_DOC) + FIND_PACKAGE(SalomeDoxygen) + SALOME_LOG_OPTIONAL_PACKAGE(Doxygen SALOME_BUILD_DOC) +ENDIF() + +## +## From KERNEL: +## +FIND_PACKAGE(SalomePythonInterp REQUIRED) +FIND_PACKAGE(SalomePythonLibs REQUIRED) +FIND_PACKAGE(SalomeOmniORB REQUIRED) +FIND_PACKAGE(SalomeOmniORBPy REQUIRED) + +# Find GUI +# =========== +SET(GUI_ROOT_DIR $ENV{GUI_ROOT_DIR} CACHE PATH "Path to the Salome GUI") +IF(EXISTS ${GUI_ROOT_DIR}) + LIST(APPEND CMAKE_MODULE_PATH "${GUI_ROOT_DIR}/adm_local/cmake_files") + FIND_PACKAGE(SalomeGUI REQUIRED) + ADD_DEFINITIONS(${GUI_DEFINITIONS}) + INCLUDE_DIRECTORIES(${GUI_INCLUDE_DIRS}) + ELSE(EXISTS ${GUI_ROOT_DIR}) + MESSAGE(FATAL_ERROR "We absolutely need a Salome GUI, please define GUI_ROOT_DIR") +ENDIF(EXISTS ${GUI_ROOT_DIR}) + +## +## From GUI: +## +# Qt +IF(NOT SALOME_GUI_BUILD_WITH_QT5) + FIND_PACKAGE(SalomeQt4 REQUIRED COMPONENTS QtCore QtGui) +ELSE() + FIND_PACKAGE(SalomeQt5 REQUIRED) +ENDIF() + +# Detection summary: +SALOME_PACKAGE_REPORT_AND_CHECK() + +# Directories +# (default values taken from KERNEL) +# =========== +SET(SALOME_INSTALL_BINS "${SALOME_INSTALL_BINS}" CACHE PATH "Install path: SALOME binaries") +SET(SALOME_INSTALL_LIBS "${SALOME_INSTALL_LIBS}" CACHE PATH "Install path: SALOME libs") +SET(SALOME_INSTALL_IDLS "${SALOME_INSTALL_IDLS}" CACHE PATH "Install path: SALOME IDL files") +SET(SALOME_INSTALL_HEADERS "${SALOME_INSTALL_HEADERS}" CACHE PATH "Install path: SALOME headers") +SET(SALOME_INSTALL_SCRIPT_SCRIPTS "${SALOME_INSTALL_SCRIPT_SCRIPTS}" CACHE PATH + "Install path: SALOME scripts") +SET(SALOME_INSTALL_SCRIPT_DATA "${SALOME_INSTALL_SCRIPT_DATA}" CACHE PATH + "Install path: SALOME script data") +SET(SALOME_INSTALL_SCRIPT_PYTHON "${SALOME_INSTALL_SCRIPT_PYTHON}" CACHE PATH + "Install path: SALOME Python scripts") +SET(SALOME_INSTALL_APPLISKEL_SCRIPTS "${SALOME_INSTALL_APPLISKEL_SCRIPTS}" CACHE PATH + "Install path: SALOME application skeleton - scripts") +SET(SALOME_INSTALL_APPLISKEL_PYTHON "${SALOME_INSTALL_APPLISKEL_PYTHON}" CACHE PATH + "Install path: SALOME application skeleton - Python") +#SET(SALOME_INSTALL_PYTHON "${SALOME_INSTALL_PYTHON}" CACHE PATH "Install path: SALOME Python stuff") +#SET(SALOME_INSTALL_PYTHON_SHARED "${SALOME_INSTALL_PYTHON_SHARED}" CACHE PATH +# "Install path: SALOME Python shared modules") +SET(SALOME_INSTALL_CMAKE_LOCAL "${SALOME_INSTALL_CMAKE_LOCAL}" CACHE PATH "Install path: SALOME CMake files") +SET(SALOME_INSTALL_AMCONFIG_LOCAL "${SALOME_INSTALL_AMCONFIG_LOCAL}" CACHE PATH + "Install path: local SALOME config files (obsolete, to be removed)") + +SET(SALOME_INSTALL_RES "${SALOME_INSTALL_RES}" CACHE PATH "Install path: SALOME resources") +SET(SALOME_INSTALL_DOC "${SALOME_INSTALL_DOC}" CACHE PATH "Install path: SALOME documentation") + +# Specific to :sat:{PYCMP}: +SET(SALOME_:sat:{PYCMP}_INSTALL_RES_DATA "${SALOME_INSTALL_RES}/:sat:{PYCMP_minus}" CACHE PATH + "Install path: SALOME :sat:{PYCMP} specific data") + +MARK_AS_ADVANCED(SALOME_INSTALL_BINS SALOME_INSTALL_LIBS SALOME_INSTALL_IDLS SALOME_INSTALL_HEADERS) +MARK_AS_ADVANCED(SALOME_INSTALL_SCRIPT_SCRIPTS SALOME_INSTALL_SCRIPT_DATA SALOME_INSTALL_SCRIPT_PYTHON) +MARK_AS_ADVANCED(SALOME_INSTALL_APPLISKEL_SCRIPTS SALOME_INSTALL_APPLISKEL_PYTHON SALOME_INSTALL_CMAKE_LOCAL SALOME_INSTALL_RES) +MARK_AS_ADVANCED(SALOME_INSTALL_PYTHON SALOME_INSTALL_PYTHON_SHARED) +MARK_AS_ADVANCED(SALOME_INSTALL_AMCONFIG_LOCAL SALOME_INSTALL_DOC) +MARK_AS_ADVANCED(SALOME_:sat:{PYCMP}_INSTALL_RES_DATA) + +# Accumulate environment variables for :sat:{PYCMP} module +SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS} + ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON}) +SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS}) + +# Sources +# ======== + +ADD_SUBDIRECTORY(idl) +ADD_SUBDIRECTORY(adm_local) +ADD_SUBDIRECTORY(resources) +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(bin) +IF(SALOME_BUILD_DOC) + ADD_SUBDIRECTORY(doc) +ENDIF() + +# Configuration export +# (here only the level 1 prerequisites are exposed) +# ==================== +INCLUDE(CMakePackageConfigHelpers) + +# List of targets in this project we want to make visible to the rest of the world. +# They all have to be INSTALL'd with the option "EXPORT ${PROJECT_NAME}TargetGroup" +SET(_${PROJECT_NAME}_exposed_targets + SalomeIDL:sat:{PYCMP} +) + +# Add all targets to the build-tree export set +EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets} + FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake) + +# Create the configuration files: +# - in the build tree: + +# Ensure the variables are always defined for the configure: +SET(GUI_ROOT_DIR "${GUI_ROOT_DIR}") + +SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/include") + +# Build variables that will be expanded when configuring SalomeConfig.cmake: +# SALOME_CONFIGURE_PREPARE() #For use in the future + +CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" + PATH_VARS CONF_INCLUDE_DIRS SALOME_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX + GUI_ROOT_DIR) + +WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + VERSION ${${PROJECT_NAME_UC}_VERSION} + COMPATIBILITY AnyNewerVersion) + +# Install the CMake configuration files: +INSTALL(FILES + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}") + +# Install the export set for use with the install-tree +INSTALL(EXPORT ${PROJECT_NAME}TargetGroup DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" + FILE ${PROJECT_NAME}Targets.cmake) + +# Specific to : +SET(SALOME_:sat:{PYCMP}_INSTALL_RES_DATA "${SALOME_INSTALL_RES}/:sat:{PYCMP_minus}" CACHE PATH "Install path: SALOME :sat:{PYCMP} specific data") +SET(SALOME_:sat:{PYCMP}_INSTALL_RES_SCRIPTS "${SALOME_INSTALL_RES}/:sat:{PYCMP_minus}" CACHE PATH "Install path: SALOME :sat:{PYCMP} scripts") +SET(SALOME_:sat:{PYCMP}_INSTALL_PLUGINS share/salome/plugins/:sat:{PYCMP_minus} CACHE PATH "Install path: SALOME :sat:{PYCMP} plugins") diff --git a/data/templates/PythonComponent/COPYING b/data/templates/PythonComponent/COPYING new file mode 100755 index 0000000..b1e3f5a --- /dev/null +++ b/data/templates/PythonComponent/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/data/templates/PythonComponent/README b/data/templates/PythonComponent/README new file mode 100755 index 0000000..a6958fa --- /dev/null +++ b/data/templates/PythonComponent/README @@ -0,0 +1 @@ +This module is a SALOME example of a module implemented in Python with PyQt GUI diff --git a/data/templates/PythonComponent/SalomePYCMPConfig.cmake.in b/data/templates/PythonComponent/SalomePYCMPConfig.cmake.in new file mode 100644 index 0000000..68aa358 --- /dev/null +++ b/data/templates/PythonComponent/SalomePYCMPConfig.cmake.in @@ -0,0 +1,110 @@ +# - Config file for the @PROJECT_NAME@ package +# It defines the following variables. +# Specific to the pacakge @PROJECT_NAME@ itself: +# @PROJECT_NAME_UC@_ROOT_DIR_EXP - the root path of the installation providing this CMake file +# + +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +### Initialisation performed by CONFIGURE_PACKAGE_CONFIG_FILE: +@PACKAGE_INIT@ + + +# Package root dir: +SET_AND_CHECK(:sat:{PYCMP}_ROOT_DIR_EXP "@PACKAGE_CMAKE_INSTALL_PREFIX@") + +# Include directories +SET_AND_CHECK(:sat:{PYCMP}_INCLUDE_DIRS "${:sat:{PYCMP}_ROOT_DIR_EXP}/@SALOME_INSTALL_HEADERS@") +SET(:sat:{PYCMP}_INCLUDE_DIRS "${:sat:{PYCMP}_INCLUDE_DIRS};@_Salome:sat:{PYCMP}_EXTRA_HEADERS@") +SET(:sat:{PYCMP}_DEFINITIONS "@GUI_DEFINITIONS@") + +# Package specific environment variables +@_Salome:sat:{PYCMP}_EXTRA_ENV_FULL@ + +# Load the dependencies for the libraries of @PROJECT_NAME@ +# (contains definitions for IMPORTED targets). This is only +# imported if we are not built as a subproject (in this case targets are already there) +IF(NOT TARGET SalomeIDL:sat:{PYCMP} AND NOT @PROJECT_NAME@_BINARY_DIR) + INCLUDE("${:sat:{PYCMP}_ROOT_DIR_EXP}/${SALOME_INSTALL_CMAKE_LOCAL}/Salome:sat:{PYCMP}Targets.cmake") +ENDIF() + +#### Now the specificities + +# Options exported by the package: +SET(SALOME_:sat:{PYCMP}_BUILD_TESTS @SALOME_BUILD_TESTS@) +SET(SALOME_:sat:{PYCMP}_BUILD_DOC @SALOME_BUILD_DOC@) + +# Level 1 prerequisites: +SET_AND_CHECK(GUI_ROOT_DIR_EXP "@PACKAGE_GUI_ROOT_DIR@") + +# For all prerequisites, load the corresponding targets if the package was used +# in CONFIG mode. This ensures dependent projects link correctly +# without having to set LD_LIBRARY_PATH: +SET(_PREREQ_@PROJECT_NAME@ @_PREREQ_LIST@) +SET(_PREREQ_@PROJECT_NAME@_CONFIG_DIR @_PREREQ_DIR_LIST@) +SET(_PREREQ_@PROJECT_NAME@_COMPONENTS "@_PREREQ_COMPO_LIST@") +LIST(LENGTH _PREREQ_@PROJECT_NAME@_CONFIG_DIR _list_len_@PROJECT_NAME@) +IF(NOT _list_len_@PROJECT_NAME@ EQUAL 0) + # Another CMake stupidity - FOREACH(... RANGE r) generates r+1 numbers ... + MATH(EXPR _range_@PROJECT_NAME@ "${_list_len_@PROJECT_NAME@}-1") + FOREACH(_p_@PROJECT_NAME@ RANGE ${_range_@PROJECT_NAME@}) + LIST(GET _PREREQ_@PROJECT_NAME@ ${_p_@PROJECT_NAME@} _pkg_@PROJECT_NAME@ ) + LIST(GET _PREREQ_@PROJECT_NAME@_CONFIG_DIR ${_p_@PROJECT_NAME@} _pkg_dir_@PROJECT_NAME@) + LIST(GET _PREREQ_@PROJECT_NAME@_COMPONENTS ${_p_@PROJECT_NAME@} _pkg_compo_@PROJECT_NAME@) + IF(NOT OMIT_DETECT_PACKAGE_${_pkg_@PROJECT_NAME@}) + MESSAGE(STATUS "===> Reloading targets from ${_pkg_@PROJECT_NAME@} ...") + IF(NOT _pkg_compo_@PROJECT_NAME@) + FIND_PACKAGE(${_pkg_@PROJECT_NAME@} REQUIRED NO_MODULE + PATHS "${_pkg_dir_@PROJECT_NAME@}" + NO_DEFAULT_PATH) + ELSE() + STRING(REPLACE "," ";" _compo_lst_@PROJECT_NAME@ "${_pkg_compo_@PROJECT_NAME@}") + MESSAGE(STATUS "===> (components: ${_pkg_compo_@PROJECT_NAME@})") + FIND_PACKAGE(${_pkg_@PROJECT_NAME@} REQUIRED NO_MODULE + COMPONENTS ${_compo_lst_@PROJECT_NAME@} + PATHS "${_pkg_dir_@PROJECT_NAME@}" + NO_DEFAULT_PATH) + ENDIF() + ENDIF() + ENDFOREACH() +ENDIF() + +# Installation directories +SET(SALOME_INSTALL_BINS "@SALOME_INSTALL_BINS@") +SET(SALOME_INSTALL_LIBS "@SALOME_INSTALL_LIBS@") +SET(SALOME_INSTALL_IDLS "@SALOME_INSTALL_IDLS@") +SET(SALOME_INSTALL_HEADERS "@SALOME_INSTALL_HEADERS@") +SET(SALOME_INSTALL_SCRIPT_SCRIPTS "@SALOME_INSTALL_SCRIPT_SCRIPTS@") +SET(SALOME_INSTALL_SCRIPT_DATA "@SALOME_INSTALL_SCRIPT_DATA@") +SET(SALOME_INSTALL_SCRIPT_PYTHON "@SALOME_INSTALL_SCRIPT_PYTHON@") +SET(SALOME_INSTALL_APPLISKEL_SCRIPTS "@SALOME_INSTALL_APPLISKEL_SCRIPTS@") +SET(SALOME_INSTALL_APPLISKEL_PYTHON "@SALOME_INSTALL_APPLISKEL_PYTHON@") +SET(SALOME_INSTALL_CMAKE_LOCAL "@SALOME_INSTALL_CMAKE_LOCAL@") +SET(SALOME_INSTALL_PYTHON "@SALOME_INSTALL_PYTHON@") +SET(SALOME_INSTALL_PYTHON_SHARED "@SALOME_INSTALL_PYTHON_SHARED@") +SET(SALOME_INSTALL_RES "@SALOME_INSTALL_RES@") +SET(SALOME_INSTALL_DOC "@SALOME_INSTALL_DOC@") +SET(SALOME_INSTALL_AMCONFIG_LOCAL "@SALOME_INSTALL_AMCONFIG_LOCAL@") + +# Include GUI targets if they were not already loaded: +IF(NOT (TARGET Event)) + INCLUDE("${GUI_ROOT_DIR_EXP}/${SALOME_INSTALL_CMAKE}/SalomeGUITargets.cmake") +ENDIF() + +# Exposed :sat:{PYCMP} targets: +SET(:sat:{PYCMP}_SalomeIDL:sat:{PYCMP} SalomeIDL:sat:{PYCMP}) diff --git a/data/templates/PythonComponent/adm_local/CMakeLists.txt b/data/templates/PythonComponent/adm_local/CMakeLists.txt new file mode 100755 index 0000000..55f01a2 --- /dev/null +++ b/data/templates/PythonComponent/adm_local/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +ADD_SUBDIRECTORY(unix) +ADD_SUBDIRECTORY(cmake_files) diff --git a/data/templates/PythonComponent/adm_local/cmake_files/CMakeLists.txt b/data/templates/PythonComponent/adm_local/cmake_files/CMakeLists.txt new file mode 100755 index 0000000..fdcf4ff --- /dev/null +++ b/data/templates/PythonComponent/adm_local/cmake_files/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# =============================================================== +# Files to be installed +# =============================================================== + +# These files are data, module or lib files +SET(_adm_data + FindSalome:sat:{PYCMP}.cmake +) + +INSTALL(FILES ${_adm_data} DESTINATION ${SALOME_INSTALL_CMAKE_LOCAL}) diff --git a/data/templates/PythonComponent/adm_local/cmake_files/FindSalomePYCMP.cmake b/data/templates/PythonComponent/adm_local/cmake_files/FindSalomePYCMP.cmake new file mode 100644 index 0000000..2e22b60 --- /dev/null +++ b/data/templates/PythonComponent/adm_local/cmake_files/FindSalomePYCMP.cmake @@ -0,0 +1,31 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +IF(NOT Salome:sat:{PYCMP}_FIND_QUIETLY) + MESSAGE(STATUS "Looking for Salome :sat:{PYCMP} ...") +ENDIF() + +SET(CMAKE_PREFIX_PATH "${:sat:{PYCMP}_ROOT_DIR}") +SALOME_FIND_PACKAGE(Salome:sat:{PYCMP} Salome:sat:{PYCMP} CONFIG) + +IF(NOT Salome:sat:{PYCMP}_FIND_QUIETLY) + MESSAGE(STATUS "Found Salome :sat:{PYCMP}: ${:sat:{PYCMP}_ROOT_DIR}") +ENDIF() + +FOREACH(_res ${Salome:sat:{PYCMP}_EXTRA_ENV}) + SALOME_ACCUMULATE_ENVIRONMENT(${_res} "${Salome:sat:{PYCMP}_EXTRA_ENV_${_res}}") +ENDFOREACH() diff --git a/data/templates/PythonComponent/adm_local/unix/CMakeLists.txt b/data/templates/PythonComponent/adm_local/unix/CMakeLists.txt new file mode 100755 index 0000000..b63e345 --- /dev/null +++ b/data/templates/PythonComponent/adm_local/unix/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +ADD_SUBDIRECTORY(config_files) diff --git a/data/templates/PythonComponent/adm_local/unix/config_files/CMakeLists.txt b/data/templates/PythonComponent/adm_local/unix/config_files/CMakeLists.txt new file mode 100755 index 0000000..d91ae7d --- /dev/null +++ b/data/templates/PythonComponent/adm_local/unix/config_files/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(_m4_data + check_:sat:{PYCMP}.m4 +) + +INSTALL(FILES ${_m4_data} DESTINATION ${SALOME_INSTALL_AMCONFIG_LOCAL}/config_files) diff --git a/data/templates/PythonComponent/adm_local/unix/config_files/check_PYCMP.m4 b/data/templates/PythonComponent/adm_local/unix/config_files/check_PYCMP.m4 new file mode 100755 index 0000000..80160d7 --- /dev/null +++ b/data/templates/PythonComponent/adm_local/unix/config_files/check_PYCMP.m4 @@ -0,0 +1,75 @@ +dnl Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +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 + +# Check availability of :sat:{PYCMP} binary distribution +# +# Author : Marc Tajchman (CEA, 2002) +#------------------------------------------------------------ + +AC_DEFUN([CHECK_:sat:{PYCMP}],[ + +AC_CHECKING(for :sat:{PYCMP}) + +:sat:{PYCMP}_ok=no + +AC_ARG_WITH(:sat:{PYCMP}, + --with-:sat:{PYCMP_minus}=DIR root directory path of :sat:{PYCMP} installation, + :sat:{PYCMP}_DIR="$withval",:sat:{PYCMP}_DIR="") + +if test "x$:sat:{PYCMP}_DIR" = "x" ; then + +# no --with-:sat:{PYCMP_minus} option used + + if test "x$:sat:{PYCMP}_ROOT_DIR" != "x" ; then + + # :sat:{PYCMP}_ROOT_DIR environment variable defined + :sat:{PYCMP}_DIR=$:sat:{PYCMP}_ROOT_DIR + + else + + # search :sat:{PYCMP} binaries in PATH variable + AC_PATH_PROG(TEMP, :sat:{PYCMP}GUI.py) + if test "x$TEMP" != "x" ; then + :sat:{PYCMP}_BIN_DIR=`dirname $TEMP` + :sat:{PYCMP}_DIR=`dirname $:sat:{PYCMP}_BIN_DIR` + fi + + fi +# +fi + +if test -f ${:sat:{PYCMP}_DIR}/bin/salome/:sat:{PYCMP}GUI.py ; then + :sat:{PYCMP}_ok=yes + AC_MSG_RESULT(Using :sat:{PYCMP} distribution in ${:sat:{PYCMP}_DIR}) + + if test "x$:sat:{PYCMP}_ROOT_DIR" == "x" ; then + :sat:{PYCMP}_ROOT_DIR=${:sat:{PYCMP}_DIR} + fi + AC_SUBST(:sat:{PYCMP}_ROOT_DIR) +else + AC_MSG_WARN("Cannot find compiled $:sat:{PYCMP} distribution") +fi + +AC_MSG_RESULT(for :sat:{PYCMP}: :sat:{PYCMP}_ok) + +])dnl + diff --git a/data/templates/PythonComponent/bin/CMakeLists.txt b/data/templates/PythonComponent/bin/CMakeLists.txt new file mode 100644 index 0000000..8f6016c --- /dev/null +++ b/data/templates/PythonComponent/bin/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Python_SOURCES + test_:sat:{PYCMP}.py +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/data/templates/PythonComponent/bin/test_PYCMP.py b/data/templates/PythonComponent/bin/test_PYCMP.py new file mode 100755 index 0000000..c70fbd6 --- /dev/null +++ b/data/templates/PythonComponent/bin/test_PYCMP.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +import salome +import :sat:{PYCMP} + +salome.salome_init() + +ppf5 = salome.lcc.FindOrLoadComponent("FactoryServerPy", ":sat:{PYCMP}") + +print ppf5.touch(":sat:{PYCMP}") diff --git a/data/templates/PythonComponent/doc/CMakeLists.txt b/data/templates/PythonComponent/doc/CMakeLists.txt new file mode 100644 index 0000000..93b521e --- /dev/null +++ b/data/templates/PythonComponent/doc/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SALOME_CONFIGURE_FILE(doxyfile.in doxyfile) + +ADD_CUSTOM_TARGET(usr_docs ${DOXYGEN_EXECUTABLE}) + +INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target usr_docs)") +INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/:sat:{PYCMP} DESTINATION ${SALOME_INSTALL_DOC}/gui) +INSTALL(FILES images/head.png DESTINATION ${SALOME_INSTALL_DOC}/gui/:sat:{PYCMP}) + +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES :sat:{PYCMP}) diff --git a/data/templates/PythonComponent/doc/doxyfile.in b/data/templates/PythonComponent/doc/doxyfile.in new file mode 100755 index 0000000..61deb0d --- /dev/null +++ b/data/templates/PythonComponent/doc/doxyfile.in @@ -0,0 +1,81 @@ +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = ":sat:{PYCMP} sample module reference manual v.@VERSION@" +OUTPUT_DIRECTORY = :sat:{PYCMP} +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +TAB_SIZE = 5 + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES + +#--------------------------------------------------------------------------- +#Input related options +#--------------------------------------------------------------------------- +INPUT = @CMAKE_CURRENT_SOURCE_DIR@ +FILE_PATTERNS = *.doc +EXCLUDE = +IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images +EXAMPLE_PATH = + +#--------------------------------------------------------------------------- +#HTML related options +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_HEADER = @CMAKE_CURRENT_SOURCE_DIR@/static/header.html +HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/static/footer.html +HTML_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/static/doxygen.css +TOC_EXPAND = YES +DISABLE_INDEX = NO +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 300 + +#--------------------------------------------------------------------------- +#SORT related options +#--------------------------------------------------------------------------- +SORT_GROUP_NAMES = NO + + +#--------------------------------------------------------------------------- +#LaTeX related option +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO + +#--------------------------------------------------------------------------- +#RTF related options +#--------------------------------------------------------------------------- +GENERATE_RTF = NO + +#--------------------------------------------------------------------------- +#External reference options +#--------------------------------------------------------------------------- +TAGFILES = +ALLEXTERNALS = NO +SEARCHENGINE = NO diff --git a/data/templates/PythonComponent/doc/images/head.png b/data/templates/PythonComponent/doc/images/head.png new file mode 100755 index 0000000..307d9ef Binary files /dev/null and b/data/templates/PythonComponent/doc/images/head.png differ diff --git a/data/templates/PythonComponent/doc/index.doc b/data/templates/PythonComponent/doc/index.doc new file mode 100755 index 0000000..a5fd6a4 --- /dev/null +++ b/data/templates/PythonComponent/doc/index.doc @@ -0,0 +1,666 @@ +/*! + +\mainpage Introduction to :sat:{PYCMP} sample module + +The purpose of the \b :sat:{PYCMP} module is to describe briefly the different +steps in the development of a SALOME module in Python. + +Contents: +- \subpage dev_steps +- \subpage tree_structure +- \subpage build_proc_files +- \subpage idl_dir +- \subpage src_dir +- \subpage bin_dir +- \subpage doc_dir +- \subpage build_procedure +- \subpage run_procedure +- \subpage load_module +- \subpage catalog_def +- \subpage load_lcc +- \subpage load_iapp + +\ref dev_steps ">> Next" + +\page dev_steps Steps in construction of the example module + +The example module chosen to illustrate the process of SALOME module +development is extremely simple. The module contains a single +component and this component provides a single service called \b +makeBanner that accepts a character string as the sole argument and +that returns a character string obtained by the concatenation of a +':sat:{PYCMP}' and the input string. The component also provides a simple +GUI. + +The steps in the development are as follows: +- create a module tree structure +- create a SALOME component that can be loaded by a Python SALOME container +- configure the module so that the component is known to SALOME +- add a graphic GUI + +\ref main "<< Previous"
\ref tree_structure ">> Next" + +\page tree_structure Create the module tree structure + +The first step in the development process is the creation of the +module tree file structure. The typical SALOME module usually includes +some set of the configuration files (used in the build procedure of a +module), Makefiles, IDL file that provides a definition of a CORBA +services implemented in a module and a set of source Python files +which implement the module CORBA engine and (optionally) its GUI. + +The following file structure is typical for the SALOME module: + +
++ :sat:{PYCMP}1_SRC
+   + build_configure
+   + configure.ac
+   + Makefile.am
+   + adm_local
+     + Makefile.am
+     + unix
+       + Makefile.am
+       + make_common_starter.am
+       + config_files
+         + Makefile.am
+         + check_:sat:{PYCMP}.m4
+   + bin
+     + Makefile.am
+     + VERSION.in
+     + runAppli.in
+     + myrunSalome.py
+   + idl
+     + Makefile.am
+     + :sat:{PYCMP}_Gen.idl
+   + src
+     + Makefile.am
+     + :sat:{PYCMP}
+       + Makefile.am
+       + :sat:{PYCMP}.py
+       + :sat:{PYCMP}_utils.py
+     + :sat:{PYCMP}GUI
+       + Makefile.am
+       + :sat:{PYCMP}GUI.py
+       + :sat:{PYCMP}_msg_en.ts
+       + :sat:{PYCMP}_icons.ts
+   + resources
+     + Makefile.am
+     + :sat:{PYCMP}.png
+     + :sat:{PYCMP}_small.png
+     + Exec:sat:{PYCMP}.png
+     + handshake.png
+     + stop.png
+     + :sat:{PYCMP}Catalog.xml.in
+     + SalomeApp.xml
+   + doc
+     + Makefile.am
+     + doxyfile.in
+     + index.doc
+
+ +Note that other files can be optionally present. For example, in some +SALOME modules sources tree you can find such files as AUTHORS, +INSTALL, ChangeLog, COPYING, NEWS, README, etc. Some files are +specific only for this :sat:{PYCMP} sample module, for example PNG images +in the resources directory which are used in the GUI dialog boxes etc. + +The usual way of the sources directory tree structure initial creation +is to copy it from the existing SALOME module. + +\warning The files of the platform base module (KERNEL) must not be +copied to initialise a module tree structure. It is usually preferable +to copy files from another module such as GEOM or MED. + +The module name is :sat:{PYCMP}, the component name is :sat:{PYCMP} and all the +files are put in a directory named :sat:{PYCMP}1_SRC. +Below is a short description of these files. Note, that files with .in +suffix are the autoconf templates from which the actual files are +generated during the build procedure. + +- build_configure, configure.ac, Makefile.am, make_common_starter.am + +These files are a part of the build system based on GNU +automake/autoconf auto-tools. These files define the build procedure, +namely, compilation and installation rules like compiler and linker +options, installation destination folder, package version etc. + +- adm_local/unix/config_files/check_:sat:{PYCMP}.m4 + +The files in this directory are also a part of the GNU auto-tools +-based build procedure. The scripts written in m4 language are usually +used to test an availability of some 3rd-party pre-requisite product, +compiler feature, different configuration options. + +- bin/VERSION.in + +This file is used to document the module, it must give its version (at +least) and (optionally) compatibilities or incompatibilities with +other modules. This file is strongly recommended but is not essential +for operation of the module. + +- bin/runAppli.in +- bin/runSalome.py + +These files are not essential but make the example easier to +use. These are scripts that can be used to run SALOME session with +:sat:{PYCMP} module. + +- idl/:sat:{PYCMP}_Gen.idl + +This is the CORBA IDL definition of the services implemented by SALOME +:sat:{PYCMP} module. + +- src/:sat:{PYCMP}/:sat:{PYCMP}.py +- src/:sat:{PYCMP}/:sat:{PYCMP}_utils.py + +These files provide the implementation of a CORBA engine of the +:sat:{PYCMP} module. In particular, this is an implementation of the +services defined in the :sat:{PYCMP}_Gen.idl file. + +- src/:sat:{PYCMP}GUI/:sat:{PYCMP}GUI.py + +The src/:sat:{PYCMP}GUI is an optional directory that provides an +implementation of :sat:{PYCMP} module's GUI. Strictly speaking, the +GUI is optional for each SALOME module. In some cases it's +enough to implement CORBA engine only. Then, the services of the +module will be avaiable in a CORBA environment. The module can be +loaded to the SALOME container and its services can be used in the +Supervisor computation schemas, in Python scripts or/and refer to it +in other modules. A GUI is necessary in the cases if it is planned to +access to the module functionality from the SALOME GUI session via +menu actions, dialog boxes and so on. + +- src/:sat:{PYCMP}GUI/:sat:{PYCMP}_msg_en.ts +- src/:sat:{PYCMP}GUI/:sat:{PYCMP}_icons.ts + +These files provide a description (internationalization) of GUI +resources of the :sat:{PYCMP} module. :sat:{PYCMP}_msg_en.ts provides an English +translation of the string resources used in a module. :sat:{PYCMP}_icons.ts +defines images and icons resources used within the GUI of the +:sat:{PYCMP} module. Please refer to Qt linguist documentation for more +details. + +- resources/:sat:{PYCMP}.png +- resources/:sat:{PYCMP}_small.png +- resources/Exec:sat:{PYCMP}.png +- resources/handshake.png +- resources/stop.png + +The resources folder usually includes different resource files used +within the SALOME module. For example, :sat:{PYCMP}.png file provides an icon +of :sat:{PYCMP} module to be shown in the SALOME GUI desktop. Exec:sat:{PYCMP}.png is +an icon for the makeBanner() function used in the menu and +toolbar. The icons handshake.png and stop.png are used in the dialog +boxes and :sat:{PYCMP}_small.png icon is used to display in the Object +browser for root :sat:{PYCMP} entity. + +- resources/:sat:{PYCMP}Catalog.xml.in + +The XML description of the CORBA services provided by the :sat:{PYCMP} +module. This file is parsed by Supervisor and YACS module to generate +the list of service nodes to be used in the calculation schemas. The +simplest way to create this file is to use Catalog Generator utility +provided by the SALOME KERNEL module, that can automatically generate +XML description file from the IDL file. + +- resources/SalomeApp.xml + +This file is essential for the module. It provides some parameters of +the module which define module behavior in SALOME. In particular it +should provide a section with the name corresponding to the name of a +module (":sat:{PYCMP}" in this case) with the following parameters: +\code +
+ + + +
+\endcode + +The "name" parameter defines GUI name of a module. The "icon" +parameter defines a GUI icon of a module. The parameter "library" +specifies the name of the C++ library representing the front-end of +the module in the SALOME GUI desktop. The Python modules which do not +implement its own C++ front-end GUI library should specify +"SalomePyQtGUI" value in this parameter. + +The section "resources" also specifies the directory that contains +resources of a module (icons, translation files, etc). + +\code +
+ +
+\endcode + +- doc/doxyfile.in + +The Doxygen configuration file. The Doxygen is used to build this +documentation. The file doxyfile.in provides a rules for the +generation of module documentation. + +- doc/index.doc + +An input file for the Doxygen, which provides a source of this documentation. + +\ref dev_steps "<< Previous"
\ref build_proc_files ">> Next" + +\page build_proc_files Build procedure input files + +SALOME uses autoconf and automake GNU auto-tools to build the +modules. The configure script is used for the build procedure to test +the system configuration and to pre-configure the module construction +Makefile files. + +The \b build_configure script provides a procedure that uses \b +configure.ac and set of \b Makefile.am files as input and uses autoconf +to generate the configure script and automake to generate Makefile.in +files. + +The files with an .in extension are the skeletons that are the input +of the configure script (to be more precise, these files should be +listed in the end of the configure.ac file in the AC_OUTPUT() +autoconf macro) and are transformed by the configure process. + +Almost all files used for this process are located in the platform +base module KERNEL that is referenced by the KERNEL_ROOT_DIR +environment variable, namely in its salome_adm sub-folder. +Similarly, the GUI_ROOT_DIR environment variable is used for the +graphical user interface (GUI), that also provides a set of +configuration utilities (m4 files) in its adm_local folder. However, +some files must be modified as a function of the target module. This +is the case for build_configure and configure.ac files which usually +need to be adapted to the module needs. + +The file \b make_common_starter.am file in the adm_local directory of +the example module provides basic build rules to be used in other +Makefile.am files. To refer to this file in the Makefile.am it is +necessary to use "include" clause: + +\code +include $(top_srcdir)/adm_local/unix/make_common_starter.am +\endcode + +The adm_local/unix/config_files is a directory in which the m4 files +that are used to test the configuration of the system in the configure +process can be placed. If the salome_adm files are not sufficient, +additional configuration files can be put to the adm_local directory. + +\ref tree_structure "<< Previous"
\ref idl_dir ">> Next" + +\page idl_dir The idl directory + +The idl directory requires a Makefile.am that must make the +compilation of the idl :sat:{PYCMP}_Gen.idl file and install all the +generated files into the correct module installation directories. The +BASEIDL_FILES target has to be modified to reach this goal. + +The idl file itself must define a CORBA module for which the name must +be different from the module name to avoid name conflicts and define a +CORBA interface that is derived at least from the EngineComponent interface +of the Engines module. The name of the CORBA module will be +\b :sat:{PYCMP}_ORB and the name of the interface will be \b :sat:{PYCMP}_Gen. + +\ref build_proc_files "<< Previous"
\ref src_dir ">> Next" + +\page src_dir The src directory + +The src contains all source files required to build and install CORBA +engine and (optionally) GUI of the module. Each of these entities usually +has (but this is not actually obligatory) its own directory. + +The Makefile.am simply triggers the path of sub-directories described +by the SUBDIRS target. + +- The src/:sat:{PYCMP} directory + +This directory contains the Python files that implement the engine +of the module. The Makefile.am defines the rules used to install these +files to the destination folder. The name of the module +engine Python file is predefined and should be set as .py +where is a name of the module. In the case of the :sat:{PYCMP} +module, the name of the engine Python script should be :sat:{PYCMP}.so. + +The :sat:{PYCMP}.py Python script implements :sat:{PYCMP} class that is derived +from the :sat:{PYCMP}_Gen interface of the :sat:{PYCMP}_ORB__POA CORBA module, +the SALOME_ComponentPy_i class (base implementation of SALOME +Python module engine exported by the KERNEL module) and +SALOME_DriverPy_i class that provides base implementation of +persistence mechanism. + +In particular, :sat:{PYCMP} class implements makeBanner() function that is +defined in the IDL interface :sat:{PYCMP}_ORB:::sat:{PYCMP}_Gen. + +\code +def makeBanner( self, name ): + banner = ":sat:{PYCMP} %s!" % name + return banner +\endcode + +Other services +defined in :sat:{PYCMP}_Gen CORBA interface also should be implemented by +this class. + +- The src/:sat:{PYCMP}GUI directory + +This directory contains the Python files that implement the GUI +of :sat:{PYCMP} module. The name of the module GUI Python script is +predefined and should be set as GUI.py where is a +name of the module. In the case of the :sat:{PYCMP} module, the name of the +GUI Python script should be :sat:{PYCMP}GUI.py. + +The implementation of GUI of the :sat:{PYCMP} module should be done +according to the architecture and rules specified by the SALOME GUI +module. The :sat:{PYCMP}.py script should implement a set of the functions +which define the module behavior in GUI, for example, create menus, +toolbars, define context popup menus, objects selection behavior, +implement dialog boxes etc. + +Here below is a short description of these methods. For more details +please refer to the SALOME GUI module documentation. + +- initialize() - module first initialization; usually used to create + GUI actions, menus, toolbars and so on; +- activate() - module activation; perform actions which should + be done when the module is activated by the user; +- deactivate() - module deactivation; perform actions which should + be done when the module is deactivated by the user; +- windows() - get a list and a position of the windows to be + associated with the module; these windows will be automatically + opened and positioned according to the setting defined by the value + returned by this function; +- views() - get a list of the compatible viewers; these viewers + will be automatically opened/raised on the module activation; +- createPopupMenu() - create and return context popup menu according + to the current selection; +- createPreferences() - initialize module's preferences; +- preferenceChanged() - callback function that is called when some + module's preference is changed by the user; allows to perform the + corresponding actions; +- engineIOR() - to get the reference to the module CORBA engine + +Note, that some of these methods are optional and need not be +obligatory implemented because SalomePyQtGUI_Module class provides a +base implementation of these functions. It's sometimes enough to +implement only some of them, depending on the module needs. + +In the case of :sat:{PYCMP} module, some of these functions are +implemented to provide a sample for the development: + +- engineIOR() that initializes :sat:{PYCMP} module's eggine: + +\code +def engineIOR(): + IOR = "" + if getORB() and getEngine(): + IOR = getORB().object_to_string( getEngine() ) + pass + return IOR +\endcode + +- initialize() that sets default module preferences + +\code +def initialize(): + if not sgPyQt.hasSetting( ":sat:{PYCMP}", "def_obj_name"): + sgPyQt.addSetting( ":sat:{PYCMP}", "def_obj_name", GUIcontext.DEFAULT_NAME ) + if not sgPyQt.hasSetting( ":sat:{PYCMP}", "creation_mode"): + sgPyQt.addSetting( ":sat:{PYCMP}", "creation_mode", 0 ) +\endcode + +- createPreferences() that initializes module preferences for the + application's Preferences dialog box + +\code +def createPreferences(): + if verbose() : print ":sat:{PYCMP}GUI.createPreferences() : study : %d" % _getStudyId() + gid = sgPyQt.addPreference( "General" ) + gid = sgPyQt.addPreference( "Object creation", gid ) + pid = sgPyQt.addPreference( "Default name", gid, SalomePyQt.PT_String, ":sat:{PYCMP}", "def_obj_name" ) + pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, ":sat:{PYCMP}", "creation_mode" ) + strings = QStringList() + strings.append( "Default name" ) + strings.append( "Generate name" ) + strings.append( "Ask name" ) + indexes = [] + indexes.append( QVariant(0) ) + indexes.append( QVariant(1) ) + indexes.append( QVariant(2) ) + sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) ) + sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) ) + pass +\endcode + +- windows() that defines dockable windows layout + +\code +def windows(): + if verbose() : print ":sat:{PYCMP}GUI.windows() : study : %d" % _getStudyId() + wm = {} + wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea + wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea + return wm +\endcode + +Please refer to :sat:{PYCMP}GUI.py script for more details about +implementation of other callback functions. + +An implemention of the Show:sat:{PYCMP}() function is quite simple. It shows +the small dialog box allowing user to enter the name, and then uses +reference to the module CORBA engine to invoke its makeBanner() +service. + +Note, that GUI elements of the Python module are implemented with help +of PyQt toolkit which provides a Python wrappings of the Qt library. + +\ref idl_dir "<< Previous"
\ref bin_dir ">> Next" + +\page bin_dir The bin directory + +The file VERSION.in is used to document the module, it must define its +version and (optionally) its compatibilities or incompatibilities with +other modules. Therefore, it is strongly recommended but is not +essential for correct operation of the module. + +The runAppli.in file is the equivalent of the runSalome script +distributed by the KERNEL module but configured to start SALOME +session with :sat:{PYCMP} module only. + +The myrunSalome.py file reuses part of functionality provided by the +KERNEL's runSalome.py script. It is used to run SALOME session and +start :sat:{PYCMP} module in this session. + +\ref src_dir "<< Previous"
\ref doc_dir ">> Next" + +\page doc_dir The doc directory + +This directory provides documentation files of the module. The +documentation of the module can be implemented in the arbitrary +way. But if you want your documentation to appear in the SALOME GUI +desktop's Help menu, some specific actions should be done as follows. + +The documentation should be generated in the HTML format. For example, +the documentation of the :sat:{PYCMP} module is generated using Doxygen +tool. It allows to generate structured set of HTML pages from the set +of input plain text files. Input source files should include Doxygen +tags and optionally direct HTML tags. For more details please refer to +the Doxygen documentation. + +The resulting documentation of a module should include at least one +file index.html. All the HTML and image files should be exported by +the build procedure to the following directory: +/share/doc/salome/gui/ +where is a module installation folder and +MODULE is its name. For example, for :sat:{PYCMP} module, at least one file +should exist: +<:sat:{PYCMP}_module_installation_dir>/share/doc/salome/gui/:sat:{PYCMP}/index.html. + +The SALOME GUI automatically searches for the index.html file in the +mentioned module directory. If the file is found, the corresponding +menu command is automatically added to the Help menu of the SALOME GUI +desktop. + +\ref bin_dir "<< Previous"
\ref build_procedure ">> Next" + +\page build_procedure Construction, installation + +Before building :sat:{PYCMP} module, please ensure that SALOME environment is +set properly. Assume that SALOME environment is set in env_products.sh +script. In order to build and install :sat:{PYCMP} module, you have to +perform several steps: + +
+[bash% ] source env_products.sh
+[bash% ] mkdir :sat:{PYCMP}_BUILD
+[bash% ] cd :sat:{PYCMP}_BUILD
+[bash% ] ../:sat:{PYCMP}1_SRC/build_configure
+[bash% ] ../:sat:{PYCMP}1_SRC/configure --prefix=<:sat:{PYCMP}_module_installation_dir>
+[bash% ] make
+[bash% ] make install
+
+ +The first command creates a build directory for the :sat:{PYCMP} module. Then +next step is to cd to this build directory. From this directory you +sequentially invoke build_configure, configure, make and make install +commands. On each step, you have to ensure that the operation is +finished correctly (no errors raised). + +The <:sat:{PYCMP}_module_installation_dir> variable above defines the +destination directory to which the :sat:{PYCMP} module should be +installed. After the last step is finished, the :sat:{PYCMP} module is built +and installed to the <:sat:{PYCMP}_module_installation_dir> directory. + +\ref doc_dir "<< Previous"
\ref run_procedure ">> Next" + +\page run_procedure Running SALOME + +Go to the the <:sat:{PYCMP}_module_installation_dir> directory and type: + +
+[bash% ] ./bin/salome/runAppli
+
+ +This command runs SALOME session configured for KERNEL and the :sat:{PYCMP} +module. At the end of running, the user will be prompted by the +Python interpreter command line configured for SALOME that provides +access to SALOME Python API (including CORBA interfaces). + +The runAppli file is a shell script that executes a Python commands +running SALOME session by passing arguments to it in a command line: + +
+${KERNEL_ROOT_DIR}/bin/salome/envSalome.py python -i $:sat:{PYCMP}_ROOT_DIR/bin/salome/myrunSalome.py --modules=:sat:{PYCMP} --killall
+
+ +These arguments state that the myrunSalome.py script located in the +:sat:{PYCMP} module will be used, that the :sat:{PYCMP} component will be +activated and all previously running SALOME sessions should be +shutdowned. + +This command will not function unless the following environment +variables have previously been set: + +
+export KERNEL_ROOT_DIR=
+export :sat:{PYCMP}_ROOT_DIR=<:sat:{PYCMP} installation path>
+
+ +\warning It is possible that the SALOME run will not reach the end. +In some circumstances, the time to start CORBA servers may be long and +could exceed the timeout. If the reasons is that the time to +load dynamic libraries is long, it is possible that a second run +immediately afterwards will be successful. + +\ref build_procedure "<< Previous"
\ref load_module ">> Next" + +\page load_module Loading :sat:{PYCMP} component + +The :sat:{PYCMP}_ORB module has to be imported before making a request to +load the component into the container, to obtain access to methods of +the component. This container is made accessible in the runSalome.py +by means of the \b container variable: + +
+>> import :sat:{PYCMP}_ORB
+>> c=container.load_impl(":sat:{PYCMP}",":sat:{PYCMP}")
+>> c.makeBanner("Christian")
+
+ +The last instruction returns a string ":sat:{PYCMP} Christian". Proceed as +follows to see the CORBA objects created by these actions: + +
+>> clt.showNS()
+
+ +\ref run_procedure "<< Previous"
\ref catalog_def ">> Next" + +\page catalog_def :sat:{PYCMP} module catalog definition + +In the example from the previous chapter, the :sat:{PYCMP} component was +loaded by making a direct request to the SALOME container. This is not +the standard method for loading of a component. The normal way uses +the SALOME LifeCycle service that invokes SALOME Module Catalog +services to identify the component and its properties and then calls +the requested container to load the component. + +Before this method can be used, the component must be declared in a +catalog in the XML format, for which the name must be +Catalog.xml. In our case, it will be :sat:{PYCMP}Catalog.xml. +Usually this catalog is put to the resources sub-directory of the +directory tree. The simplest way to create this file is to use Catalog +Generator utility provided by the SALOME KERNEL module, that can +automatically generate XML description file from the IDL file. + +\ref load_module "<< Previous"
\ref load_lcc ">> Next" + +\page load_lcc Loading :sat:{PYCMP} component via LifeCycle service + +The method of loading the component is not very different from that +is described above. The services of the LifeCycle module are used in +this case instead of calling the container directly. The call sequence +is contained in the runSalome.Py \b test() function. + +
+    c=test(clt)
+    c.makeBanner("Christian")
+
+ +The test function creates the LifeCycle object. It then asks for the +:sat:{PYCMP} component to be loaded in the FactoryServer container: + +\code +def test(clt): + """ + Test function that creates an instance of :sat:{PYCMP} component + usage : myCompo=test(clt) + """ + import LifeCycleCORBA + lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb) + import :sat:{PYCMP}_ORB + myCompo = lcc.FindOrLoadComponent("FactoryServePy", ":sat:{PYCMP}") + return myCompo +\endcode + +\ref catalog_def "<< Previous"
\ref load_iapp ">> Next" + +\page load_iapp Loading from the GUI (IAPP) + +In order to activate :sat:{PYCMP} module in the SALOME GUI desktop, the user +should press the :sat:{PYCMP} module's button on the "Modules" toolbar or +select the name of the module in the combo box on this toolbar. + +The image file to be used as an icon of a module should be exported by +the module build procedure. The icon file name is defined in the +corresponding SalomeApp.xml configuration file: +\code +
+ + + +
+\endcode + +\ref load_lcc "<< Previous" + +*/ diff --git a/data/templates/PythonComponent/doc/static/doxygen.css b/data/templates/PythonComponent/doc/static/doxygen.css new file mode 100755 index 0000000..9d051a4 --- /dev/null +++ b/data/templates/PythonComponent/doc/static/doxygen.css @@ -0,0 +1,830 @@ +/* The standard CSS for doxygen */ + +body, table, div, p, dl { + font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size: 12px; +} + +/* @group Heading Levels */ + +h1 { + font-size: 150%; +} + +h2 { + font-size: 120%; +} + +h3 { + font-size: 100%; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + padding: 2px; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code { + color: #4665A2; +} + +a.codeRef { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +.fragment { + font-family: monospace, fixed; + font-size: 105%; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.version { + border:1px solid #0000FF; + color: #CCCCCC; + font-family: Arial, Helvetica, sans-serif; + font-size: 9pt; + text-align: center; + width:100px; + -moz-border-radius: 8px; + margin: 5px; +} + +div.footer1 { + background-color: #DFE5F1; + border: 1px solid #AAAAAA; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + padding: 10px; + margin-top: 15px; +} + + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 10px; + margin-right: 10px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memItemLeft, .memItemRight, .memTemplParams { + border-top: 1px solid #C4CFE5; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.memitem { + padding: 0; + margin-bottom: 10px; +} + +.memname { + white-space: nowrap; + font-weight: bold; + margin-left: 6px; +} + +.memproto { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 8px; + border-top-left-radius: 8px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 8px; + -moz-border-radius-topleft: 8px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 8px; + -webkit-border-top-left-radius: 8px; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + +} + +.memdoc { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 2px 5px; + background-color: #FBFCFD; + border-top-width: 0; + /* opera specific markup */ + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} + +.params, .retval, .exception, .tparams { + border-spacing: 6px 2px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + + + + +/* @end */ + +/* @group Directory (tree) */ + +/* for the tree view */ + +.ftvtree { + font-family: sans-serif; + margin: 0px; +} + +/* these are for tree view when used as main index */ + +.directory { + font-size: 9pt; + font-weight: bold; + margin: 5px; +} + +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +/* +The following two styles can be used to replace the root node title +with an image of your choice. Simply uncomment the next two styles, +specify the name of your image and be sure to set 'height' to the +proper pixel height of your image. +*/ + +/* +.directory h3.swap { + height: 61px; + background-repeat: no-repeat; + background-image: url("yourimage.gif"); +} +.directory h3.swap span { + display: none; +} +*/ + +.directory > h3 { + margin-top: 0; +} + +.directory p { + margin: 0px; + white-space: nowrap; +} + +.directory div { + display: none; + margin: 0px; +} + +.directory img { + vertical-align: -30%; +} + +/* these are for tree view when not used as main index */ + +.directory-alt { + font-size: 100%; + font-weight: bold; +} + +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +.directory-alt > h3 { + margin-top: 0; +} + +.directory-alt p { + margin: 0px; + white-space: nowrap; +} + +.directory-alt div { + display: none; + margin: 0px; +} + +.directory-alt img { + vertical-align: -30%; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; +} + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + padding-left: 5px; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug +{ + border-left:4px solid; + padding: 0 0 0 6px; +} + +dl.note +{ + border-color: #D0D000; +} + +dl.warning, dl.attention +{ + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + border-color: #00D000; +} + +dl.deprecated +{ + border-color: #505050; +} + +dl.todo +{ + border-color: #00C0E0; +} + +dl.test +{ + border-color: #3030E0; +} + +dl.bug +{ + border-color: #C08050; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + background-color: #175783; + border: 1px solid; + height: 80px; + background-repeat: no-repeat; +/* font: 300% arial,sans-serif;*/ + margin: 0px; + padding: 0px; +} + +#projectbrief +{ + font: 120% arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + background: url("head.png"); + background-color: #175783; + border: 1px solid; + height: 80px; + background-repeat: no-repeat; + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + diff --git a/data/templates/PythonComponent/doc/static/footer.html b/data/templates/PythonComponent/doc/static/footer.html new file mode 100755 index 0000000..ec09dc6 --- /dev/null +++ b/data/templates/PythonComponent/doc/static/footer.html @@ -0,0 +1,12 @@ + + + +
+
+ Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
+ Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+
+
+ + + diff --git a/data/templates/PythonComponent/doc/static/header.html b/data/templates/PythonComponent/doc/static/header.html new file mode 100755 index 0000000..55707a0 --- /dev/null +++ b/data/templates/PythonComponent/doc/static/header.html @@ -0,0 +1,22 @@ + + + + +$title + + + + + + + + + + + +
+
Version: 1.0
+ +
diff --git a/data/templates/PythonComponent/idl/CMakeLists.txt b/data/templates/PythonComponent/idl/CMakeLists.txt new file mode 100644 index 0000000..5c85744 --- /dev/null +++ b/data/templates/PythonComponent/idl/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# Provided by KERNEL +INCLUDE(UseOmniORB) + +INCLUDE_DIRECTORIES( + ${OMNIORB_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${KERNEL_INCLUDE_DIRS} +) + +SET(IDL_SOURCES + :sat:{PYCMP}_Gen.idl +) + +SET(_idl_include_dirs + ${KERNEL_ROOT_DIR}/idl/salome +) + +SET(_idl_link_flags + ${KERNEL_SalomeIDLKernel} +) + +OMNIORB_ADD_MODULE(SalomeIDL:sat:{PYCMP} "${IDL_SOURCES}" "${_idl_include_dirs}" "${_idl_link_flags}") + +INSTALL(TARGETS SalomeIDL:sat:{PYCMP} EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) diff --git a/data/templates/PythonComponent/idl/PYCMP_Gen.idl b/data/templates/PythonComponent/idl/PYCMP_Gen.idl new file mode 100755 index 0000000..e30d5e0 --- /dev/null +++ b/data/templates/PythonComponent/idl/PYCMP_Gen.idl @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// --- +// File: :sat:{PYCMP}GUI.py +// --- + +#ifndef __:sat:{PYCMP}_GEN__ +#define __:sat:{PYCMP}_GEN__ + +#include "SALOME_Component.idl" +#include "SALOMEDS.idl" +#include "SALOME_Exception.idl" + +module :sat:{PYCMP}_ORB +{ + interface :sat:{PYCMP}_Gen : Engines::EngineComponent, SALOMEDS::Driver + { + string touch(in string name) + raises (SALOME::SALOME_Exception); + + void createObject(in SALOMEDS::Study theStudy, + in string name) + raises (SALOME::SALOME_Exception); + }; +}; + +#endif diff --git a/data/templates/PythonComponent/resources/CMakeLists.txt b/data/templates/PythonComponent/resources/CMakeLists.txt new file mode 100644 index 0000000..6ae660c --- /dev/null +++ b/data/templates/PythonComponent/resources/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Others_RESOURCES + :sat:{PYCMP}.png + :sat:{PYCMP}_small.png + Exec:sat:{PYCMP}.png + handshake.png + stop.png + ExecDelAll.png + ExecCircle.png + ExecPolyline.png + SalomeApp.xml + :sat:{PYCMP}Catalog.xml +) + +INSTALL(FILES ${Others_RESOURCES} DESTINATION ${SALOME_:sat:{PYCMP}_INSTALL_RES_DATA}) diff --git a/data/templates/PythonComponent/resources/ExecCircle.png b/data/templates/PythonComponent/resources/ExecCircle.png new file mode 100755 index 0000000..4241692 Binary files /dev/null and b/data/templates/PythonComponent/resources/ExecCircle.png differ diff --git a/data/templates/PythonComponent/resources/ExecDelAll.png b/data/templates/PythonComponent/resources/ExecDelAll.png new file mode 100755 index 0000000..bca4e7e Binary files /dev/null and b/data/templates/PythonComponent/resources/ExecDelAll.png differ diff --git a/data/templates/PythonComponent/resources/ExecPYCMP.png b/data/templates/PythonComponent/resources/ExecPYCMP.png new file mode 100755 index 0000000..16a20c1 Binary files /dev/null and b/data/templates/PythonComponent/resources/ExecPYCMP.png differ diff --git a/data/templates/PythonComponent/resources/ExecPolyline.png b/data/templates/PythonComponent/resources/ExecPolyline.png new file mode 100755 index 0000000..14eced8 Binary files /dev/null and b/data/templates/PythonComponent/resources/ExecPolyline.png differ diff --git a/data/templates/PythonComponent/resources/Makefile.am b/data/templates/PythonComponent/resources/Makefile.am new file mode 100755 index 0000000..4efa7e1 --- /dev/null +++ b/data/templates/PythonComponent/resources/Makefile.am @@ -0,0 +1,39 @@ +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# -* Makefile *- +# Author : Patrick GOLDBRONN (CEA) +# Date : 28/06/2001 +# Modified by : Alexander BORODIN (OCN) - autotools usage +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +dist_salomeres_DATA = \ + :sat:{PYCMP}.png \ + :sat:{PYCMP}_small.png \ + Exec:sat:{PYCMP}.png \ + handshake.png \ + stop.png \ + ExecDelAll.png \ + ExecCircle.png \ + ExecPolyline.png \ + SalomeApp.xml + +# VSR: little trick to avoid putting if :sat:{PYCMP}Catalog.xml to the distribution archive +nodist_salomeres_SCRIPTS = :sat:{PYCMP}Catalog.xml diff --git a/data/templates/PythonComponent/resources/PYCMP.png b/data/templates/PythonComponent/resources/PYCMP.png new file mode 100755 index 0000000..2aa523d Binary files /dev/null and b/data/templates/PythonComponent/resources/PYCMP.png differ diff --git a/data/templates/PythonComponent/resources/PYCMPCatalog.xml b/data/templates/PythonComponent/resources/PYCMPCatalog.xml new file mode 100755 index 0000000..2266091 --- /dev/null +++ b/data/templates/PythonComponent/resources/PYCMPCatalog.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + :sat:{PYCMP} + :sat:{PYCMP} GUI + Data + CEA + 1.0 + + 1 + :sat:{PYCMP}.png + + + + diff --git a/data/templates/PythonComponent/resources/PYCMP_small.png b/data/templates/PythonComponent/resources/PYCMP_small.png new file mode 100755 index 0000000..474a537 Binary files /dev/null and b/data/templates/PythonComponent/resources/PYCMP_small.png differ diff --git a/data/templates/PythonComponent/resources/SalomeApp.xml b/data/templates/PythonComponent/resources/SalomeApp.xml new file mode 100755 index 0000000..5e01ffb --- /dev/null +++ b/data/templates/PythonComponent/resources/SalomeApp.xml @@ -0,0 +1,45 @@ + + + +
+ + + + + + +
+ +
+ + +
+ +
+ + +
+ +
diff --git a/data/templates/PythonComponent/resources/handshake.png b/data/templates/PythonComponent/resources/handshake.png new file mode 100755 index 0000000..e840a02 Binary files /dev/null and b/data/templates/PythonComponent/resources/handshake.png differ diff --git a/data/templates/PythonComponent/resources/stop.png b/data/templates/PythonComponent/resources/stop.png new file mode 100755 index 0000000..e896855 Binary files /dev/null and b/data/templates/PythonComponent/resources/stop.png differ diff --git a/data/templates/PythonComponent/src/CMakeLists.txt b/data/templates/PythonComponent/src/CMakeLists.txt new file mode 100644 index 0000000..b8ea2df --- /dev/null +++ b/data/templates/PythonComponent/src/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +ADD_SUBDIRECTORY(Controller) +ADD_SUBDIRECTORY(Dialog) +ADD_SUBDIRECTORY(Model) +ADD_SUBDIRECTORY(:sat:{PYCMP}) +ADD_SUBDIRECTORY(:sat:{PYCMP}GUI) +ADD_SUBDIRECTORY(StandAlone) +ADD_SUBDIRECTORY(View) diff --git a/data/templates/PythonComponent/src/Controller/CMakeLists.txt b/data/templates/PythonComponent/src/Controller/CMakeLists.txt new file mode 100644 index 0000000..c3c5fd7 --- /dev/null +++ b/data/templates/PythonComponent/src/Controller/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Python_SOURCES + Controller.py +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/data/templates/PythonComponent/src/Controller/Controller.py b/data/templates/PythonComponent/src/Controller/Controller.py new file mode 100755 index 0000000..b42de0c --- /dev/null +++ b/data/templates/PythonComponent/src/Controller/Controller.py @@ -0,0 +1,104 @@ +from Polyline import Polyline +from Circle import Circle + +class Controller() : + """Manages the Model instances""" + + def __init__( self, MainFrame ) : + """Constructor""" + + self._models = [] + self._mainFrame = MainFrame + self._nbPolylines = 0 + self._nbCircles = 0 + pass + + def getModels( self ) : + return self._models + + def getMainFrame( self ) : + return self._mainFrame + + def getNbPolylines( self ) : + return self._nbPolylines + + def setNbPolylines( self, n ) : + self._nbPolylines = n + pass + + def getNbCircles( self ) : + return self._nbCircles + + def setNbCircles( self, n ) : + self._nbCircles = n + pass + + def createPolyline( self, name, randomNumberOfPoints ) : + """Creates a Polyline object nammed name with randomNumberOfPoints points""" + + import random + + # Making randomNumberOfPoints random positionned points + points = [] + x = random.uniform( 0, randomNumberOfPoints ) + for i in range( randomNumberOfPoints ) : + x = random.uniform( x, x+randomNumberOfPoints ) + y = random.uniform( 0, x ) + point = x, y + points.append( point ) + pass + + myPolyline = Polyline( name, points, self ) + self._models.append( myPolyline ) + myPolyline.updateViews( mode = 'creation' ) + + self._nbPolylines +=1 + return myPolyline + + def createCircle( self, name, center, radius ) : + """Creates a Circle object nammed name with center and radius""" + + myCircle = Circle( name, center, radius, self ) + self._models.append( myCircle ) + myCircle.updateViews( mode = 'creation' ) + + self._nbCircles +=1 + return myCircle + + def showModel( self, model ) : + model.updateViews( mode = 'showing' ) + pass + + def editName( self, model, name ) : + model.setName( name ) + model.updateViews( mode = 'modification' ) + return model + + def editPoint( self, polyline, newPoint, pointRange ) : + polyline.editPoint( pointRange, newPoint ) + polyline.updateViews( mode = 'modification' ) + return polyline + + def editCenter( self, circle, center ) : + circle.setCenter( center ) + circle.updateViews( mode = 'modification' ) + return circle + + def editRadius( self, circle, radius ) : + circle.setRadius( radius ) + circle.updateViews( mode = 'modification' ) + return circle + + def removeModel( self, model ) : + model.updateViews( mode = 'supression' ) + index = self._models.index( model ) + del model + pass + + def saveListOfModels( self ) : + for model in self._models : + model.save() + pass + pass + +pass diff --git a/data/templates/PythonComponent/src/Dialog/CMakeLists.txt b/data/templates/PythonComponent/src/Dialog/CMakeLists.txt new file mode 100644 index 0000000..b4e985e --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Python_SOURCES + CreateCircleDialog.py + CreatePolylineDialog.py + DialogEdit.py + Dialog.py + EditCenterDialog.py + EditPointDialog.py + EditRadiusDialog.py + RenameDialog.py +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/data/templates/PythonComponent/src/Dialog/CreateCircleDialog.py b/data/templates/PythonComponent/src/Dialog/CreateCircleDialog.py new file mode 100755 index 0000000..d4e408a --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/CreateCircleDialog.py @@ -0,0 +1,70 @@ +from Dialog import * +from qtsalome import * + +class CreateCircleDialog( Dialog ) : + + def __init__( self, helpFile, controller, widgetDialogBox ) : + """Constructor""" + + # Initializing parent widget + Dialog.__init__( self, helpFile, controller, widgetDialogBox ) + + # Setting default name + nbCircles = controller.getNbCircles() + self.entryName.setText( "circle_" + str(nbCircles+1) ) + pass + + def addSpecialWidgets( self ) : + floatValidator = QDoubleValidator( self ) + + lxCenter = QLabel( "xCenter", self ) + self.v11.addWidget( lxCenter ) + lyCenter = QLabel( "yCenter", self ) + self.v11.addWidget( lyCenter ) + lRadius = QLabel( "Radius", self ) + self.v11.addWidget( lRadius ) + + self.entryxCenter = QLineEdit( self ) + self.entryxCenter.setValidator( floatValidator ) + self.entryxCenter.setText( "0" ) + self.v12.addWidget( self.entryxCenter ) + self.entryyCenter = QLineEdit( self ) + self.entryyCenter.setValidator( floatValidator ) + self.entryyCenter.setText( "0" ) + self.v12.addWidget( self.entryyCenter ) + self.entryRadius = QLineEdit( self ) + self.entryRadius.setValidator( floatValidator ) + self.entryRadius.setText( "10" ) + self.v12.addWidget( self.entryRadius) + pass + + def execApply( self ) : + name = self.name + center = float(self.xCenter), float(self.yCenter) + radius = float( self.radius ) + self.getController().createCircle( name, center, radius ) + self.reInitializeDialog() + return + + def retrieveUserEntries( self ) : + self.name = str( self.entryName.text() ) + self.xCenter = str( self.entryxCenter.text() ) + self.yCenter = str( self.entryyCenter.text() ) + self.radius = str( self.entryRadius.text() ) + pass + + def checkUserEntries( self ) : + if self.name == "" or self.xCenter == "" or self.yCenter == "" or self.radius == "" : + self.errMessage = 'All attributes must be filled' + return False + return True + + def reInitializeDialog( self ) : + nbCircles = self.getController().getNbCircles() + self.entryName.setText( "circle_" + str(nbCircles+1) ) + self.entryxCenter.setText( "0" ) + self.entryyCenter.setText( "0" ) + self.entryRadius.setText( "10" ) + pass + +pass diff --git a/data/templates/PythonComponent/src/Dialog/CreatePolylineDialog.py b/data/templates/PythonComponent/src/Dialog/CreatePolylineDialog.py new file mode 100755 index 0000000..f0a92a6 --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/CreatePolylineDialog.py @@ -0,0 +1,58 @@ +from Dialog import Dialog +from qtsalome import * + +class CreatePolylineDialog( Dialog ) : + + def __init__( self, helpFile, controller, widgetDialogBox ) : + """Constructor""" + + #Initializing parent widget + Dialog.__init__( self, helpFile, controller, widgetDialogBox ) + + #Setting default name + nbPolylines = controller.getNbPolylines() + self.entryName.setText( "polyline_" + str(nbPolylines+1) ) + pass + + def addSpecialWidgets( self ) : + + intValidator = QIntValidator( self ) + + lNbPoints = QLabel( "Number of points", self ) + self.v11.addWidget( lNbPoints ) + + self.entryNbPoints = QLineEdit( self ) + self.entryNbPoints.setValidator( intValidator ) + self.entryNbPoints.setText( "10" ) + self.v12.addWidget( self.entryNbPoints ) + pass + + def execApply( self ) : + name = self.name + nbPoints = int( self.nbPoints ) + self.getController().createPolyline( name, nbPoints ) + self.reInitializeDialog() + return + + + def retrieveUserEntries( self ) : + self.name = str( self.entryName.text() ) + self.nbPoints = str( self.entryNbPoints.text() ) + pass + + def checkUserEntries( self ) : + if self.name == "" or self.nbPoints == "" : + self.errMessage = 'All attributes must be filled' + return False + if int( self.nbPoints ) > 10 : + self.errMessage = 'The number of points must not exceed 10' + return False + return True + + def reInitializeDialog( self ) : + nbPolylines = self.getController().getNbPolylines() + self.entryName.setText( "polyline_" + str(nbPolylines+1) ) + self.entryNbPoints.setText( "10" ) + pass + +pass diff --git a/data/templates/PythonComponent/src/Dialog/Dialog.py b/data/templates/PythonComponent/src/Dialog/Dialog.py new file mode 100755 index 0000000..0feb345 --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/Dialog.py @@ -0,0 +1,104 @@ +from qtsalome import * + +class Dialog( QDialog ) : + + def __init__( self, helpFile, controller, widgetDialogBox ) : + """Constructor""" + + # Initializing parent widget + QDialog.__init__( self ) + + # Setting attributes + self.setObjectName( "Dialog" ) + self.setWindowTitle( "Dialog data" ) + self._helpFile = helpFile + self._controller = controller + self._widgetDialogBox = widgetDialogBox + + # Setting layouts + self.mainLayout = QVBoxLayout( self ) + self.h1 = QHBoxLayout( self ) + self.h2 = QHBoxLayout( self ) + self.mainLayout.addLayout( self.h1 ) + self.mainLayout.addLayout( self.h2 ) + self.v11 = QVBoxLayout( self) + self.v12 = QVBoxLayout( self ) + self.h1.addLayout( self.v11 ) + self.h1.addLayout( self.v12 ) + + # Filling layouts with standard widgets( common to all childre ) + self.fillStandardWidgets() + # Adding special widgets to layouts( special to each child ) + self.addSpecialWidgets() + + # Connecting widgets to slots + self.connectSlots() + pass + + def getController( self ) : + return self._controller + + def fillStandardWidgets( self ) : + + lName = QLabel( "Name", self ) + self.v11.addWidget( lName ) + + self.entryName = QLineEdit( self ) + self.v12.addWidget( self.entryName ) + + #Setting buttons + self.bApply = QPushButton( "Apply", self ) + self.h2.addWidget( self.bApply ) + self.bClose = QPushButton( "Close", self ) + self.h2.addWidget( self.bClose ) + self.bHelp = QPushButton( "Help", self ) + self.h2.addWidget( self.bHelp ) + pass + + def addSpecialWidgets( self ) : + print 'Virtual method' + pass + + def connectSlots( self ) : + self.bApply.clicked.connect(self.apply) + self.bHelp.clicked.connect(self.help) + self.bClose.clicked.connect(self.close) + pass + + def apply( self ) : + + self.retrieveUserEntries() + if not self.checkUserEntries() : + QMessageBox.warning( self, 'information faillure', self.errMessage ) + return + self.execApply() + return + + def retrieveUserEntries( self ) : + self.name = str( self.entryName.text() ) + pass + + def checkUserEntries( self ) : + if self.name == "" : + self.errMessage = 'All attributes must be filled' + return False + return True + + def execApply( self ) : + print 'Virtual method' + pass + + def reInitializeDialog( self ) : + print 'Virtual method' + pass + + def help( self ) : + import os + os.system( 'firefox ' + self._helpFile + '&' ) + pass + + def close( self ) : + self._widgetDialogBox.close() + pass + +pass diff --git a/data/templates/PythonComponent/src/Dialog/DialogEdit.py b/data/templates/PythonComponent/src/Dialog/DialogEdit.py new file mode 100755 index 0000000..0d2d884 --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/DialogEdit.py @@ -0,0 +1,92 @@ +from qtsalome import * + +class DialogEdit( QDialog ) : + + def __init__( self, helpFile, controller, widgetDialogBox ) : + """Constructor""" + + # Initializing parent widget + QDialog.__init__( self ) + + # Setting attributes + self.setObjectName( "Dialog" ) + self.setWindowTitle( "Dialog data" ) + self._helpFile = helpFile + self._controller = controller + self._widgetDialogBox = widgetDialogBox + + # Setting layouts + self.mainLayout = QVBoxLayout( self ) + self.h1 = QHBoxLayout( self ) + self.h2 = QHBoxLayout( self ) + self.mainLayout.addLayout( self.h1 ) + self.mainLayout.addLayout( self.h2 ) + self.v11 = QVBoxLayout( self) + self.v12 = QVBoxLayout( self ) + self.h1.addLayout( self.v11 ) + self.h1.addLayout( self.v12 ) + + # Filling layouts with standard widgets( common to all childre ) + self.fillStandardWidgets() + # Adding special widgets to layouts( special to each child ) + self.addSpecialWidgets() + + # Connecting widgets to slots + self.connectSlots() + pass + + def getController( self ) : + return self._controller + + def fillStandardWidgets( self ) : + + #Setting buttons + self.bOk = QPushButton( "OK", self ) + self.h2.addWidget( self.bOk ) + self.bCancel = QPushButton( "Cancel", self ) + self.h2.addWidget( self.bCancel ) + self.bHelp = QPushButton( "Help", self ) + self.h2.addWidget( self.bHelp ) + pass + + def addSpecialWidgets( self ) : + print 'Virtual method' + pass + + def connectSlots( self ) : + self.bOk.clicked.connect(self.apply) + self.bHelp.clicked.connect(self.help) + self.bCancel.clicked.connect(self.close) + pass + + def apply( self ) : + self.retrieveUserEntries() + if not self.checkUserEntries() : + QMessageBox.warning( self, 'information faillure', self.errMessage ) + return + self.execApply() + self.close() + return + + def retrieveUserEntries( self ) : + print 'Virtual method' + pass + + def checkUserEntries( self ) : + print 'Virtual method' + return True + + def execApply( self ) : + print 'Virtual method' + pass + + def help( self ) : + import os + os.system( 'firefox ' + self._helpFile + '&' ) + pass + + def close( self ) : + self._widgetDialogBox.close() + pass + +pass diff --git a/data/templates/PythonComponent/src/Dialog/EditCenterDialog.py b/data/templates/PythonComponent/src/Dialog/EditCenterDialog.py new file mode 100755 index 0000000..1e3a100 --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/EditCenterDialog.py @@ -0,0 +1,63 @@ +from DialogEdit import * +from qtsalome import * + +class EditCenterDialog( DialogEdit ) : + + def __init__( self, helpFile, controller, widgetDialogBox, model, oldCenter ) : + """Constructor""" + + # Initializing parent widget + DialogEdit.__init__( self, helpFile, controller, widgetDialogBox ) + + self._model = model + + # Reading oldX and oldY + oldX = "" + oldY = "" + i = 0 + while oldCenter[i] != ':' : + oldX += oldCenter[i] + i += 1 + pass + for j in range( i+1, len(oldCenter) ) : + oldY += oldCenter[j] + pass + self.entryX.setText( oldX ) + self.entryY.setText( oldY ) + pass + + def addSpecialWidgets( self ) : + floatValidator = QDoubleValidator( self ) + + lX = QLabel( "X", self ) + self.v11.addWidget( lX ) + lY = QLabel( "Y", self ) + self.v11.addWidget( lY ) + + self.entryX = QLineEdit( self ) + self.entryX.setValidator( floatValidator ) + self.v12.addWidget( self.entryX ) + self.entryY = QLineEdit( self ) + self.entryY.setValidator( floatValidator ) + self.v12.addWidget( self.entryY ) + pass + + def execApply( self ) : + newX = float( self.newX ) + newY = float( self.newY ) + newCenter = newX, newY + self.getController().editCenter( self._model, newCenter ) + return + + def retrieveUserEntries( self ) : + self.newX= str( self.entryX.text() ) + self.newY= str( self.entryY.text() ) + pass + + def checkUserEntries( self ) : + if self.newX == "" or self.newY == "" : + self.errMessage = 'All attributes must be filled' + return False + return True + +pass diff --git a/data/templates/PythonComponent/src/Dialog/EditPointDialog.py b/data/templates/PythonComponent/src/Dialog/EditPointDialog.py new file mode 100755 index 0000000..00702ad --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/EditPointDialog.py @@ -0,0 +1,66 @@ +from DialogEdit import * +from qtsalome import * + +class EditPointDialog( DialogEdit ) : + + def __init__( self, helpFile, controller, widgetDialogBox, model, oldPoint, pointRange ) : + """Constructor""" + + #Initializing parent widget + DialogEdit.__init__( self, helpFile, controller, widgetDialogBox ) + + self._model = model + + #Reading oldX and oldY + oldX = "" + oldY = "" + i = 0 + while oldPoint[i] != ':' : + oldX += oldPoint[i] + i += 1 + pass + for j in range( i+1, len(oldPoint) ) : + oldY += oldPoint[j] + pass + self.pointRange = pointRange + self.entryX.setText( oldX ) + self.entryY.setText( oldY ) + pass + + def addSpecialWidgets( self ) : + floatValidator = QDoubleValidator( self ) + + lX = QLabel( "X", self ) + self.v11.addWidget( lX ) + lY = QLabel( "Y", self ) + self.v11.addWidget( lY ) + + self.entryX = QLineEdit( self ) + self.entryX.setValidator( floatValidator ) + self.v12.addWidget( self.entryX ) + self.entryY = QLineEdit( self ) + self.entryY.setValidator( floatValidator ) + self.v12.addWidget( self.entryY ) + pass + + def execApply( self ) : + pointRange = self.pointRange + newX = float( self.newX ) + newY = float( self.newY ) + newPoint = newX, newY + self.getController().editPoint( self._model, newPoint, pointRange ) + return + + + def retrieveUserEntries( self ) : + self.newX= str( self.entryX.text() ) + self.newY= str( self.entryY.text() ) + pass + + def checkUserEntries( self ) : + if self.newX == "" or self.newY == "" : + self.errMessage = 'All attributes must be filled' + return False + return True + +pass diff --git a/data/templates/PythonComponent/src/Dialog/EditRadiusDialog.py b/data/templates/PythonComponent/src/Dialog/EditRadiusDialog.py new file mode 100755 index 0000000..69c648e --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/EditRadiusDialog.py @@ -0,0 +1,42 @@ +from DialogEdit import * +from qtsalome import * + +class EditRadiusDialog( DialogEdit ) : + + def __init__( self, helpFile, controller, widgetDialogBox, model, oldRadius ) : + """Constructor""" + + #Initializing parent widget + DialogEdit.__init__( self, helpFile, controller, widgetDialogBox ) + + self._model = model + self.entryRadius.setText( oldRadius ) + pass + + def addSpecialWidgets( self ) : + floatValidator = QDoubleValidator( self ) + + lRadius = QLabel( "Radius", self ) + self.v11.addWidget( lRadius ) + self.entryRadius = QLineEdit( self ) + self.entryRadius.setValidator( floatValidator ) + self.v12.addWidget( self.entryRadius ) + pass + + def execApply( self ) : + newRadius = self.newRadius + self.getController().editRadius( self._model, newRadius ) + return + + + def retrieveUserEntries( self ) : + self.newRadius = str( self.entryRadius.text() ) + pass + + def checkUserEntries( self ) : + if self.newRadius == "" : + self.errMessage = 'All attributes must be filled' + return False + return True + +pass diff --git a/data/templates/PythonComponent/src/Dialog/RenameDialog.py b/data/templates/PythonComponent/src/Dialog/RenameDialog.py new file mode 100755 index 0000000..dddcc2d --- /dev/null +++ b/data/templates/PythonComponent/src/Dialog/RenameDialog.py @@ -0,0 +1,38 @@ +from DialogEdit import * +from qtsalome import * + +class RenameDialog( DialogEdit ) : + + def __init__( self, helpFile, controller, widgetDialogBox, model, oldName ) : + """Constructor""" + + # Initializing parent widget + DialogEdit.__init__( self, helpFile, controller, widgetDialogBox ) + + self._model = model + self.entryName.setText( oldName ) + pass + + def addSpecialWidgets( self ) : + lName = QLabel( "Name", self ) + self.v11.addWidget( lName ) + self.entryName = QLineEdit( self ) + self.v12.addWidget( self.entryName ) + pass + + def execApply( self ) : + newName = self.newName + self.getController().editName( self._model, newName ) + return + + def retrieveUserEntries( self ) : + self.newName = str( self.entryName.text() ) + pass + + def checkUserEntries( self ) : + if self.newName == "" : + self.errMessage = 'All attributes must be filled' + return False + return True + +pass diff --git a/data/templates/PythonComponent/src/Model/CMakeLists.txt b/data/templates/PythonComponent/src/Model/CMakeLists.txt new file mode 100644 index 0000000..d955515 --- /dev/null +++ b/data/templates/PythonComponent/src/Model/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Python_SOURCES + Circle.py + Polyline.py + Model.py +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/data/templates/PythonComponent/src/Model/Circle.py b/data/templates/PythonComponent/src/Model/Circle.py new file mode 100755 index 0000000..bbd59e0 --- /dev/null +++ b/data/templates/PythonComponent/src/Model/Circle.py @@ -0,0 +1,58 @@ +from Model import * +from qtsalome import * + +__all__ = [ + "Circle", + ] + +class Circle( Model ): + + def __init__( self, name, center, radius, controller ): + """Constructor""" + + Model.__init__( self,controller ) + self._name = name + self._center = center + self._radius = radius + self.addTreeWidgetItem( self.getName(), controller ) + self.addGraphicScene( controller ) + pass + + def getCenter( self ): + return self._center[0], self._center[1] + + def setCenter( self, center ): + self._center = center + pass + + def getRadius( self ): + return self._radius + + def setRadius( self, radius ): + self._radius = radius + + def addTreeWidgetItem( self, name, controller ): + from CircleTreeWidgetItem import CircleTreeWidgetItem + from TreeWidgetItem import TreeWidgetItem + + myTreeWidgetItem = CircleTreeWidgetItem( name, controller, ["Show", "Rename", "Delete"] ) + newTreeWidgetItem = TreeWidgetItem( str(self.getCenter()[0]) + ':' + str(self.getCenter()[1]), controller, ["Edit"] ) + myTreeWidgetItem.addChild( newTreeWidgetItem ) + newTreeWidgetItem = TreeWidgetItem( str(self.getRadius()), controller, ["Edit"] ) + myTreeWidgetItem.addChild( newTreeWidgetItem ) + myTreeWidgetItem.setModel( self ) + self.getViews().append( myTreeWidgetItem ) + return myTreeWidgetItem + + def addGraphicScene( self, controller ) : + from CircleGraphicsScene import CircleGraphicsScene + + myGraphicsScene = CircleGraphicsScene( controller ) + myGraphicsScene.setModel( self ) + self.getViews().append( myGraphicsScene ) + return myGraphicsScene + + def save( self ): + pass + +pass diff --git a/data/templates/PythonComponent/src/Model/Model.py b/data/templates/PythonComponent/src/Model/Model.py new file mode 100755 index 0000000..7b5d4e9 --- /dev/null +++ b/data/templates/PythonComponent/src/Model/Model.py @@ -0,0 +1,34 @@ +from View import * + +class Model: + + def __init__( self, controller ): + """Constructor""" + + self._name = None + self._views = [] + pass + + def getName( self ): + return self._name + + def setName( self, name ): + self._name = name + pass + + def getViews( self ) : + return self._views + + def addView( self ) : + myView = View() + self._views.append( myView ) + return myView + + def updateViews( self, mode ) : + for view in self._views : view.update( mode ) + + def save( self ) : + print 'Virtual method' + pass + +pass diff --git a/data/templates/PythonComponent/src/Model/Polyline.py b/data/templates/PythonComponent/src/Model/Polyline.py new file mode 100755 index 0000000..9a6bd49 --- /dev/null +++ b/data/templates/PythonComponent/src/Model/Polyline.py @@ -0,0 +1,54 @@ +from Model import * +from qtsalome import * + +class Polyline( Model ): + + def __init__( self, name, points, controller ): + """Constructor""" + + Model.__init__( self, controller ) + self._name = name + self._points = points + self.addTreeWidgetItem( self.getName(), controller ) + self.addGraphicScene( controller ) + pass + + def getPoints( self ): + return self._points + + def setPoints( self, points ): + self._points = points + pass + + def editPoint( self, pointRange, newPoint ) : + self._points[ pointRange ] = newPoint + pass + + def addTreeWidgetItem( self, name, controller ): + from PolyTreeWidgetItem import PolyTreeWidgetItem + from TreeWidgetItem import TreeWidgetItem + + myTreeWidgetItem = PolyTreeWidgetItem( name, controller, ["Show", "Rename", "Delete"] ) + # Adding list of points + for point in self.getPoints() : + x = point[0] + y = point[1] + newTreeWidgetItem = TreeWidgetItem( str(x) + ":" + str(y), controller, ["Edit"] ) + myTreeWidgetItem.addChild( newTreeWidgetItem ) + pass + myTreeWidgetItem.setModel( self ) + self.getViews().append( myTreeWidgetItem ) + return myTreeWidgetItem + + def addGraphicScene( self, controller ) : + from PolyGraphicsScene import PolyGraphicsScene + + myGraphicsScene = PolyGraphicsScene( controller ) + myGraphicsScene.setModel( self ) + self.getViews().append( myGraphicsScene ) + return myGraphicsScene + + def save( self ): + pass + +pass diff --git a/data/templates/PythonComponent/src/PYCMP/CMakeLists.txt b/data/templates/PythonComponent/src/PYCMP/CMakeLists.txt new file mode 100644 index 0000000..8ef191a --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMP/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Python_SOURCES + :sat:{PYCMP}.py + :sat:{PYCMP}_utils.py +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/data/templates/PythonComponent/src/PYCMP/PYCMP.py b/data/templates/PythonComponent/src/PYCMP/PYCMP.py new file mode 100755 index 0000000..51afc58 --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMP/PYCMP.py @@ -0,0 +1,101 @@ +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# --- +# File : :sat:{PYCMP}.py +# Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +# --- +# +import :sat:{PYCMP}_ORB__POA +import SALOME_ComponentPy +import SALOME_DriverPy + +from :sat:{PYCMP}_utils import * + +class :sat:{PYCMP}(:sat:{PYCMP}_ORB__POA.:sat:{PYCMP}_Gen, + SALOME_ComponentPy.SALOME_ComponentPy_i, + SALOME_DriverPy.SALOME_DriverPy_i): + """ + Construct an instance of :sat:{PYCMP} module engine. + The class :sat:{PYCMP} implements CORBA interface :sat:{PYCMP}_Gen (see :sat:{PYCMP}_Gen.idl). + It is inherited from the classes SALOME_ComponentPy_i (implementation of + Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i + (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine). + """ + def __init__ ( self, orb, poa, contID, containerName, instanceName, + interfaceName ): + SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa, + contID, containerName, instanceName, interfaceName, 0) + SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName) + # + self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb ) + # + pass + + """ + Touch the component + """ + def touch(self, name): + message = "Touch: %s!" % name + return message + + """ + Create object. + """ + def createObject( self, study, name ): + builder = study.NewBuilder() + father = findOrCreateComponent( study ) + object = builder.NewObject( father ) + attr = builder.FindOrCreateAttribute( object, "AttributeName" ) + attr.SetValue( name ) + attr = builder.FindOrCreateAttribute( object, "AttributeLocalID" ) + attr.SetValue( objectID() ) + pass + + """ + Dump module data to the Python script. + """ + def DumpPython( self, study, isPublished ): + abuffer = [] + abuffer.append( "def RebuildData( theStudy ):" ) + names = [] + father = study.FindComponent( moduleName() ) + if father: + iter = study.NewChildIterator( father ) + while iter.More(): + name = iter.Value().GetName() + if name: names.append( name ) + iter.Next() + pass + pass + if names: + abuffer += [ " from batchmode_salome import lcc" ] + abuffer += [ " import :sat:{PYCMP}_ORB" ] + abuffer += [ " " ] + abuffer += [ " myCompo = lcc.FindOrLoadComponent( 'FactoryServerPy', '%s' )" % moduleName() ] + abuffer += [ " " ] + abuffer += [ " myCompo.createObject( theStudy, '%s' )" % name for name in names ] + pass + abuffer += [ " " ] + abuffer.append( " pass" ) + abuffer.append( "\0" ) + return ("\n".join( abuffer ), 1) diff --git a/data/templates/PythonComponent/src/PYCMP/PYCMP_utils.py b/data/templates/PythonComponent/src/PYCMP/PYCMP_utils.py new file mode 100755 index 0000000..56e1557 --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMP/PYCMP_utils.py @@ -0,0 +1,197 @@ +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# --- +# File : :sat:{PYCMP}_utils.py +# Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +# --- +# +__all__ = [ + "moduleID", + "objectID", + "unknownID", + "moduleName", + "modulePixmap", + "verbose", + "getORB", + "getNS", + "getLCC", + "getStudyManager", + "getEngine", + "getEngineIOR", + "findOrCreateComponent", + "getObjectID", + ] + +from omniORB import CORBA +from SALOME_NamingServicePy import SALOME_NamingServicePy_i +from LifeCycleCORBA import LifeCycleCORBA +import SALOMEDS +import SALOMEDS_Attributes_idl +import :sat:{PYCMP}_ORB + +### +# Get :sat:{PYCMP} module's ID +### +def moduleID(): + MODULE_ID = 1000 + return MODULE_ID + +### +# Get :sat:{PYCMP} object's ID +### +def objectID(): + OBJECT_ID = 1010 + return OBJECT_ID + +### +# Get unknown ID +### +def unknownID(): + FOREIGN_ID = -1 + return FOREIGN_ID + +### +# Get :sat:{PYCMP} module's name +### +def moduleName(): + return ":sat:{PYCMP}" + +### +# Get module's pixmap name +### +def modulePixmap(): + return ":sat:{PYCMP}_small.png" + +### +# Get verbose level +### +__verbose__ = None +def verbose(): + global __verbose__ + if __verbose__ is None: + try: + __verbose__ = int( os.getenv( 'SALOME_VERBOSE', 0 ) ) + except: + __verbose__ = 0 + pass + pass + return __verbose__ + +### +# Get ORB reference +### +__orb__ = None +def getORB(): + global __orb__ + if __orb__ is None: + __orb__ = CORBA.ORB_init( [''], CORBA.ORB_ID ) + pass + return __orb__ + +### +# Get naming service instance +### +__naming_service__ = None +def getNS(): + global __naming_service__ + if __naming_service__ is None: + __naming_service__ = SALOME_NamingServicePy_i( getORB() ) + pass + return __naming_service__ + +## +# Get life cycle CORBA instance +## +__lcc__ = None +def getLCC(): + global __lcc__ + if __lcc__ is None: + __lcc__ = LifeCycleCORBA( getORB() ) + pass + return __lcc__ + +## +# Get study manager +### +__study_manager__ = None +def getStudyManager(): + global __study_manager__ + if __study_manager__ is None: + obj = getNS().Resolve( '/myStudyManager' ) + __study_manager__ = obj._narrow( SALOMEDS.StudyManager ) + pass + return __study_manager__ + +### +# Get :sat:{PYCMP} engine +### +__engine__ = None +def getEngine(): + global __engine__ + if __engine__ is None: + __engine__ = getLCC().FindOrLoadComponent( "FactoryServerPy", moduleName() ) + pass + return __engine__ + +### +# Get :sat:{PYCMP} engine IOR +### +def getEngineIOR(): + IOR = "" + if getORB() and getEngine(): + IOR = getORB().object_to_string( getEngine() ) + pass + return IOR + +### +# Find or create :sat:{PYCMP} component object in a study +### +def findOrCreateComponent( study ): + father = study.FindComponent( moduleName() ) + if father is None: + builder = study.NewBuilder() + father = builder.NewComponent( moduleName() ) + attr = builder.FindOrCreateAttribute( father, "AttributeName" ) + attr.SetValue( moduleName() ) + attr = builder.FindOrCreateAttribute( father, "AttributePixMap" ) + attr.SetPixMap( modulePixmap() ) + attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" ) + attr.SetValue( moduleID() ) + try: + builder.DefineComponentInstance( father, getEngine() ) + pass + except: + pass + pass + return father + +### +# Get object's ID +### +def getObjectID( study, entry ): + ID = unknownID() + if study and entry: + sobj = study.FindObjectID( entry ) + if sobj is not None: + test, anAttr = sobj.FindAttribute( "AttributeLocalID" ) + if test: ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value() + pass + pass + return ID diff --git a/data/templates/PythonComponent/src/PYCMPGUI/CMakeLists.txt b/data/templates/PythonComponent/src/PYCMPGUI/CMakeLists.txt new file mode 100644 index 0000000..dea3702 --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMPGUI/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +INCLUDE(UseQtExt) + +SET(Python_SOURCES + :sat:{PYCMP}Desktop.py + :sat:{PYCMP}GUI.py +) + +SET(qt_RESOURCES + :sat:{PYCMP}_msg_en.ts + :sat:{PYCMP}_msg_fr.ts + :sat:{PYCMP}_icons.ts +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) + +QT_INSTALL_TS_RESOURCES("${qt_RESOURCES}" "${SALOME_INSTALL_RES}") diff --git a/data/templates/PythonComponent/src/PYCMPGUI/PYCMPDesktop.py b/data/templates/PythonComponent/src/PYCMPGUI/PYCMPDesktop.py new file mode 100755 index 0000000..dcc57f7 --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMPGUI/PYCMPDesktop.py @@ -0,0 +1,101 @@ +from qtsalome import * +from TreeWidget import TreeWidget +from GraphicsView import GraphicsView +from GraphicsScene import GraphicsScene + +class :sat:{PYCMP}Desktop( QMainWindow ) : + + def __init__( self, sgPyQt, sg ) : + """Constructor""" + + QMainWindow.__init__( self ) + self._controller = None + self._sgPyQt = sgPyQt + self._sg = sg + self._sgDesktop = self._sgPyQt.getDesktop() + + # Menus IDs + self._curveMenuID = 1000 + self._advancedMenuID = 1001 + + # Actions IDs + self._polylineID = 1002 + self._circleID = 1003 + self._deleteAllID = 1004 + + self.createTreeView() + self.createGraphicsView() + pass + + def createTreeView( self ) : + self._globalTree= TreeWidget( self ) + self._globalTree.setHeaderLabel ( "Tree view" ) + self._dockGlobalTree = QDockWidget( self._sgDesktop ) + self._dockGlobalTree.setFeatures( QDockWidget.NoDockWidgetFeatures ) + self._dockGlobalTree.setAllowedAreas( Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea ) + self._dockGlobalTree.setWidget( self._globalTree ) + self._sgDesktop.addDockWidget( Qt.LeftDockWidgetArea, self._dockGlobalTree ) + pass + + def createGraphicsView( self ) : + scene = GraphicsScene( self._controller ) + self._globalGraphicsView = GraphicsView( scene ) + self._globalGraphicsViewID = self._sgPyQt.createView( "ViewCurve", self._globalGraphicsView ) + pass + + def createActions( self ) : + self.createPolylineAction = self._sgPyQt.createAction( self._polylineID, "Polyline", "Create Polyline", "Show Polyline dialog box", "ExecPolyline.png" ) + self.createCircleAction = self._sgPyQt.createAction( self._circleID, "Circle", "Create Circle", "Show Circle dialog box", "ExecCircle.png" ) + self.deleteAllAction = self._sgPyQt.createAction( self._deleteAllID, "Delete all", "Delete all", "Delete all objects", "ExecDelAll.png" ) + pass + + def createMenus( self ) : + curveMenu = self._sgPyQt.createMenu( " Curve", -1, self._curveMenuID, self._sgPyQt.defaultMenuGroup() ) + advancedMenu = self._sgPyQt.createMenu( " Advanced", -1, self._advancedMenuID, self._sgPyQt.defaultMenuGroup() ) + + self._sgPyQt.createMenu( self.createPolylineAction, curveMenu ) + self._sgPyQt.createMenu( self.createCircleAction, curveMenu ) + self._sgPyQt.createMenu( self.deleteAllAction, advancedMenu ) + pass + + def createToolBars( self ) : + createPolylineTB = self._sgPyQt.createTool("New polyline") + createCircleTB = self._sgPyQt.createTool("New circle") + deleteAllTB = self._sgPyQt.createTool("Delete all") + + self._sgPyQt.createTool( self.createPolylineAction, createPolylineTB ) + self._sgPyQt.createTool( self.createCircleAction, createCircleTB ) + self._sgPyQt.createTool( self.deleteAllAction, deleteAllTB ) + pass + + def createPopups( self ) : + pass + + def getController( self ) : + return self._controller + + def setController( self, controller ) : + self._controller = controller + pass + + def getGlobalTree( self ) : + return self._globalTree + + def getGlobalGraphicsView( self ) : + return self._globalGraphicsView + + def getGlobalGraphicsViewID( self ) : + return self._globalGraphicsViewID + + def getDockGlobalTree( self ) : + return self._dockGlobalTree + + def updateGlobalGraphicsView( self, scene ) : + self._globalGraphicsView.setScene( scene ) + if scene is None : return + #Resizing the globalGraphicView + sceneRect = scene.getRect() + self._globalGraphicsView.fitInView ( sceneRect, Qt.KeepAspectRatio ) + pass + +pass diff --git a/data/templates/PythonComponent/src/PYCMPGUI/PYCMPGUI.py b/data/templates/PythonComponent/src/PYCMPGUI/PYCMPGUI.py new file mode 100755 index 0000000..71a4e0f --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMPGUI/PYCMPGUI.py @@ -0,0 +1,256 @@ +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# --- +# File : :sat:{PYCMP}GUI.py +# Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +# --- +# +import traceback +import string +import os +import sys +from qtsalome import * + +#from :sat:{PYCMP}_utils import * + +import salome +from Controller import Controller +from TreeWidget import TreeWidget +from :sat:{PYCMP}Desktop import :sat:{PYCMP}Desktop + +# Get SALOME PyQt interface +import SalomePyQt +import libSALOME_Swig + +######################################################## +# Global variables +######################################################## + +sgPyQt = SalomePyQt.SalomePyQt() +sg = libSALOME_Swig.SALOMEGUI_Swig() +sgDesktop = sgPyQt.getDesktop() +widgetDialogBox = None + +objectsManager = Controller( None ) +moduleDesktop = {} +currentDesktop = None + +CURVE_MENU_ID = 1000 +ADVANCED_MENU_ID = 1001 +POLYLINE_ID = 1002 +CIRCLE_ID = 1003 +DEL_ALL_ID = 1004 + +######################################################## +# Internal methods +######################################################## + +def getStudyId(): + """This method returns the active study ID""" + return sgPyQt.getStudyId() + +def getStudy(): + """This method returns the active study""" + + studyId = _getStudyId() + study = getStudyManager().GetStudyByID( studyId ) + return study + +def getDesktop(): + """This method returns the current :sat:{PYCMP} desktop""" + + global currentDesktop + return currentDesktop + +def setDesktop( studyID ): + """This method sets and returns :sat:{PYCMP} desktop""" + + global moduleDesktop, currentDesktop, objectsManager + + if not studyID in moduleDesktop: + moduleDesktop[studyID] = :sat:{PYCMP}Desktop( sgPyQt, sg ) + objectsManager = Controller( moduleDesktop[studyID] ) + moduleDesktop[studyID].setController( objectsManager ) + pass + currentDesktop = moduleDesktop[studyID] + return currentDesktop + +def incObjToMap( m, id ): + """This method incrementes the object counter in the map""" + + if id not in m: m[id] = 0 + m[id] += 1 + pass + +def getSelection(): + """This method analyses selection""" + + selcount = sg.SelectedCount() + seltypes = {} + for i in range( selcount ): + incObjToMap( seltypes, getObjectID( getStudy(), sg.getSelected( i ) ) ) + pass + return selcount, seltypes + +################################################ +# Callback functions +################################################ + +def initialize(): + """This method is called when module is initialized. It performs initialization actions""" + + setDesktop( getStudyId() ) + pass + +def windows(): + """This method is called when module is initialized. It returns a map of popup windows to be used by the module""" + + wm = {} + wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea + wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea + return wm + +def views(): + """This method is called when module is initialized. It returns a list of 2D/3D views to be used by the module""" + return [] + +def createPreferences(): + """This method is called when module is initialized. It exports module preferences""" + pass + +def activate(): + """This method is called when module is initialized. It returns True if activating is successfull, False otherwise""" + + global moduleDesktop, sgPyQt, widgetDialogBox + + widgetDialogBox = QDockWidget( sgDesktop ) + moduleDesktop[getStudyId()].createActions() + moduleDesktop[getStudyId()].createMenus() + moduleDesktop[getStudyId()].createToolBars() + moduleDesktop[getStudyId()].createPopups() + moduleDesktop[getStudyId()].getDockGlobalTree().show() + moduleDesktop[getStudyId()].getGlobalGraphicsView().show() + sgPyQt.activateView( moduleDesktop[getStudyId()].getGlobalGraphicsViewID() ) + return True + +def viewTryClose( wid ): + sgPyQt.setViewClosable(wid, True) + pass + +def deactivate(): + """This method is called when module is deactivated""" + + global moduleDesktop, widgetDialogBox + + widgetDialogBox.close() + moduleDesktop[getStudyId()].getDockGlobalTree().hide() + moduleDesktop[getStudyId()].updateGlobalGraphicsView( None ) + moduleDesktop[getStudyId()].getGlobalGraphicsView().hide() + pass + +def activeStudyChanged( studyID ): + """This method is called when active study is changed""" + + setDesktop( getStudyId() ) + pass + +def createPopupMenu( popup, context ): + """This method is called when popup menu is invocked""" + pass + +def OnGUIEvent( commandID ): + """This method is called when a GUI action is activated""" + + if commandID in dict_command: + dict_command[commandID]() + pass + pass + +def preferenceChanged( section, setting ): + """This method is called when module's preferences are changed""" + pass + +def activeViewChanged( viewID ): + """This method is called when active view is changed""" + pass + +def viewCloned( viewID ): + """This method is called when active view is cloned""" + pass + +def viewClosed( viewID ): + """This method is called when active view viewClosed""" + pass + +def engineIOR(): + """This method is called when study is opened. It returns engine IOR""" + return getEngineIOR() + + +################################################ +# GUI actions implementation +################################################ + +def showCreatePolylineDialog() : + from CreatePolylineDialog import CreatePolylineDialog + + global widgetDialogBox + widgetDialogBox = QDockWidget( sgDesktop ) + myDialog = CreatePolylineDialog( "www.cea.fr", objectsManager, widgetDialogBox ) + widgetDialogBox.setWidget( myDialog ) + widgetDialogBox.setWindowTitle( "Polyline definition" ) + sgDesktop.addDockWidget(Qt.LeftDockWidgetArea, widgetDialogBox) + pass + +def showCreateCircleDialog() : + from CreateCircleDialog import CreateCircleDialog + + global widgetDialogBox + widgetDialogBox = QDockWidget( sgDesktop ) + myDialog = CreateCircleDialog( "www.cea.fr", objectsManager, widgetDialogBox ) + widgetDialogBox.setWidget( myDialog ) + widgetDialogBox.setWindowTitle( "Circle definition" ) + sgDesktop.addDockWidget(Qt.LeftDockWidgetArea, widgetDialogBox) + pass + +def deleteAll() : + models = moduleDesktop[getStudyId()].getController().getModels() + if len( models ) == 0 : return + answer = QMessageBox.question( moduleDesktop[getStudyId()], 'Confirmation', 'Do you really want to delete all the existing objects ?' , QMessageBox.Yes | QMessageBox.No ) + if answer == QMessageBox.Yes : + for model in models : + moduleDesktop[getStudyId()].getController().removeModel( model ) + pass + pass + pass + +######################################################## +# Commands dictionary +######################################################## + +dict_command = { POLYLINE_ID : showCreatePolylineDialog, + CIRCLE_ID : showCreateCircleDialog, + DEL_ALL_ID : deleteAll + } + +######################################################## diff --git a/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_icons.ts b/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_icons.ts new file mode 100755 index 0000000..f6bef70 --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_icons.ts @@ -0,0 +1,37 @@ + + + + + @default + + ICO_HANDSHAKE + handshake.png + + + ICO_STOP + stop.png + + + diff --git a/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_msg_en.ts b/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_msg_en.ts new file mode 100755 index 0000000..2ee4f7f --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_msg_en.ts @@ -0,0 +1,11 @@ + + + + + @default + + + + + + diff --git a/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_msg_fr.ts b/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_msg_fr.ts new file mode 100755 index 0000000..1e4dea3 --- /dev/null +++ b/data/templates/PythonComponent/src/PYCMPGUI/PYCMP_msg_fr.ts @@ -0,0 +1,11 @@ + + + + + @default + + + + + + diff --git a/data/templates/PythonComponent/src/StandAlone/CMakeLists.txt b/data/templates/PythonComponent/src/StandAlone/CMakeLists.txt new file mode 100644 index 0000000..1ddc9db --- /dev/null +++ b/data/templates/PythonComponent/src/StandAlone/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Python_SOURCES + Desktop.py + Standalone:sat:{PYCMP}GUI.py +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/data/templates/PythonComponent/src/StandAlone/Desktop.py b/data/templates/PythonComponent/src/StandAlone/Desktop.py new file mode 100755 index 0000000..69256a5 --- /dev/null +++ b/data/templates/PythonComponent/src/StandAlone/Desktop.py @@ -0,0 +1,126 @@ +from PyQt5.QtCore import * +from PyQt5.QtGui import * +from PyQt5.QtWidgets import * + +from TreeWidget import TreeWidget +from GraphicsView import GraphicsView +from GraphicsScene import GraphicsScene + +class Desktop( QMainWindow ) : + + def __init__( self ) : + """Constructor""" + + QMainWindow.__init__( self ) + self._controller = None + + # Creating a dockWidget which will contain globalTree + self._globalTree= TreeWidget( self ) + self._globalTree.setHeaderLabel ( "Object browser" ) + dockGlobalTree = QDockWidget( "Tree view", self ) + dockGlobalTree.setAllowedAreas( Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea ) + dockGlobalTree.setWidget( self._globalTree ) + self.addDockWidget( Qt.LeftDockWidgetArea, dockGlobalTree ) + + # Creating a central widget which contains the globalGraphicsView + self._dockGlobalView = QDockWidget( "Graphics view", self ) + scene = GraphicsScene( self._controller ) + self._globalGraphicsView = GraphicsView( scene ) + self._dockGlobalView.setWidget( self._globalGraphicsView ) + self._globalGraphicsView.show() + self.setCentralWidget( self._dockGlobalView ) + + # Creating menus and toolbars + self.createMenus() + self.createToolBars() + pass + + def getController( self ) : + return self._controller + + def setController( self, controller ) : + self._controller = controller + pass + + def getGlobalTree( self ) : + return self._globalTree + + def createMenus( self ) : + # Creating menus + curveMenu = self.menuBar().addMenu( "Curve" ) + toolsMenu = self.menuBar().addMenu( "Tools" ) + # Adding actions + createPolylineAction = QAction( "Polyline", self ) + createCircleAction = QAction( "Circle", self ) + curveMenu.addAction( createPolylineAction ) + curveMenu.addAction( createCircleAction ) + + deleteAllAction = QAction( "Delete all", self ) + toolsMenu.addAction( deleteAllAction ) + # Connecting slots + createPolylineAction.triggered.connect(self.showCreatePolylineDialog) + createCircleAction.triggered.connect(self.showCreateCircleDialog) + deleteAllAction.triggered.connect(self.deleteAll) + pass + + def createToolBars( self ) : + # Creating toolBars + createPolylineTB = self.addToolBar( "New polyline") + createCircleTB = self.addToolBar( "New circle") + createPolylineAction = QAction( "Polyline", self ) + createCircleAction = QAction( "Circle", self ) + # Adding actions + createPolylineTB.addAction( createPolylineAction ) + createCircleTB.addAction( createCircleAction ) + # Connecting slots + createPolylineAction.triggered.connect(self.showCreatePolylineDialog) + createCircleAction.triggered.connect(self.showCreateCircleDialog) + pass + + def showCreatePolylineDialog( self ) : + from CreatePolylineDialog import CreatePolylineDialog + + widgetDialogBox = QDockWidget( "myDockWidget", self ) + myDialog = CreatePolylineDialog( "www.google.fr", self._controller, widgetDialogBox ) + widgetDialogBox.setAllowedAreas( Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea ) + widgetDialogBox.setWidget( myDialog ) + widgetDialogBox.setWindowTitle( "Polyline definition" ) + self.addDockWidget( Qt.LeftDockWidgetArea, widgetDialogBox ) + pass + + def showCreateCircleDialog( self ) : + from CreateCircleDialog import CreateCircleDialog + + widgetDialogBox = QDockWidget( "myDockWidget", self ) + myDialog = CreateCircleDialog( "www.cea.fr", self._controller, widgetDialogBox ) + widgetDialogBox.setAllowedAreas( Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea ) + widgetDialogBox.setWidget( myDialog ) + widgetDialogBox.setWindowTitle( "Polyline definition" ) + self.addDockWidget( Qt.LeftDockWidgetArea, widgetDialogBox ) + pass + + def deleteAll( self ) : + models = self.getController().getModels() + if len( models ) == 0 : return + answer = QMessageBox.question( self, 'Confirmation', 'Do you really want to delete all the existing objects ?' , QMessageBox.Yes | QMessageBox.No ) + if answer == QMessageBox.Yes : + for model in models : + self.getController().removeModel( model ) + pass + pass + pass + + def updateGlobalGraphicsView( self, scene ) : + self._globalGraphicsView.setScene( scene ) + if scene is None : + self._dockGlobalView.setWindowTitle( "Graphics view" ) + return + self._dockGlobalView.setWindowTitle( "Graphics view : showing " + scene.getModel().getName() ) + #Resizing the globalGraphicView + sceneRect = scene.getRect() + topLeft = sceneRect.topLeft() + viewRect = QRectF( topLeft.x(), topLeft.y(), 2*sceneRect.width(), 2*sceneRect.height() ) + self._globalGraphicsView.fitInView ( viewRect, Qt.IgnoreAspectRatio ) + pass + +pass diff --git a/data/templates/PythonComponent/src/StandAlone/StandalonePYCMPGUI.py b/data/templates/PythonComponent/src/StandAlone/StandalonePYCMPGUI.py new file mode 100755 index 0000000..45be4e9 --- /dev/null +++ b/data/templates/PythonComponent/src/StandAlone/StandalonePYCMPGUI.py @@ -0,0 +1,21 @@ +import sys + +from PyQt5.QtCore import * +from PyQt5.QtGui import * +from PyQt5.QtWidgets import * + +from Controller import Controller +from Desktop import Desktop + +def main( args ) : + Appli = QApplication( args ) + MainFrame = Desktop() + myController = Controller( MainFrame ) + MainFrame.setController( myController ) + MainFrame.show() + Appli.exec_() + +if __name__ == "__main__" : + main( sys.argv ) + pass + diff --git a/data/templates/PythonComponent/src/View/CMakeLists.txt b/data/templates/PythonComponent/src/View/CMakeLists.txt new file mode 100644 index 0000000..d0970c5 --- /dev/null +++ b/data/templates/PythonComponent/src/View/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (C) 2018-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +SET(Python_SOURCES + CircleGraphicsScene.py + CircleTreeWidgetItem.py + GraphicsRectItem.py + GraphicsScene.py + GraphicsView.py + PolyGraphicsScene.py + PolyTreeWidgetItem.py + TreeWidgetItem.py + TreeWidget.py + View.py + Menu.py +) + +SALOME_INSTALL_SCRIPTS("${Python_SOURCES}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/data/templates/PythonComponent/src/View/CircleGraphicsScene.py b/data/templates/PythonComponent/src/View/CircleGraphicsScene.py new file mode 100755 index 0000000..65a0c21 --- /dev/null +++ b/data/templates/PythonComponent/src/View/CircleGraphicsScene.py @@ -0,0 +1,30 @@ +from GraphicsScene import GraphicsScene +from qtsalome import * +from GraphicsRectItem import GraphicsRectItem + +class CircleGraphicsScene( GraphicsScene ) : + + def __init__( self, controller ) : + GraphicsScene.__init__( self, controller ) + pass + + def draw( self ) : + + import math + + center = self._model.getCenter() + radius = float( self._model.getRadius() ) + xCenter = float( center[0] ) + yCenter = float( center[1] ) + + #Drawing the center as a small rectangle + centerItem = GraphicsRectItem( xCenter-0.1, yCenter-0.1, 0.2, 0.2, None ) + self.addItem( centerItem ) + #Drawing the circle + rect = QRectF( xCenter-radius, yCenter-radius, 2*radius, 2*radius ) + circleItem = QGraphicsEllipseItem() + circleItem.setRect( rect ) + self.addItem( circleItem ) + pass + +pass diff --git a/data/templates/PythonComponent/src/View/CircleTreeWidgetItem.py b/data/templates/PythonComponent/src/View/CircleTreeWidgetItem.py new file mode 100755 index 0000000..da53ff3 --- /dev/null +++ b/data/templates/PythonComponent/src/View/CircleTreeWidgetItem.py @@ -0,0 +1,27 @@ +from View import * +from TreeWidgetItem import TreeWidgetItem +from qtsalome import * + +class CircleTreeWidgetItem( TreeWidgetItem ) : + + def __init__( self, name, controller, actionsList ) : + """Constructor""" + + TreeWidgetItem.__init__( self, name, controller, actionsList ) + pass + + def editInGlobalTree( self, treeWidgetItem ) : + name = self.getModel().getName() + treeWidgetItem.setText( 0 , name ) + center = self._model.getCenter() + xCenter = center[0] + yCenter = center[1] + relatedItem = treeWidgetItem.child( 0 ) + relatedItem.setText( 0 , str(xCenter) + ":" + str(yCenter) ) + + radius = self._model.getRadius() + relatedItem = treeWidgetItem.child( 1 ) + relatedItem.setText( 0 , str(radius) ) + pass + +pass diff --git a/data/templates/PythonComponent/src/View/GraphicsRectItem.py b/data/templates/PythonComponent/src/View/GraphicsRectItem.py new file mode 100755 index 0000000..9d89516 --- /dev/null +++ b/data/templates/PythonComponent/src/View/GraphicsRectItem.py @@ -0,0 +1,15 @@ +from qtsalome import * + +class GraphicsRectItem( QGraphicsRectItem ) : + + def __init__( self, x, y, w, h, index ) : + QGraphicsRectItem.__init__( self, x, y, w, h ) + self._index = index + self.setFlag( self.ItemIsMovable, True ) + self.setFlag( self.ItemIsSelectable, True ) + pass + + def getIndex( self ) : + return self._index + +pass diff --git a/data/templates/PythonComponent/src/View/GraphicsScene.py b/data/templates/PythonComponent/src/View/GraphicsScene.py new file mode 100755 index 0000000..ca307f4 --- /dev/null +++ b/data/templates/PythonComponent/src/View/GraphicsScene.py @@ -0,0 +1,67 @@ +from View import * +from qtsalome import * + +class GraphicsScene( View, QGraphicsScene ) : + + def __init__( self, controller ) : + """Constructor""" + + View.__init__( self, controller ) + QGraphicsScene.__init__( self ) + pass + + def getRect( self ) : + rect = QRectF( 0, 0, self.width(), self.height() ) + return rect + + def editPoint( self, oldPoint, newPoint ) : + polyline = self.getModel() + self.getController().editPoint( polyline, oldPoint, newPoint ) + pass + + def editCenter( self, center ) : + circle = self.getModel() + self.getController().editCenter( circle, center ) + pass + + def editRadius( self, radius ) : + circle = self.getModel() + self.getController().editRadius( circle, radius ) + pass + + def update( self, mode ) : + if mode == 'creation' : + self.showInGlobalGraphicsView() + pass + elif mode == "showing" : + self.showInGlobalGraphicsView() + elif mode == 'modification' : + self.undraw() + self.showInGlobalGraphicsView() + pass + elif mode == 'supression' : + self.removeFromGlobalGraphicsView() + pass + else : + return + + def showInGlobalGraphicsView( self ) : + self.draw() + self.getController().getMainFrame().updateGlobalGraphicsView( self ) + pass + + def removeFromGlobalGraphicsView( self ) : + self.getController().getMainFrame().updateGlobalGraphicsView( None ) + pass + + def draw( self ) : + print 'Virtual method' + pass + + def undraw( self ) : + for item in self.items() : + self.removeItem( item ) + pass + pass + +pass diff --git a/data/templates/PythonComponent/src/View/GraphicsView.py b/data/templates/PythonComponent/src/View/GraphicsView.py new file mode 100755 index 0000000..6635e13 --- /dev/null +++ b/data/templates/PythonComponent/src/View/GraphicsView.py @@ -0,0 +1,100 @@ +from Polyline import Polyline +from Circle import Circle +from qtsalome import * + +class GraphicsView( QGraphicsView ) : + + moved = pyqtSignal(QPointF) + released = pyqtSignal(QPointF) + + def __init__( self, scene ) : + QGraphicsView.__init__( self, scene ) + self.setMouseTracking( True ) + self._selectedItem = None + self.moved[QPointF].connect(self.execMouseMoveEvent) + self.released[QPointF].connect(self.execMouseReleaseEvent) + pass + + def mousePressEvent( self, mouseEvent ) : + QGraphicsView.mousePressEvent( self, mouseEvent ) + if self.scene() is None : return + self._selectedItem = self.scene().mouseGrabberItem() + pass + + def mouseMoveEvent( self, mouseEvent ) : + QGraphicsView.mouseMoveEvent( self, mouseEvent ) + pt = mouseEvent.pos() + currentPos = self.mapToScene( pt ) + self.moved.emit(currentPos) + pass + + def mouseReleaseEvent( self, mouseEvent ) : + QGraphicsView.mouseReleaseEvent( self, mouseEvent ) + if mouseEvent.button() == Qt.LeftButton : + pt = mouseEvent.pos() + newPos = self.mapToScene( pt ) + self.released.emit(newPos) + self._selectedItem = None + pass + pass + + def execMouseMoveEvent( self, currentPos ) : + if self._selectedItem is None : return + selectedIndex = self._selectedItem.getIndex() + newX = currentPos.x() + newY = currentPos.y() + newPoint = newX, newY + model = self.scene().getModel() + pen = QPen( QColor("red") ) + if isinstance( model, Polyline ) : + #Previsualisation + if selectedIndex == 0 : + nextPoint = model.getPoints()[ selectedIndex+1 ] + xNext = nextPoint[0] + yNext = nextPoint[1] + self.scene().addLine( newX, newY, xNext, yNext, pen ) + pass + elif selectedIndex == len( model.getPoints()) - 1 : + previousPoint = model.getPoints()[ selectedIndex-1 ] + xPrevious = previousPoint[0] + yPrevious = previousPoint[1] + self.scene().addLine( xPrevious, yPrevious, newX, newY, pen ) + pass + else : + previousPoint = model.getPoints()[ selectedIndex-1 ] + xPrevious = previousPoint[0] + yPrevious = previousPoint[1] + self.scene().addLine( xPrevious, yPrevious, newX, newY, pen ) + nextPoint = model.getPoints()[ selectedIndex+1 ] + xNext = nextPoint[0] + yNext = nextPoint[1] + self.scene().addLine( newX, newY, xNext, yNext, pen ) + pass + pass + elif isinstance( model, Circle ) : + #Previsualisation + radius = float( model.getRadius() ) + rect = QRectF( newX-radius, newY-radius, 2*radius, 2*radius ) + circleItem = QGraphicsEllipseItem() + circleItem.setPen( pen ) + circleItem.setRect( rect ) + self.scene().addItem( circleItem ) + pass + pass + + def execMouseReleaseEvent( self, newPos ) : + if self._selectedItem is None : return + selectedIndex = self._selectedItem.getIndex() + newX = newPos.x() + newY = newPos.y() + newPoint = newX, newY + model = self.scene().getModel() + if isinstance( model, Polyline ) : + self.scene().getController().editPoint( model, newPoint, selectedIndex ) + pass + elif isinstance( model, Circle ) : + self.scene().getController().editCenter( model, newPoint ) + pass + pass + +pass diff --git a/data/templates/PythonComponent/src/View/Menu.py b/data/templates/PythonComponent/src/View/Menu.py new file mode 100755 index 0000000..1f2a380 --- /dev/null +++ b/data/templates/PythonComponent/src/View/Menu.py @@ -0,0 +1,15 @@ +from qtsalome import * + +class Menu( QMenu ) : + + def __init__( self, item ) : + """Constructor""" + + QMenu.__init__( self ) + self._item = item + pass + + def getItem( self ) : + return self._item + +pass diff --git a/data/templates/PythonComponent/src/View/PolyGraphicsScene.py b/data/templates/PythonComponent/src/View/PolyGraphicsScene.py new file mode 100755 index 0000000..0690d75 --- /dev/null +++ b/data/templates/PythonComponent/src/View/PolyGraphicsScene.py @@ -0,0 +1,39 @@ +from GraphicsScene import GraphicsScene +from qtsalome import * +from GraphicsRectItem import GraphicsRectItem + +class PolyGraphicsScene( GraphicsScene ) : + + def __init__( self, controller ) : + GraphicsScene.__init__( self, controller ) + pass + + def draw( self ) : + points = self.getModel().getPoints() + + # Drawing the points as small rectangles + for i in range( len(points) ) : + point = points[i] + xPoint = float( point[0] ) + yPoint = float( point[1] ) + # Constructing a rectangle centered on point + pointItem = GraphicsRectItem( xPoint-0.1, yPoint-0.1, 0.2, 0.2, i ) + self.addItem( pointItem ) + pass + + # Linking the points with lines + for i in range( len(points) - 1 ) : + current = points[i] + next = points[i+1] + xCurrent = float( current[0] ) + yCurrent = float( current[1] ) + xNext = float( next[0] ) + yNext = float( next[1] ) + line = QLineF( xCurrent, yCurrent, xNext, yNext ) + lineItem = QGraphicsLineItem() + lineItem.setLine( line ) + self.addItem( lineItem ) + pass + pass + +pass diff --git a/data/templates/PythonComponent/src/View/PolyTreeWidgetItem.py b/data/templates/PythonComponent/src/View/PolyTreeWidgetItem.py new file mode 100755 index 0000000..344bf18 --- /dev/null +++ b/data/templates/PythonComponent/src/View/PolyTreeWidgetItem.py @@ -0,0 +1,27 @@ +from View import * +from TreeWidgetItem import TreeWidgetItem +from qtsalome import * + +class PolyTreeWidgetItem( TreeWidgetItem ) : + + def __init__( self, name, controller, actionsList ) : + """Constructor""" + + TreeWidgetItem.__init__( self, name, controller, actionsList ) + pass + + def editInGlobalTree( self, treeWidgetItem ) : + name = self.getModel().getName() + treeWidgetItem.setText( 0 , name ) + + points = self._model.getPoints() + for i in range( len(points) ) : + point = points[i] + xPoint = point[0] + yPoint = point[1] + relatedItem = treeWidgetItem.child( i ) + relatedItem.setText( 0 , str(xPoint) + ":" + str(yPoint) ) + pass + pass + +pass diff --git a/data/templates/PythonComponent/src/View/TreeWidget.py b/data/templates/PythonComponent/src/View/TreeWidget.py new file mode 100755 index 0000000..c3b1ccd --- /dev/null +++ b/data/templates/PythonComponent/src/View/TreeWidget.py @@ -0,0 +1,107 @@ +from qtsalome import * +from Menu import Menu +from RenameDialog import RenameDialog +from EditPointDialog import EditPointDialog +from EditCenterDialog import EditCenterDialog +from EditRadiusDialog import EditRadiusDialog +from Polyline import Polyline +from Circle import Circle +from SalomePyQt import SalomePyQt +from libSALOME_Swig import SALOMEGUI_Swig + +######################################### +# Global variables +######################################### + +sgPyQt = SalomePyQt() +sg = SALOMEGUI_Swig() +sgDesktop = sgPyQt.getDesktop() + +######################################### + +class TreeWidget( QTreeWidget ) : + + def __init__( self, desktop ) : + """Constructor""" + + QTreeWidget.__init__( self ) + self._desktop = desktop + + #Creating popup menu + self.setContextMenuPolicy( Qt.CustomContextMenu ) + self.customContextMenuRequested[QPoint].connect(self.createPopups) + pass + + def createPopups( self, point ) : + item = self.itemAt( point ) + if item is None : return + self.menu = Menu( item ) + for action in item.getActionsList(): + if action == "Show" : + self.menu.addAction(action).triggered.connect(self.show) + pass + elif action == 'Rename' : + self.menu.addAction(action).triggered.connect(self.showRenameDialog) + pass + elif action == 'Delete' : + self.menu.addAction(action).triggered.connect(self.delete) + pass + else : + self.menu.addAction(action).triggered.connect(self.showEditDialog) + pass + pass + self. menu.exec_( QCursor.pos() ) + pass + + def show( self ) : + model = self.menu.getItem().getModel() + controller = self._desktop.getController() + controller.showModel( model ) + pass + + def showRenameDialog( self ) : + model = self.menu.getItem().getModel() + oldName = model.getName() + widgetDialogBox = QDockWidget( sgDesktop ) + myDialog = RenameDialog( "www.google.fr", self._desktop.getController(), widgetDialogBox, model, oldName ) + widgetDialogBox.setAllowedAreas( Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea ) + widgetDialogBox.setWidget( myDialog ) + widgetDialogBox.setWindowTitle( "Object renaming" ) + sgDesktop.addDockWidget( Qt.LeftDockWidgetArea, widgetDialogBox ) + pass + + def delete( self ) : + answer = QMessageBox.question( self, 'Confirmation', 'Do you really want to remove the selected curve ?' , QMessageBox.Yes | QMessageBox.No ) + if answer == QMessageBox.Yes : + model = self.menu.getItem().getModel() + controller = self._desktop.getController() + controller.removeModel( model ) + pass + pass + + def showEditDialog( self ) : + item = self.menu.getItem() + parentItem = item.parent() + parentModel = parentItem.getModel() + widgetDialogBox = QDockWidget( sgDesktop ) + if isinstance( parentModel, Polyline ) : + pointRange = parentItem.indexOfChild( item ) + oldPoint = item.text( 0 ) + myDialog = EditPointDialog( "www.google.fr", self._desktop.getController(), widgetDialogBox, parentModel, oldPoint, pointRange ) + pass + elif isinstance( parentModel, Circle ) : + selectedRange = parentItem.indexOfChild( item ) + oldSelected = item.text( 0 ) + if selectedRange == 0 : myDialog = EditCenterDialog( "www.google.fr", self._desktop.getController(), widgetDialogBox, parentModel, oldSelected ) + elif selectedRange == 1 : myDialog = EditRadiusDialog("www.google.fr",self._desktop.getController(),widgetDialogBox,parentModel,oldSelected) + else : pass + pass + else : pass + + widgetDialogBox.setAllowedAreas( Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea ) + widgetDialogBox.setWidget( myDialog ) + widgetDialogBox.setWindowTitle( "Object edition" ) + sgDesktop.addDockWidget( Qt.LeftDockWidgetArea, widgetDialogBox ) + pass + +pass diff --git a/data/templates/PythonComponent/src/View/TreeWidgetItem.py b/data/templates/PythonComponent/src/View/TreeWidgetItem.py new file mode 100755 index 0000000..c24bf47 --- /dev/null +++ b/data/templates/PythonComponent/src/View/TreeWidgetItem.py @@ -0,0 +1,55 @@ +from View import * +from qtsalome import * + +class TreeWidgetItem( View, QTreeWidgetItem ) : + + def __init__( self, name, controller, actionsList ) : + """Constructor""" + + View.__init__( self, controller ) + self._name = [ name ] + QTreeWidgetItem.__init__( self, self._name ) + self._actionsList = actionsList + pass + + def getActionsList( self ) : + return self._actionsList + + def editCenter( self, center ) : + circle = self.getModel() + self.getController().editCenter( circle, center ) + pass + + def editRadius( self, radius ) : + circle = self.getModel() + self.getController().editRadius( circle, radius ) + pass + + def update( self, mode ) : + if mode == 'creation' : + self.addToGlobalTree( self ) + pass + elif mode == 'modification' : + self.editInGlobalTree( self ) + pass + elif mode == 'supression' : + self.removeFromGlobalTree( self ) + pass + else : + return + + def addToGlobalTree( self, treeWidgetItem ) : + globalTree = self.getController().getMainFrame().getGlobalTree() + globalTree.addTopLevelItem( treeWidgetItem ) + pass + + def editInGlobalTree( self, treeWidgetItem ) : + print 'Virtual' + pass + + def removeFromGlobalTree( self, treeWidgetItem ) : + globalTree = self.getController().getMainFrame().getGlobalTree() + globalTree.takeTopLevelItem( globalTree.indexOfTopLevelItem(treeWidgetItem) ) + pass + +pass diff --git a/data/templates/PythonComponent/src/View/View.py b/data/templates/PythonComponent/src/View/View.py new file mode 100755 index 0000000..899419d --- /dev/null +++ b/data/templates/PythonComponent/src/View/View.py @@ -0,0 +1,33 @@ +class View() : + + def __init__( self, controller ) : + """Constructor""" + + self._model = None + self._controller = controller + pass + + def getModel( self ) : + return self._model + + def setModel( self, model ) : + self._model = model + pass + + def getController( self ) : + return self._controller + + def setController( self, controller ) : + self._controller = controller + pass + + def editName( self, name ) : + model = self.getModel() + self._controller.editName( model, name ) + pass + + def update( self, mode ) : + print 'Virtual method' + pass + +pass diff --git a/data/templates/PythonComponent/template.info b/data/templates/PythonComponent/template.info new file mode 100644 index 0000000..0971a2c --- /dev/null +++ b/data/templates/PythonComponent/template.info @@ -0,0 +1,72 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +# description of the template to be displayed with option --info +info = """ +Author: CEA +Version: 1.1 +Date: 29/03/2018 +Description: This template can be used to create a python module for SALOME. +""" + +# code to substitute with component name +file_subst = "PYCMP" + +# delimiter used in the template (default is ':sat:') +#delimiter = ":sat:" + +# filter of files to ignore for substitution +# if not defined all files will be parsed +ignore_filters = '*.png' + +# list of parameters +# a string = parameter name +# a tuple = (parameter name, default value, prompt, validation method) + +#there is a problem for loading modules if user choose something else than standard "resources directory (lowercase)" +#so we need force standard choice... +# ('PYCMP_minus', "%(name)s", "resources directory (lowercase)", lambda l: l.islower() and l.replace("_","").isalnum()), + +parameters = [ + (file_subst, "%(NAME)s"), + ('PYCMPCompoName', "%(Name)s", "Name of the module (hit return!)"), + ('PYCMP_minus', "%(name)s", "resources directory (lowercase) (hit return!)", lambda l: l.islower() and l.replace("_","").isalnum()), + ("get_method", "archive", "get method for prepare", lambda l: l in ['cvs', 'git', 'archive']) + ] + +# configuration to use this component with sat +pyconf = """ + 'default': + { + name : "%(NAME)s" + + get_source : '%(get_method)s' + build_source : 'cmake' + git_info: + { + repo : 'to be filled' + tag : 'to be filled' + } + + environ : { } + depend : [ 'Python', 'KERNEL', 'GUI' ] + opt_depend : [] + + type : "salome" + + source_dir : $APPLICATION.workdir + $VARS.sep + 'SOURCES' + $VARS.sep + $name + build_dir : $APPLICATION.workdir + $VARS.sep + 'BUILD' + $VARS.sep + $name + + properties : + { + has_salome_gui : 'yes' + is_SALOME_module : 'yes' + has_unit_tests : True + } + + archive_info: + { + archive_name : '%(NAME)s.tgz' + } + } +"""