Source code for gui.menus.Help

#
##
##  SPDX-FileCopyrightText: © 2007-2024 Benedict Verhegghe <bverheg@gmail.com>
##  SPDX-License-Identifier: GPL-3.0-or-later
##
##  This file is part of pyFormex 3.5  (Thu Feb  8 19:11:13 CET 2024)
##  pyFormex is a tool for generating, manipulating and transforming 3D
##  geometrical models by sequences of mathematical operations.
##  Home page: https://pyformex.org
##  Project page: https://savannah.nongnu.org/projects/pyformex/
##  Development: https://gitlab.com/bverheg/pyformex
##  Distributed under the GNU General Public License version 3 or later.
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program.  If not, see http://www.gnu.org/licenses/.
##
"""Display help

"""
import sys

import pyformex as pf
from pyformex.gui import guiscript as pg
from pyformex.gui.menus.Settings import updateSettings
_I = pg._I


# TODO: this info may be not up to date
# The location of the local docs depends on the type of installation
#
#  'G': build/install under git tree
#         build_dir = pyformexdir / 'doc'
#
#  'URD': as user post-install:
#         build_dir = .local/share/pyformex/doc/html
#
#  'R': pyformex installation from .tar.gz, during install:
#         build in pyformexdir / 'doc', install in /usr/local/share
#
#  'D': debian package during creation
#         build in pyformexdir / 'doc'
#         create pyformex-doc package /usr/share/doc/pyformex/html
#

[docs]def checkHtmlDir(): """Check that we have the html docs available""" for htmldir in ( # paths where the html docs might be pf.cfg['htmldir'], pf.cfg['docdir'] / 'html', pf.Path.home() / '.local' / 'share' / 'pyformex' / 'doc' / 'html', pf.Path.home() / '.local' / 'lib' / 'pyformex' / 'doc' / 'html', ): if (htmldir / 'index.html').exists(): if pf.cfg['htmldir'] != htmldir: pf.cfg['htmldir'] = htmldir # correct if needed return True return False
[docs]def checkHtmlReqs(): """Check the requirements for building the html docs""" required = { 'System': { 'pyFormex_installtype': 'G', }, 'Module': { 'docutils': '>= 0', 'sphinx': '>= 1.4', }, 'External': { 'sphinx-build': '>= 1.4', }, } # CHECK SOFT result, s = pf.software.checkSoftware(required, report=True) print(s) return result
[docs]def buildHtmlDocs(builddir=None): """Build the html documentation. Note: this is only for users building the docs. Builds at installation time are done by the Makefile. builddir is where the docs are built. For 'G' this is pyformex/doc/. For 'RD' this is .local/share/pyformex/doc/html. """ # Check requirements if not checkHtmlReqs() != 'OK': raise ValueError("I could not find some required software") # the source should always be here sourcedir = pf.cfg['pyformexdir'] / 'sphinx' print(f"BUILDDIR {builddir} ({type(builddir)})") if builddir is None: # set default build dir if pf._installtype in 'GU': builddir = pf.cfg['docdir'] else: builddir = pf.Path.home() / '.local' / 'share' / 'pyformex' / 'doc' print(f"BUILDDIR {builddir} ({type(builddir)})") builddir.mkdir(parents=True, exist_ok=True) if not builddir.is_writable_dir(): pg.error("TODO: !!!!!!") if pg.showInfo(f""".. Building local documentation ---------------------------- I will now build the local documentation in :: {builddir} As this is a lengthy process (especially if you are building for the first time), I will run it in the background and notify you when it's ready. """, actions=['Cancel', 'OK']) == 'OK': cmd = f'make -C {sourcedir} html BUILDDIR={builddir}' P = pg.runLongTask(cmd) print(f"Return with value {P.returncode}") updateSettings({'htmldir': builddir}, save=True) menu_setup(pf.GUI.menu)
[docs]def searchIndex(): """Search text in pyFormex refman index. Asks a pattern from the user and searches for it the index of the local pyFormex documentation. Displays the results in the browser. """ res = pg.askItems([ _I('text', '', text='String to search'), ]) if res: showLocalURL(f"search.html?q={res['text']}&check_keywords=yes&area=default")
[docs]def searchText(): """Search text in pyFormex source files. Asks a pattern from the user and searches for it through all the pyFormex source files. """ res = pg.askItems([ _I('pattern', '', text='String to grep'), _I('options', '', text='Options', tooltip="Some cool options: -a (extended search), -i (ignore case), " "-f (literal string), -e (extended regexp)"), ]) if res: out = pf.utils.grepSource(relative=False, **res) pg.showText(out, mono=True) # , modal=False)
[docs]def catchAndDisplay(expression): """Catch stdout from a Python expression and display it in a window.""" save = sys.stdout try: with pf.TempFile() as f: sys.stdout = f eval(expression) f.seek(0) pg.showText(f.read()) finally: sys.stdout = save
[docs]def opengl(): """Display the OpenGL format description.""" from pyformex.gui import qtgl from pyformex.opengl import gl s = pf.formatDict(gl.gl_version()) + '\n' s += qtgl.OpenGLFormat(pf.canvas.format()) pg.showText(s, mono=True)
[docs]def detected(probe): """Display the detected software components.""" header = "Detected Software" if not probe: header = "Already " + header pg.showText( pf.cmdtools.whereami() + '\n\n' + pf.software.reportSoftware(probe=probe, header=header, color=False), mono=True)
[docs]def about(): """Display short information about pyFormex.""" version = pf.version() pg.showInfo(f""".. {version} {'='*len(version)} A tool for generating, manipulating and transforming 3D geometrical models by sequences of mathematical operations. {pf._copyright} Distributed under the GNU GPL version 3 or later """) # noqa: E501
[docs]def developers(): """Display the list of developers.""" import random devs = [ 'Matthieu De Beule', 'Nic Debusschere', 'Gianluca De Santis', 'Bart Desloovere', 'Wouter Devriendt', 'Francesco Iannaccone', 'Peter Mortier', 'Tim Neels', 'Tomas Praet', 'Tran Phuong Toan', 'Sofie Van Cauter', 'Benedict Verhegghe', 'Zhou Wenxuan', ] random.shuffle(devs) pg.showInfo("The following people have\n" "contributed to pyFormex.\n" "They are listed in random order.\n\n" + '\n'.join(devs) + "\n\nIf you feel that your name was left\n" "out in error, please write to\n" "bverheg@gmail.com\n")
_NO_COOKIES = 'No cookies found :(' _cookies = [] def roll(l): l.append(l.pop(0)) def cookie(): import random global _cookies if not _cookies: try: cookie_file = pf.cfg['datadir'] / 'cookies.txt' _cookies = cookie_file.read_text().split('\n') print(f"Read {len(_cookies)} cookies") random.shuffle(_cookies) except Exception: _cookies = [_NO_COOKIES] pg.showInfo(_cookies[0], ["OK"]) roll(_cookies) # Help showing functions
[docs]def showLocalURL(filename): """Show a html document in the local html dir. Parameters ---------- filename: str Path of the file relative to pf.cfg['htmldir'] """ path = pf.cfg['htmldir'] / filename pg.showURL(f"file:{path}")
[docs]def showConfig(which): """Show one of the configs: S(ession), U(ser), F(actory)""" cfg = {'S': pf.cfg, 'U': pf.prefcfg, 'F': pf.refcfg}[which] pg.showText(str(cfg))
[docs]def install_external(pkgdir, prgname): """Install external software from the pyformex/extra dir""" extdir = pf.cfg['pyformexdir'] / 'extra' / pkgdir cmd = f"cd {extdir} && make && make install" P = pf.utils.command(cmd, shell=True) if P.returncode: pg.showText(P.stdout + P.stderr) else: if pf.External.has(prgname, check=True): info = f"Succesfully installed {prgname}" else: info = "You should now restart pyFormex!" pg.showInfo(info) return P.returncode
# Short aliases for use in items _L = showLocalURL _C = showConfig _F = pg.showFile _U = pg.showURL _E = install_external # constant strings used in items docdir = pf.cfg['docdir'] savannah = 'http://savannah.nongnu.org/'
[docs]def showHelp(action): """Function triggered by the help menu items. If the action's data is a tuple with a callable as first item, call it with the remainder of the tuple as arguments. """ if pf.debugon(pf.DEBUG.HELP): print(f"SHOWHELP {action.text()}") data = action.data() if data and isinstance(data, tuple) and callable(data[0]): data[0](*data[1:])
##### extra help items when running from source directory ######## if pf._installtype in 'UG': # extra help items for developer version devdir = pf.cfg['pyformexdir'] / '..' dev_installs = [ # ('dxfparser', (_E, 'dxfparser', 'pyformex-dxfparser')), # fails ('postabq', (_E, 'postabq', 'pyformex-postabq')), ('gtsinside', (_E, 'gts', 'gtsinside')), ] dev_docs = [ ('Developer Guides', [ ('Developer HOWTO', ( _F, devdir / "HOWTO-dev.rst")), ('pyFormex coding style guide', ( _F, devdir / "HOWTO-style.rst")), ('Installation of extra software', ( _F, devdir / "install-extra.rst")), ('Numpy documentation guidelines', ( _U, 'https://numpydoc.readthedocs.io/en/latest/' 'format.html#docstring-standard')), ('re-structured text (reST)', ( _U, 'http://docutils.sourceforge.io/rst.html')), ]), ('Build local documentation', buildHtmlDocs), ] else: dev_installs = dev_docs = [] ########## The menu ########## menu_items = [ ('Online documentation', (_U, pf.cfg['help/webdoc'])), ('---', None), ('Local documentation', (_L, 'index.html')), ('Reference Manual', (_L, 'refman.html')), ('Tutorial', (_L, 'tutorial.html')), ('Running pyFormex', (_L, 'running.html')), ('Module Index', (_L, 'py-modindex.html')), ('Index', (_L, 'genindex.html')), ('Search in index', searchIndex), ('Search in source', searchText), ('About Current Application', pg.showDoc), ('---', None), ('Readme', (_F, docdir / 'README.rst')), ('ReleaseNotes', (_F, docdir / 'ReleaseNotes')), ('License', (_F, docdir / 'LICENSE')), ('Detected Software', [ ('Detected so far', (detected, False)), ('Probe all', (detected, True)), ]), ('OpenGL Format', opengl), ('Settings', [ ('Session settings', (_C, 'S')), ('User settings', (_C, 'U')), ('Factory settings', (_C, 'F')), ]), ('---', None), ('Important Links', [ ('pyFormex', (_U, 'http://pyformex.org')), ('pyFormex development', (_U, 'https://gitlab.com/bverheg/pyformex')), ('pyFormex issues', (_U, 'https://gitlab.com/bverheg/pyformex/-/issues')), ('pyFormex @Savannah', [ ('project page', (_U, savannah + 'projects/pyformex/')), ('support', (_U, savannah + 'support/?func=additem&group=pyformex')), ('bugs', (_U, savannah + 'bugs/?func=additem&group=pyformex')), ]), ('Python', (_U, 'https://python.org')), ('NumPy', (_U, 'https://numpy.org/doc/stable/')), ]), ('Fortune Cookie', cookie), ('People', developers), ('---', None), ('About', about), ('---', None), ('Install Externals', [ ('Instant Meshes', (_E, 'instant', 'instant-meshes')), ] + dev_installs), ] + dev_docs menu_func = showHelp # End