From c04957322e9a80f8a917ccbe1ed672a85826ff4f Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 20 Mar 2022 14:32:20 +0200 Subject: [PATCH] - added a last resort option to load old projects; the result is not guaranteed if the differences are too great --- CHANGELOG.md | 4 ++ appObjects/FlatCAMCNCJob.py | 21 +++++- appObjects/FlatCAMGeometry.py | 9 +++ app_Main.py | 117 ++++++++++++++++++++++++---------- 4 files changed, 116 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 243249c9..28daca36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta ================================================= +20.03.2022 + +- added a last resort option to load old projects; the result is not guaranteed if the differences are too great + 19.03.2022 - fixed some errors for when loading a saved project diff --git a/appObjects/FlatCAMCNCJob.py b/appObjects/FlatCAMCNCJob.py index a4512e54..be7f9853 100644 --- a/appObjects/FlatCAMCNCJob.py +++ b/appObjects/FlatCAMCNCJob.py @@ -859,7 +859,12 @@ class CNCJobObject(FlatCAMObj, CNCjob): if self.obj_options['type'].lower() == 'geometry': try: for key in self.tools: - ppg = self.tools[key]['data']['tools_mill_ppname_g'] + try: + ppg = self.tools[key]['data']['tools_mill_ppname_g'] + except KeyError: + # for older loaded projects + ppg = self.app.options['tools_mill_ppname_g'] + if 'marlin' in ppg.lower() or 'repetier' in ppg.lower(): marlin = True break @@ -1001,7 +1006,13 @@ class CNCJobObject(FlatCAMObj, CNCjob): # for the case that self.tools is empty: old projects try: first_key = list(self.tools.keys())[0] - include_header = self.app.preprocessors[self.tools[first_key]['data']['tools_mill_ppname_g']] + try: + include_header = self.app.preprocessors[self.tools[first_key]['data']['tools_mill_ppname_g']] + except KeyError: + # for older loaded projects + self.app.log.debug("CNCJobObject.export_gcode() --> old project detected. Results are unreliable.") + include_header = self.app.preprocessors[self.app.options['tools_mill_ppname_g']] + include_header = include_header.include_header except (TypeError, IndexError): include_header = self.app.preprocessors['default'].include_header @@ -1020,6 +1031,12 @@ class CNCJobObject(FlatCAMObj, CNCjob): include_header = self.app.preprocessors[ self.tools[first_key]['data']['ppname_e'] ].include_header + except Exception: + self.app.log.debug("CNCJobObject.export_gcode() --> old project detected. Results are unreliable.") + # for older loaded projects + include_header = self.app.preprocessors[ + self.app.options['tools_drill_ppname_e'] + ].include_header except TypeError: # when self.tools is empty - old projects include_header = self.app.preprocessors['default'].include_header diff --git a/appObjects/FlatCAMGeometry.py b/appObjects/FlatCAMGeometry.py index e9338e30..86fef406 100644 --- a/appObjects/FlatCAMGeometry.py +++ b/appObjects/FlatCAMGeometry.py @@ -196,6 +196,9 @@ class GeometryObject(FlatCAMObj, Geometry): offset_item_txt = self.offset_item_options[tooluid_value['data']['tools_mill_offset_type']] except TypeError: offset_item_txt = tooluid_value['data']['tools_mill_offset_type'] + except KeyError: + # for older loaded projects + offset_item_txt = self.app.options['tools_mill_offset_type'] offset_item = QtWidgets.QTableWidgetItem(offset_item_txt) offset_item.setFlags(QtCore.Qt.ItemFlag.ItemIsEnabled) self.ui.geo_tools_table.setItem(row_idx, 2, offset_item) # Offset Type @@ -205,6 +208,9 @@ class GeometryObject(FlatCAMObj, Geometry): job_item_txt = self.job_item_options[tooluid_value['data']['tools_mill_job_type']] except TypeError: job_item_txt = tooluid_value['data']['tools_mill_job_type'] + except KeyError: + # for older loaded projects + job_item_txt = self.app.options['tools_mill_job_type'] job_item = QtWidgets.QTableWidgetItem(job_item_txt) job_item.setFlags(QtCore.Qt.ItemFlag.ItemIsEnabled) self.ui.geo_tools_table.setItem(row_idx, 3, job_item) # Job Type @@ -214,6 +220,9 @@ class GeometryObject(FlatCAMObj, Geometry): tool_shape_item_txt = self.tool_type_item_options[tooluid_value['data']['tools_mill_tool_shape']] except TypeError: tool_shape_item_txt = tooluid_value['data']['tools_mill_tool_shape'] + except KeyError: + # for older loaded projects + tool_shape_item_txt = self.app.options['tools_mill_tool_shape'] tool_shape_item = QtWidgets.QTableWidgetItem(tool_shape_item_txt) tool_shape_item.setFlags(QtCore.Qt.ItemFlag.ItemIsEnabled) self.ui.geo_tools_table.setItem(row_idx, 4, tool_shape_item) # Tool Shape diff --git a/app_Main.py b/app_Main.py index 8778ebe9..6700b6b5 100644 --- a/app_Main.py +++ b/app_Main.py @@ -10333,30 +10333,6 @@ class MenuFileHandlers(QtCore.QObject): self.app.ui.plot_tab_area.insertTab(0, self.app.ui.plot_tab, _("Plot Area")) self.app.ui.plot_tab_area.protectTab(0) - if silenced is None or silenced is False: - msgbox = FCMessageBox(parent=self.app.ui) - title = _("Save preferences") - txt = _("Do you want to save the loaded project settings as the default settings?") - msgbox.setWindowTitle(title) # taskbar still shows it - msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png')) - msgbox.setText('%s' % title) - msgbox.setInformativeText(txt) - msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/save_as.png')) - - bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.ButtonRole.YesRole) - bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.ButtonRole.NoRole) - # bt_cancel = msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.ButtonRole.RejectRole) - - msgbox.setDefaultButton(bt_yes) - msgbox.exec() - response = msgbox.clickedButton() - - if response == bt_yes: - self.app.defaults.update(self.app.options) - self.app.preferencesUiManager.save_defaults() - if response == bt_no: - pass - # take the focus of the Notebook on Project Tab. self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) @@ -11893,6 +11869,41 @@ class MenuFileHandlers(QtCore.QObject): self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open project file"), filename)) return + # Check for older projects + found_older_project = False + for obj in d['objs']: + if 'cnc_tools' in obj or 'exc_cnc_tools' in obj or 'apertures' in obj: + self.app.log.error( + 'MenuFileHandlers.open_project() --> %s %s. %s' % + ("Failed to open the CNCJob file:", str(obj['options']['name']), + "Maybe it is an old project.")) + found_older_project = True + + if found_older_project: + if not run_from_arg or not cli or from_tcl is False: + msgbox = FCMessageBox(parent=self.app.ui) + title = _("Legacy Project") + txt = _("The loaded project was made for an older version.\n" + "It may not load correctly. Do you want to continue?") + msgbox.setWindowTitle(title) # taskbar still shows it + msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png')) + msgbox.setText('%s' % title) + msgbox.setInformativeText(txt) + msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question) + + bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.ButtonRole.AcceptRole) + bt_cancel = msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.ButtonRole.RejectRole) + + msgbox.setDefaultButton(bt_ok) + msgbox.exec() + response = msgbox.clickedButton() + + if response == bt_cancel: + return + else: + self.app.log.error("Legacy Project. Loading not supported.") + return + # Clear the current project # # NOT THREAD SAFE # ## if run_from_arg is True: @@ -11902,8 +11913,35 @@ class MenuFileHandlers(QtCore.QObject): else: self.on_file_new_project() - # Project options - self.app.options.update(d['options']) + if not run_from_arg or not cli or from_tcl is False: + msgbox = FCMessageBox(parent=self.app.ui) + title = _("Save preferences") + txt = _("Do you want to import the loaded project settings?") + msgbox.setWindowTitle(title) # taskbar still shows it + msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/flatcam_icon128.png')) + msgbox.setText('%s' % title) + msgbox.setInformativeText(txt) + msgbox.setIconPixmap(QtGui.QPixmap(self.app.resource_location + '/save_as.png')) + + bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.ButtonRole.YesRole) + bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.ButtonRole.NoRole) + # bt_cancel = msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.ButtonRole.RejectRole) + + msgbox.setDefaultButton(bt_yes) + msgbox.exec() + response = msgbox.clickedButton() + + if response == bt_yes: + # self.app.defaults.update(self.app.options) + # self.app.preferencesUiManager.save_defaults() + # Project options + self.app.options.update(d['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.project_filename = filename @@ -11916,12 +11954,6 @@ class MenuFileHandlers(QtCore.QObject): self.log.debug(" **************** Started PROEJCT loading... **************** ") for obj in d['objs']: - if 'cnc_tools' in obj or 'exc_cnc_tools' in obj: - self.app.log.error( - 'MenuFileHandlers.open_project() --> %s %s. %s' % - ("Failed to open the CNCJob file:", str(obj['options']['name']), "Maybe it is an old project.")) - continue - try: msg = "Recreating from opened project an %s object: %s" % \ (obj['kind'].capitalize(), obj['obj_options']['name']) @@ -11941,6 +11973,20 @@ class MenuFileHandlers(QtCore.QObject): app_inst.log.error('MenuFileHandlers.open_project() --> ' + str(erro)) return 'fail' + # ############################################################################################# + # for older projects loading try to convert the 'apertures' or 'cnc_tools' or 'exc_cnc_tools' + # attributes, if found, to 'tools' + # ############################################################################################# + # for older loaded projects + if 'apertures' in obj: + new_obj.__dict__['tools'] = obj['apertures'] + if 'cnc_tools' in obj: + new_obj.__dict__['tools'] = obj['cnc_tools'] + if 'exc_cnc_tools' in obj: + new_obj.__dict__['tools'] = obj['exc_cnc_tools'] + # ############################################################################################# + # ############################################################################################# + # try to make the keys in the tools dictionary to be integers # JSON serialization makes them strings # not all FlatCAM objects have the 'tools' dictionary attribute @@ -11948,6 +11994,11 @@ class MenuFileHandlers(QtCore.QObject): new_obj.tools = { int(tool): tool_dict for tool, tool_dict in list(new_obj.tools.items()) } + except ValueError: + # for older loaded projects + new_obj.tools = { + float(tool): tool_dict for tool, tool_dict in list(new_obj.tools.items()) + } except Exception as erro: app_inst.log.error('MenuFileHandlers.open_project() keys to int--> ' + str(erro)) return 'fail' @@ -11969,7 +12020,7 @@ class MenuFileHandlers(QtCore.QObject): # 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 inherit TclCommandSignaled) + # it's because the TclCommand is run in another thread (it inherits TclCommandSignaled) try: if cli is None: self.app.ui.set_ui_title(name="{} {}: {}".format(