Create attractive VASL scenarios, with loads of useful information embedded to assist with game play. https://vasl-templates.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
vasl-templates/vasl_templates/file_dialog.py

96 lines
3.5 KiB

""" Manage loading and saving files. """
import os
from PyQt5.QtWidgets import QFileDialog
# ---------------------------------------------------------------------
# NOTE: While loading/saving files works fine when handled by the embedded browser,
# we can't get the full path of the file loaded (because of browser security).
# This means that we can't do things like default to saving a scenario to the same file
# it was loaded from, or retrying a failed save. This is such a lousy UX,
# we handle load/save operations ourself, where we can manage things like this.
class FileDialog:
"""Manage loading and saving files."""
def __init__( self, parent, object_name, default_extn, filters, default_fname ):
self.parent = parent
self.object_name = object_name
self.default_extn = default_extn
self.filters = filters
self.curr_fname = default_fname
# NOTE: We can't just use the directory of self.curr_fname, since this gets reset
# when the user chooses "new scenario", but we want to remember the current directory.
self._curr_dir = os.path.dirname( default_fname ) if default_fname else None
def load_file( self, binary ):
"""Load a file."""
# ask the user which file to load
fname, _ = QFileDialog.getOpenFileName(
self.parent, "Load {}".format( self.object_name ),
self._get_start_path(),
self.filters
)
if not fname:
return None
# load the file
try:
with open( fname, "rb" ) as fp:
data = fp.read()
except Exception as ex: #pylint: disable=broad-except
self.parent.showErrorMsg( "Can't load the {}:\n\n{}".format( self.object_name, ex ) )
return None
if not binary:
data = data.decode( "utf-8" )
self.curr_fname = fname
self._curr_dir = os.path.dirname( fname )
return data
def save_file( self, data ):
"""Save data to a file."""
# initialize
if isinstance( data, str ):
data = data.encode( "utf-8" )
while True: # nb: keep trying until the save succeeds or the user cancels the operation
# ask the user where to save the file
fname, _ = QFileDialog.getSaveFileName(
self.parent, "Save {}".format( self.object_name ),
self._get_start_path(),
self.filters
)
if not fname:
return False
# check the file extension
extn = os.path.splitext( fname )[1]
if not extn:
fname += self.default_extn
elif fname.endswith( "." ):
fname = fname[:-1]
# save the file
try:
with open( fname, "wb", ) as fp:
fp.write( data )
except Exception as ex: #pylint: disable=broad-except
self.parent.showErrorMsg( "Can't save the {}:\n\n{}".format( self.object_name, ex ) )
continue
self.curr_fname = fname
self._curr_dir = os.path.dirname( fname )
return True
def _get_start_path( self ):
"""Get the start filename or directory path for saving/loading files."""
if self.curr_fname and os.path.isabs( self.curr_fname ):
return self.curr_fname
if self._curr_dir and self.curr_fname:
return os.path.join( self._curr_dir, self.curr_fname )
return self.curr_fname