Source code for gui.menus.File

#
##
##  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/.
##
"""Functions from the File menu.

"""
import pyformex as pf
from pyformex.gui import guiscript as pg
from pyformex.gui import dialogs
from pyformex.gui import image
from pyformex.gui.widgets import _I, _G
from pyformex.gui.menus.Settings import updateSettings


##################### handle script files ##########################

[docs]def openScript(fn=None, exist=False, create=False): """Open a pyFormex script and set it as the current script. If no filename is specified, a file selection dialog is started to select an existing script, or allow to create a new file if exist is False. If the file exists and is a pyFormex script, it is set ready to execute. If the file is empty or create is True, a default pyFormex script template will be written to the file, overwriting the contents if the file existed. Then, the script is loaded into the editor. """ if fn is not None: fn = pf.Path(fn) else: mode = 'exist' if exist else 'file' fn = pg.askFilename(pf.cfg['curfile'], 'pyformex', mode=mode) if fn: if create and fn.exists() and fn.size > 0: if not pg.ack(f"The file {fn} exists and is not empty.\n " f"Are you sure you want to overwrite it?"): return None create = create or not fn.exists() or fn.size == 0 if create: template = pf.cfg['scripttemplate'] if template.exists(): template.copy(fn) updateSettings({'workdir': fn.parent}, save=True) pf.chdir(fn) pf.GUI.setcurfile(fn) pf.GUI.scripthistory.add(fn) if create: pg.editFile(fn) return fn
[docs]def editApp(appname=None): """Edit an application source file. If no appname is specified, the current application is used. This loads the application module, gets its file name, and if it is a source file or the the corresponding source file exists, that file is loaded into the editor. """ if appname is None: appname = pf.cfg['curfile'] if pf.utils.is_script(appname): # this is a script, not an app fn = pf.Path(appname) else: from pyformex import apps app = apps.load(appname) if app is None: fn = apps.findAppSource(appname) else: fn = apps.findAppSource(app) if not fn.exists(): pg.showWarning(f"The file '{fn}' does not exist") return pg.editFile(fn)
##################### other functions ########################## def showImage(filename=None): pf.clear() dia = pf.ImageLoadDialog(filename, store='showImage_data', extra=[ _I('size', (0, 0), itemtype='ivector', fields=('w', 'h'), text='Resize (if negative or zero: unchanged)'), _I('pos', (-1, -1), itemtype='ivector', fields=('x', 'y'), text='Insertion position (if negative: centered'), ]) res = dia.getResults() if res: pf.drawImage(res.pop('filename'), **res) def showImage3D(filename=None): pf.clear() dia = pf.ImageLoadDialog(filename, store='showImage3D_data', extra=[ _I('pixel cell', choices=['dot', 'quad']) ]) res = dia.getResults() if res: pf.drawImage3D(res['filename'], pixel=res['pixel cell'])
[docs]def saveImage(multi=False): """Save an image to file. Show the Save Image dialog, with the multisave mode checked if multi = True. Then, depending on the user's selection, either: - save the current Canvas/Window to file - start the multisave/autosave mode - do nothing """ dia = dialogs.ImageSaveDialog(multi=multi) res = dia.getResults() if res: if pf.verbosity(3): print(res) del res['set_size'] if pf.debugon(pf.DEBUG.IMAGE): print(res) # updateSettings({'workdir': pf.Path(opt.fn).parent}, save=True) image.saveImage(**res)
[docs]def startMultiSave(): """Start/change multisave mode""" saveImage(True)
[docs]def stopMultiSave(): """Stop multisave mode""" image.saveImage()
[docs]def saveIcon(): """Save an image as icon. This will show the Save Image dialog, with the multisave mode off and asking for an icon file name. Then save the current rendering to that file. """ ## We should create a specialized input dialog, asking also for the size fn = pg.askFilename(filter='icon') if fn: image.saveIcon(fn, size=32)
# viewer = None # def showImage(): # """Display an image file""" # from pyformex.gui.imageViewer import ImageViewer # global viewer # fn = pg.askFilename(filter='img') # if fn: # viewer = ImageViewer(pf.app, fn) # viewer.show()
[docs]def createMovieInteractive(): """Create a movie from a saved sequence of images. """ if not image.multisave: pf.warning('You need to start multisave mode first!') return names = image.multisave['filename'] glob = names.glob() res = pg.askItems([ _I('files', glob), _I('encoder', choices=['mencoder', 'convert', 'ffmpeg']), _G('Mencoder', [ _I('fps', 10), _I('vbirate', 800), ]), _G('Convert', [ _I('delay', 1), _I('colors', 256), ]), ], enablers=[ ('encoder', 'mencoder', 'Mencoder'), ('encoder', 'convert', 'Convert'), ]) if not res: return with pg.busyCursor(): image.createMovie(**res)
# # TODO: this no longer works with the new webgl; should redo # # def exportPGF(): # """Export the current scene to PGF""" # from pyformex.plugins.webgl import WebGL # fn = pg.askFilename(pf.cfg['workdir'], ['pgf', 'all']) # if fn: # with pg.busyCursor(): # print("Exporting current scene to", fn) # fn = fn.with_suffix('.pgf') # W = WebGL(fn.stem) # W.addScene() # res = W.exportPGF(fn, sep='') # print("Contents:", res) last_exported_webgl = None
[docs]def exportWebGL(): """Export the current scene to WebGL The user is asked for a file name to store the exported model, and after export, whether to load the model in the browser. """ global last_exported_webgl last_exported_webgl = None fn = pg.askFilename(pf.cfg['workdir'], 'html') if fn: last_exported_webgl = pg.exportWebGL(fn)
[docs]def multiWebGL(): """Export the current scene as a model in a multiscene WebGL The user is asked for a file name to store the exported model, and after export, whether to load the model in the browser. """ global last_exported_webgl last_exported_webgl = None if pg.the_multiWebGL is None: print("NO CURRENT EXPORT") else: print("CURRENTLY EXPORTED:", pg.the_multiWebGL.scenes) if pg.the_multiWebGL is None: fn = pg.askFilename(pf.cfg['workdir'], 'html') if fn: print("Exporting multiscene WebGL to", fn) pg.multiWebGL(fn=fn) print(pg.the_multiWebGL) if pg.the_multiWebGL is not None: res = pg.askItems([ _I('name', pg.the_multiWebGL.name, text='Name of the scene', tooltip='An empty name will skip the export of the current scene'), _I('finish', False, text='Finish the export'), ]) if res['name']: pg.multiWebGL(res['name']) if res['finish']: last_exported_webgl = pg.multiWebGL()
[docs]def showWebGL(): """Show the last WebGL model. """ if last_exported_webgl and last_exported_webgl.exists(): pg.showHtml(last_exported_webgl)
[docs]def recordSession(): """Record the current pyFormex session""" if pf.debugon(pf.DEBUG.IMAGE): print(f"RECORDING with {pf.options.dri=}") pf.External.require('ffmpeg') dia = dialogs.RecordSessionDialog(pf.cfg['workdir']) res = dia.getResults() if res: image.recordSession(**res)
########## The menu ########## menu_items = [ ('Exit', pg.closeGui), ('---', None), ('Change workdir', pg.askDirname), ('Open pyFormex script', openScript), ('Edit current script/app', editApp), ('Run current script/app', pg.play), ('Reload and run current app', pg.replay), ('Show Text File', pg.showFile), ('Edit Text File', pg.editFile), ('---', None), ('Save Image', saveImage), ('Start MultiSave', startMultiSave), ('Save Next Image', image.saveNext), ('Create Movie', createMovieInteractive), ('Stop MultiSave', stopMultiSave), ('Save as Icon', saveIcon), ('Show Image', [ ('on canvas', showImage), ('on 3d grid', showImage3D), ]), ('Export as WebGL', exportWebGL), ('Export as multiscene WebGL', multiWebGL), ('Show exported WebGL', showWebGL), ('Show HTML', pg.showHtml), ('Record Session', recordSession), ] # End