- trying to make loading a project an easier task for the application
This commit is contained in:
@@ -7,6 +7,10 @@ CHANGELOG for FlatCAM Evo beta
|
||||
|
||||
=================================================
|
||||
|
||||
27.03.2022
|
||||
|
||||
- trying to make loading a project an easier task for the application
|
||||
|
||||
24.03.2022
|
||||
|
||||
- refactoring names for some classes
|
||||
|
||||
100
appMain.py
100
appMain.py
@@ -226,21 +226,16 @@ class App(QtCore.QObject):
|
||||
file_opened = QtCore.pyqtSignal(str, str)
|
||||
# File type and filename
|
||||
file_saved = QtCore.pyqtSignal(str, str)
|
||||
|
||||
# close app signal
|
||||
close_app_signal = pyqtSignal()
|
||||
|
||||
# will perform the cleanup operation after a Graceful Exit
|
||||
# usefull for the NCC Tool and Paint Tool where some progressive plotting might leave
|
||||
# graphic residues behind
|
||||
cleanup = pyqtSignal()
|
||||
|
||||
# emitted when the new_project is created in a threaded way
|
||||
new_project_signal = pyqtSignal()
|
||||
|
||||
# Percentage of progress
|
||||
progress = QtCore.pyqtSignal(int)
|
||||
|
||||
# Emitted when a new object has been added or deleted from/to the collection
|
||||
object_status_changed = QtCore.pyqtSignal(object, str, str)
|
||||
|
||||
@@ -248,31 +243,28 @@ class App(QtCore.QObject):
|
||||
|
||||
# Emmited when shell command is finished(one command only)
|
||||
shell_command_finished = QtCore.pyqtSignal(object)
|
||||
|
||||
# Emitted when multiprocess pool has been recreated
|
||||
pool_recreated = QtCore.pyqtSignal(object)
|
||||
|
||||
# Emitted when an unhandled exception happens
|
||||
# in the worker task.
|
||||
thread_exception = QtCore.pyqtSignal(object)
|
||||
|
||||
# used to signal that there are arguments for the app
|
||||
args_at_startup = QtCore.pyqtSignal(list)
|
||||
|
||||
# a reusable signal to replot a list of objects
|
||||
# should be disconnected after use so it can be reused
|
||||
replot_signal = pyqtSignal(list)
|
||||
|
||||
# signal emitted when jumping
|
||||
jump_signal = pyqtSignal(tuple)
|
||||
|
||||
# signal emitted when jumping
|
||||
locate_signal = pyqtSignal(tuple, str)
|
||||
|
||||
proj_selection_changed = pyqtSignal(object, object)
|
||||
|
||||
# used by the FlatCAMScript object to process a script
|
||||
# used by the AppScript object to process a script
|
||||
run_script = pyqtSignal(str)
|
||||
# used when loading a project and parsing the project file
|
||||
restore_project = pyqtSignal(object, str, bool, bool, bool, bool)
|
||||
# used when loading a project and restoring objects
|
||||
restore_project_objects_sig = pyqtSignal(object, str, bool, bool)
|
||||
|
||||
def __init__(self, qapp, user_defaults=True):
|
||||
"""
|
||||
@@ -1411,6 +1403,9 @@ class App(QtCore.QObject):
|
||||
|
||||
# signals for displaying messages in the Tcl Shell are now connected in the ToolShell class
|
||||
|
||||
# loading an project
|
||||
self.restore_project.connect(self.f_handlers.restore_project_handler)
|
||||
self.restore_project_objects_sig.connect(self.f_handlers.restore_project_objects)
|
||||
# signal to be called when the app is quiting
|
||||
self.app_quit.connect(self.quit_application, type=Qt.ConnectionType.QueuedConnection)
|
||||
self.message.connect(
|
||||
@@ -1494,7 +1489,6 @@ class App(QtCore.QObject):
|
||||
# ###########################################################################################################
|
||||
# ####################################### FILE ASSOCIATIONS SIGNALS #########################################
|
||||
# ###########################################################################################################
|
||||
|
||||
self.ui.util_pref_form.fa_excellon_group.restore_btn.clicked.connect(
|
||||
lambda: self.restore_extensions(ext_type='excellon'))
|
||||
self.ui.util_pref_form.fa_gcode_group.restore_btn.clicked.connect(
|
||||
@@ -2119,12 +2113,13 @@ class App(QtCore.QObject):
|
||||
self.ui.menu_plugins_shell.triggered.connect(self.ui.toggle_shell_ui)
|
||||
|
||||
# third install all of them
|
||||
t0 = time.time()
|
||||
try:
|
||||
self.install_tools(init_tcl=init_tcl)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
self.log.debug("Tools are initialized.")
|
||||
self.log.debug("%s: %s" % ("Tools are initialized in", str(time.time() - t0)))
|
||||
|
||||
# def parse_system_fonts(self):
|
||||
# self.worker_task.emit({'fcn': self.f_parse.get_fonts_by_types,
|
||||
@@ -10245,7 +10240,7 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
|
||||
self.log.debug("on_file_new_project()")
|
||||
|
||||
t0 = time.time()
|
||||
t_start_proj = time.time()
|
||||
|
||||
# close any editor that might be open
|
||||
if self.app.call_source != 'app':
|
||||
@@ -10281,7 +10276,7 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
# delete any selection shape on canvas
|
||||
self.app.delete_selection_shape()
|
||||
|
||||
# delete all FlatCAM objects
|
||||
# delete all App objects
|
||||
if keep_scripts is True:
|
||||
for prj_obj in self.app.collection.get_list():
|
||||
if prj_obj.kind != 'script':
|
||||
@@ -10289,6 +10284,9 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
else:
|
||||
self.app.collection.delete_all()
|
||||
|
||||
self.log.debug('%s: %s %s.' %
|
||||
("Deleted all the application objects", str(time.time() - t_start_proj), _("seconds")))
|
||||
|
||||
# add in Selected tab an initial text that describe the flow of work in FlatCAm
|
||||
self.app.setup_default_properties_tab()
|
||||
|
||||
@@ -10305,6 +10303,7 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
if use_thread is True:
|
||||
self.app.new_project_signal.emit()
|
||||
else:
|
||||
t0 = time.time()
|
||||
# Clear pool
|
||||
self.app.clear_pool()
|
||||
|
||||
@@ -10313,6 +10312,8 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
self.app.init_tools(init_tcl=True)
|
||||
else:
|
||||
self.app.init_tools(init_tcl=False)
|
||||
self.log.debug(
|
||||
'%s: %s %s.' % ("Initiated the MP pool and plugins in: ", str(time.time() - t0), _("seconds")))
|
||||
|
||||
# tcl needs to be reinitialized, otherwise old shell variables etc remains
|
||||
# self.app.shell.init_tcl()
|
||||
@@ -10336,7 +10337,7 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
# take the focus of the Notebook on Project Tab.
|
||||
self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
|
||||
|
||||
self.log.debug('%s: %s %s.' % (_("Project created in"), str(time.time() - t0), _("seconds")))
|
||||
self.log.debug('%s: %s %s.' % (_("Project created in"), str(time.time() - t_start_proj), _("seconds")))
|
||||
self.app.ui.set_ui_title(name=_("New Project - Not saved"))
|
||||
|
||||
self.inform.emit('[success] %s...' % _("New Project created"))
|
||||
@@ -10348,6 +10349,7 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
t0 = time.time()
|
||||
|
||||
# Clear pool
|
||||
self.log.debug("New Project: cleaning multiprocessing pool.")
|
||||
@@ -10356,6 +10358,7 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
# Init FlatCAMTools
|
||||
self.log.debug("New Project: initializing the Tools and Tcl Shell.")
|
||||
self.app.init_tools(init_tcl=True)
|
||||
self.log.debug('%s: %s %s.' % ("Initiated the MP pool and plugins in: ", str(time.time() - t0), _("seconds")))
|
||||
|
||||
def on_filenewscript(self, silent=False):
|
||||
"""
|
||||
@@ -11854,7 +11857,7 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open config file"), filename))
|
||||
return
|
||||
|
||||
def open_project(self, filename, run_from_arg=None, plot=True, cli=None, from_tcl=False):
|
||||
def open_project(self, filename, run_from_arg=False, plot=True, cli=False, from_tcl=False):
|
||||
"""
|
||||
Loads a project from the specified file.
|
||||
|
||||
@@ -11872,8 +11875,11 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
:param from_tcl: True if run from Tcl Sehll
|
||||
:return: None
|
||||
"""
|
||||
self.log.debug("Opening project: " + filename)
|
||||
if not os.path.exists(filename):
|
||||
|
||||
project_filename = filename
|
||||
|
||||
self.log.debug("Opening project: " + project_filename)
|
||||
if not os.path.exists(project_filename):
|
||||
self.inform.emit('[ERROR_NOTCL] %s' % _("File no longer available."))
|
||||
return
|
||||
|
||||
@@ -11893,22 +11899,24 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
alignment=Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignLeft,
|
||||
color=QtGui.QColor("lightgray"))
|
||||
|
||||
def parse_worker(prj_filename):
|
||||
with self.app.proc_container.new('%s' % _("Parsing...")):
|
||||
# Open and parse an uncompressed Project file
|
||||
try:
|
||||
f = open(filename, 'r')
|
||||
f = open(prj_filename, 'r')
|
||||
except IOError:
|
||||
if from_tcl:
|
||||
name = filename.split('/')[-1].split('\\')[-1]
|
||||
filename = self.options['global_tcl_path'] + '/' + name
|
||||
name = prj_filename.split('/')[-1].split('\\')[-1]
|
||||
prj_filename = os.path.join(self.options['global_tcl_path'], name)
|
||||
try:
|
||||
f = open(filename, 'r')
|
||||
f = open(prj_filename, 'r')
|
||||
except IOError:
|
||||
self.log.error("Failed to open project file: %s" % filename)
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open project file"), filename))
|
||||
self.log.error("Failed to open project file: %s" % prj_filename)
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open project file"), prj_filename))
|
||||
return
|
||||
else:
|
||||
self.log.error("Failed to open project file: %s" % filename)
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open project file"), filename))
|
||||
self.log.error("Failed to open project file: %s" % prj_filename)
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open project file"), prj_filename))
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -11916,17 +11924,17 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
except Exception as e:
|
||||
self.log.debug(
|
||||
"Failed to parse project file, trying to see if it loads as an LZMA archive: %s because %s" %
|
||||
(filename, str(e)))
|
||||
(prj_filename, str(e)))
|
||||
f.close()
|
||||
|
||||
# Open and parse a compressed Project file
|
||||
try:
|
||||
with lzma.open(filename) as f:
|
||||
with lzma.open(prj_filename) as f:
|
||||
file_content = f.read().decode('utf-8')
|
||||
d = json.loads(file_content, object_hook=dict2obj)
|
||||
except Exception as e:
|
||||
self.log.error("Failed to open project file: %s with error: %s" % (filename, str(e)))
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open project file"), filename))
|
||||
self.log.error("Failed to open project file: %s with error: %s" % (prj_filename, str(e)))
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open project file"), prj_filename))
|
||||
return
|
||||
|
||||
# Check for older projects
|
||||
@@ -11965,6 +11973,11 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
self.app.log.error("Legacy Project. Loading not supported.")
|
||||
return
|
||||
|
||||
self.app.restore_project.emit(d, prj_filename, run_from_arg, from_tcl, cli, plot)
|
||||
|
||||
self.app.worker_task.emit({'fcn': parse_worker, 'params': [project_filename]})
|
||||
|
||||
def restore_project_handler(self, proj_dict, filename, run_from_arg, from_tcl, cli, plot):
|
||||
# Clear the current project
|
||||
# # NOT THREAD SAFE # ##
|
||||
if run_from_arg is True:
|
||||
@@ -11996,13 +12009,13 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
# self.app.defaults.update(self.app.options)
|
||||
# self.app.preferencesUiManager.save_defaults()
|
||||
# Project options
|
||||
self.app.options.update(d['options'])
|
||||
self.app.options.update(proj_dict['options'])
|
||||
if response == bt_no:
|
||||
pass
|
||||
else:
|
||||
# Load by default new options when not using GUI
|
||||
# Project options
|
||||
self.app.options.update(d['options'])
|
||||
self.app.options.update(proj_dict['options'])
|
||||
|
||||
self.app.project_filename = filename
|
||||
|
||||
@@ -12011,10 +12024,15 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
if cli is None:
|
||||
self.app.set_screen_units(self.app.options["units"])
|
||||
|
||||
self.app.restore_project_objects_sig.emit(proj_dict, filename, cli, plot)
|
||||
|
||||
def restore_project_objects(self, proj_dict, filename, cli, plot):
|
||||
|
||||
def worker_task():
|
||||
with self.app.proc_container.new('%s' % _("Loading...")):
|
||||
# Re create objects
|
||||
self.log.debug(" **************** Started PROEJCT loading... **************** ")
|
||||
|
||||
for obj in d['objs']:
|
||||
for obj in proj_dict['objs']:
|
||||
try:
|
||||
msg = "Recreating from opened project an %s object: %s" % \
|
||||
(obj['kind'].capitalize(), obj['obj_options']['name'])
|
||||
@@ -12025,9 +12043,6 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
self.app.log.debug(msg)
|
||||
|
||||
def obj_init(new_obj, app_inst):
|
||||
|
||||
def worker_task():
|
||||
with app_inst.proc_container.new('%s...' % _("Opening")):
|
||||
try:
|
||||
new_obj.from_dict(obj)
|
||||
except Exception as erro:
|
||||
@@ -12100,9 +12115,6 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
# CNCJob.set_ui()
|
||||
new_obj.is_loaded_from_project = True
|
||||
|
||||
worker_task()
|
||||
# app_inst.worker_task.emit({'fcn': worker_task, 'params': []})
|
||||
|
||||
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
|
||||
# it's because the TclCommand is run in another thread (it inherits TclCommandSignaled)
|
||||
try:
|
||||
@@ -12138,6 +12150,8 @@ class MenuFileHandlers(QtCore.QObject):
|
||||
|
||||
self.log.debug(" **************** Finished PROJECT loading... **************** ")
|
||||
|
||||
self.app.worker_task.emit({'fcn': worker_task, 'params': []})
|
||||
|
||||
def save_project(self, filename, quit_action=False, silent=False, from_tcl=False):
|
||||
"""
|
||||
Saves the current project to the specified file.
|
||||
|
||||
Reference in New Issue
Block a user