From d6261f7ca28c73e286ded23e54854ddae06caba3 Mon Sep 17 00:00:00 2001 From: vsv Date: Fri, 3 Aug 2018 15:25:35 +0300 Subject: [PATCH] Create help management system --- CMakeCommon/FindSphinx.cmake | 59 ++++++++++ CMakeLists.txt | 9 ++ doc/gui/CMakeLists.txt | 34 ++++-- doc/gui/Makefile | 20 ++++ doc/gui/conf.py.in | 153 ++++++++++++++++++++++++++ doc/gui/index.html | 1 - doc/gui/index.rst | 20 ++++ doc/gui/make.bat | 36 ++++++ src/Config/Config_FeatureMessage.cpp | 11 ++ src/Config/Config_FeatureMessage.h | 6 + src/Config/Config_FeatureReader.cpp | 1 + src/Config/Config_Keywords.h | 1 + src/ModuleBase/ModuleBase_Operation.h | 8 ++ src/XGUI/XGUI_Workshop.cpp | 50 ++++++++- src/XGUI/XGUI_Workshop.h | 3 + 15 files changed, 401 insertions(+), 11 deletions(-) create mode 100644 CMakeCommon/FindSphinx.cmake create mode 100644 doc/gui/Makefile create mode 100644 doc/gui/conf.py.in delete mode 100644 doc/gui/index.html create mode 100644 doc/gui/index.rst create mode 100644 doc/gui/make.bat diff --git a/CMakeCommon/FindSphinx.cmake b/CMakeCommon/FindSphinx.cmake new file mode 100644 index 000000000..cf0242aa1 --- /dev/null +++ b/CMakeCommon/FindSphinx.cmake @@ -0,0 +1,59 @@ +# - Sphinx detection +# +# Output variables: +# SPHINX_EXECUTABLE - path to the Sphinx executable +# SPHINX_PYTHONPATH - path to the Sphinx Python modules +# +########################################################################### +# Copyright (C) 2007-2016 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, 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 +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +FIND_PROGRAM(SPHINX_EXECUTABLE + NAMES sphinx-build sphinx-build-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} + PATH_SUFFIXES Scripts) +FIND_PROGRAM(SPHINX_APIDOC_EXECUTABLE + NAMES sphinx-apidoc sphinx-apidoc-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} + PATH_SUFFIXES Scripts) + +# Get root dir locally, going up two levels from the exec: +GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${SPHINX_EXECUTABLE}" PATH) +GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${_tmp_ROOT_DIR}" PATH) +IF(WIN32) + SET(SPHINX_PYTHONPATH "${_tmp_ROOT_DIR}/lib/site-packages") +ELSE() + SET(SPHINX_PYTHONPATH "${_tmp_ROOT_DIR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages") +ENDIF() + +# Handle the standard arguments of the find_package() command: +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sphinx REQUIRED_VARS SPHINX_EXECUTABLE SPHINX_APIDOC_EXECUTABLE) + +IF(SPHINX_EXECUTABLE) + EXECUTE_PROCESS(COMMAND ${SPHINX_EXECUTABLE} "--version" OUTPUT_VARIABLE SPHINX_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + STRING(REGEX REPLACE ".* ([0-9.]+)$" "\\1" SPHINX_VERSION "${SPHINX_VERSION}" ) + MESSAGE(STATUS "Sphinx version is ${SPHINX_VERSION}") + IF(SPHINX_VERSION VERSION_LESS "1.3") + SET(SPHINX_THEME "default") + ELSE() + SET(SPHINX_THEME "classic") + ENDIF() +ENDIF(SPHINX_EXECUTABLE) diff --git a/CMakeLists.txt b/CMakeLists.txt index b28a3d5cb..8006e1506 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ ENDIF(WIN32) SET (SHAPER_Version 8.5.0) SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeCommon" ${CMAKE_MODULE_PATH}) +OPTION(SHAPER_BUILD_DOC "Generate SHAPER documentation" ON) INCLUDE(SalomeMacros) @@ -174,6 +175,14 @@ IF(ADD_MODELS_TESTS) ADD_CUSTOM_TARGET(run_unit_tests COMMAND ${CMAKE_CTEST_COMMAND} -C "${CMAKE_BUILD_TYPE}" -LE "models_tests") ENDIF(ADD_MODELS_TESTS) + +IF(SHAPER_BUILD_DOC) + INCLUDE(FindSphinx) + ADD_SUBDIRECTORY (doc) +ENDIF(SHAPER_BUILD_DOC) + + + # Add the uninstall target for eclipse IDE if (CMAKE_GENERATOR MATCHES "NMake Makefiles") configure_file("${CMAKE_SOURCE_DIR}/CMakeCommon/cmake_uninstall.cmake.in" diff --git a/doc/gui/CMakeLists.txt b/doc/gui/CMakeLists.txt index 4cc6691a0..eb5563ab2 100644 --- a/doc/gui/CMakeLists.txt +++ b/doc/gui/CMakeLists.txt @@ -18,14 +18,32 @@ ## email : webmaster.salome@opencascade.com ## -SET(HTML_RESOURCES - index.html -) +SET(input ${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in) + +SET(output ${CMAKE_CURRENT_BINARY_DIR}/conf.py) + +CONFIGURE_FILE(${input} ${output}) + -ADD_CUSTOM_TARGET(usr_docs - SOURCES ${HTML_RESOURCES} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/doc/gui" +#sphinx-build -b html -c doc -D latex_paper_size=a4 -d doc/doctree /dn23/PPGP/vsv/SALOME730/SOURCES/PPGP_SRC/doc doc/html + +INSTALL(CODE " +EXECUTE_PROCESS( +COMMAND ${SPHINX_EXECUTABLE} -Q -b html -c ${CMAKE_CURRENT_BINARY_DIR} -D latex_paper_size=a4 -d doctree ${CMAKE_CURRENT_SOURCE_DIR} html +WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +)" ) -INSTALL(FILES ${HTML_RESOURCES} DESTINATION ${SHAPER_INSTALL_GUI_DOC} OPTIONAL) -INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target usr_docs)") +IF(${HAVE_SALOME}) +INSTALL(CODE " +EXECUTE_PROCESS( +COMMAND ${PYTHON_EXECUTABLE} -c \"import shutil;shutil.rmtree('${CMAKE_INSTALL_PREFIX}/share/doc/salome/gui/SHAPER', True);shutil.copytree('${CMAKE_CURRENT_BINARY_DIR}/html', '${CMAKE_INSTALL_PREFIX}/share/doc/salome/gui/SHAPER')\" +) +") +ELSE(${HAVE_SALOME}) +INSTALL(CODE " +EXECUTE_PROCESS( +COMMAND ${PYTHON_EXECUTABLE} -c \"import shutil;shutil.rmtree('${CMAKE_INSTALL_PREFIX}/doc', True);shutil.copytree('${CMAKE_CURRENT_BINARY_DIR}/html', '${CMAKE_INSTALL_PREFIX}/doc')\" +) +") +ENDIF(${HAVE_SALOME}) diff --git a/doc/gui/Makefile b/doc/gui/Makefile new file mode 100644 index 000000000..2cd260e71 --- /dev/null +++ b/doc/gui/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = SHAPER +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/doc/gui/conf.py.in b/doc/gui/conf.py.in new file mode 100644 index 000000000..68f3d4860 --- /dev/null +++ b/doc/gui/conf.py.in @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# +# SHAPER documentation build configuration file, created by +# sphinx-quickstart on Fri Aug 3 11:29:53 2018. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'SHAPER' +copyright = u'2014-2017 CEA/DEN, EDF R&D' +author = u'vsv' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'3.0.0' +# The full version, including alpha/beta/rc tags. +release = u'3.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'SHAPERdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'SHAPER.tex', u'SHAPER Documentation', + u'vsv', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'shaper', u'SHAPER Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'SHAPER', u'SHAPER Documentation', + author, 'SHAPER', 'One line description of project.', + 'Miscellaneous'), +] diff --git a/doc/gui/index.html b/doc/gui/index.html deleted file mode 100644 index a53e19f54..000000000 --- a/doc/gui/index.html +++ /dev/null @@ -1 +0,0 @@ -The documentation for the SHAPER module will come soon. \ No newline at end of file diff --git a/doc/gui/index.rst b/doc/gui/index.rst new file mode 100644 index 000000000..8f0c9c88d --- /dev/null +++ b/doc/gui/index.rst @@ -0,0 +1,20 @@ +.. SHAPER documentation master file, created by + sphinx-quickstart on Fri Aug 3 11:29:53 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to SHAPER's documentation! +================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/doc/gui/make.bat b/doc/gui/make.bat new file mode 100644 index 000000000..a3355b462 --- /dev/null +++ b/doc/gui/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=SHAPER + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/src/Config/Config_FeatureMessage.cpp b/src/Config/Config_FeatureMessage.cpp index 7220887d8..8c93a8f42 100644 --- a/src/Config/Config_FeatureMessage.cpp +++ b/src/Config/Config_FeatureMessage.cpp @@ -28,6 +28,7 @@ Config_FeatureMessage::Config_FeatureMessage(const Events_ID theId, const void* myTooltip = ""; myIcon = ""; myKeysequence = ""; + myHelpFile = ""; myGroupId = ""; myWorkbenchId = ""; @@ -215,4 +216,14 @@ void Config_FeatureMessage::setAutoPreview(bool isAutoPreview) void Config_FeatureMessage::setApplyContinue(bool isModal) { myIsApplyContinue = isModal; +} + +const std::string& Config_FeatureMessage::helpFileName() const +{ + return myHelpFile; +} + +void Config_FeatureMessage::setHelpFileName(const std::string& aName) +{ + myHelpFile = aName; } \ No newline at end of file diff --git a/src/Config/Config_FeatureMessage.h b/src/Config/Config_FeatureMessage.h index 1bd9ecff0..466c8e9b0 100644 --- a/src/Config/Config_FeatureMessage.h +++ b/src/Config/Config_FeatureMessage.h @@ -30,6 +30,7 @@ * \class Config_FeatureMessage * \ingroup Config * \brief Class to pass a feature entry extracted from xml file. + * Example of the feature entry: * \code * @@ -42,6 +43,7 @@ class Config_FeatureMessage : public Events_Message std::string myTooltip; ///setIcon(getProperty(theFeatureNode, FEATURE_ICON)); outFeatureMessage->setKeysequence(getProperty(theFeatureNode, FEATURE_KEYSEQUENCE)); + outFeatureMessage->setHelpFileName(getProperty(theFeatureNode, HELP_FILE)); std::string aGroupName = restoreAttribute(NODE_GROUP, _ID); std::string aWBNName = restoreAttribute(NODE_WORKBENCH, _ID); diff --git a/src/Config/Config_Keywords.h b/src/Config/Config_Keywords.h index 545d738a2..beb599b20 100644 --- a/src/Config/Config_Keywords.h +++ b/src/Config/Config_Keywords.h @@ -74,6 +74,7 @@ const static char* FEATURE_TOOLTIP = "tooltip"; const static char* GROUP_TOOLBAR = "toolbar"; const static char* FEATURE_ICON = "icon"; const static char* FEATURE_TEXT = "title"; +const static char* HELP_FILE = "helpfile"; const static char* FEATURE_KEYSEQUENCE = "keysequence"; const static char* FEATURE_NESTED = "nested"; const static char* FEATURE_WHEN_NESTED = "when_nested"; diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 7e88b08e0..4ea8c6c44 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -100,6 +100,12 @@ Q_OBJECT /// \return Currently installed property panel ModuleBase_IPropertyPanel* propertyPanel() const { return myPropertyPanel; } + QString helpFileName() const { return myHelpFileName; } + + void setHelpFileName(QString theName) { + myHelpFileName = theName; + } + signals: /// The operation is started void beforeStarted(); @@ -202,6 +208,8 @@ private: /// Access to property panel ModuleBase_IPropertyPanel* myPropertyPanel; + + QString myHelpFileName; }; #endif diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 6b079cdc3..a475dd584 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -135,6 +135,7 @@ #include #include #include +#include #include @@ -558,6 +559,47 @@ void XGUI_Workshop::onPreviewActionClicked() Events_Loop::loop()->send(aMsg); } + +//****************************************************** +void XGUI_Workshop::onHelpActionClicked() +{ + XGUI_OperationMgr* anOperationMgr = operationMgr(); + if (anOperationMgr) { + ModuleBase_Operation* aOperation = anOperationMgr->currentOperation(); + if (aOperation) { + QString aDocDir; + const QChar aSep = QDir::separator(); +#ifdef HAVE_SALOME + QString aBrowserName("HelpBrowser"); + QString aDir(getenv("SHAPER_ROOT_DIR")); + if (!aDir.isEmpty()) { + aDocDir = aDir + aSep + "share" + aSep + "doc" + aSep + + "salome" + aSep + "gui" + aSep + "SHAPER"; + } + SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr(); + bool aUseExtBrowser = aResMgr->booleanValue("ExternalBrowser", "use_external_browser", false); + if (aUseExtBrowser) { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + aBrowserName = aResMgr->stringValue("ExternalBrowser", platform); + } +#else + QString aBrowserName("C:\\Program Files\\Internet Explorer\\iexplore.exe"); + QString aDir(getenv("OPENPARTS_ROOT_DIR")); + aDocDir = aDir + aSep + "doc"; +#endif + QStringList aParams; + aParams << aDocDir + aSep + aOperation->helpFileName(); + QProcess::startDetached(aBrowserName, aParams); + } + } +} + + //****************************************************** void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer) { @@ -644,9 +686,10 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation) aFeatureInfo = aCommand->featureMessage(); #endif bool anIsAutoPreview = true; - if (aFeatureInfo.get()) + if (aFeatureInfo.get()) { anIsAutoPreview = aFeatureInfo->isAutoPreview(); - else { + theOperation->setHelpFileName(aFeatureInfo->helpFileName().c_str()); + } else { std::string aXmlCfg, aDescription; module()->getXMLRepresentation(aFeatureKind, aXmlCfg, aDescription); ModuleBase_WidgetFactory aFactory(aXmlCfg, moduleConnector()); @@ -1394,6 +1437,9 @@ void XGUI_Workshop::createDockWidgets() QAction* aPreviewAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Preview); connect(aPreviewAct, SIGNAL(triggered()), this, SLOT(onPreviewActionClicked())); + QAction* aHelpAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Help); + connect(aHelpAct, SIGNAL(triggered()), this, SLOT(onHelpActionClicked())); + connect(myPropertyPanel, SIGNAL(keyReleased(QObject*, QKeyEvent*)), myOperationMgr, SLOT(onKeyReleased(QObject*, QKeyEvent*))); connect(myPropertyPanel, SIGNAL(enterClicked(QObject*)), diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 7af135fc8..1d0662757 100755 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -466,6 +466,9 @@ private: /// compute preview. void onPreviewActionClicked(); + /// Called on help button clicked in the property panel. + void onHelpActionClicked(); + private: /// Init menu void initMenu(); -- 2.30.2