# SPDX-License-Identifier: LGPL-2.1-or-later # *************************************************************************** # * Copyright (c) 2017 sliptonic * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * # * as published by the Free Software Foundation; either version 2 of * # * the License, or (at your option) any later version. * # * for detail see the LICENCE text file. * # * * # * 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 Library General Public License for more details. * # * * # * You should have received a copy of the GNU Library General Public * # * License along with this program; if not, write to the Free Software * # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * # * USA * # * * # *************************************************************************** from PySide import QtCore, QtGui from PySide.QtCore import QT_TRANSLATE_NOOP import FreeCAD import FreeCADGui import Path import Path.Main.Gui.JobDlg as PathJobDlg import Path.Main.Job as PathJob import Path.Main.Stock as PathStock import json import os translate = FreeCAD.Qt.translate if False: Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule()) Path.Log.trackModule(Path.Log.thisModule()) else: Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule()) class CommandJobCreate: """ Command used to create a command. When activated the command opens a dialog allowing the user to select a base object (has to be a solid) and a template to be used for the initial creation. """ def __init__(self): pass def GetResources(self): return { "Pixmap": "CAM_Job", "MenuText": QT_TRANSLATE_NOOP("CAM_Job", "New Job"), "Accel": "P, J", "ToolTip": QT_TRANSLATE_NOOP("CAM_Job", "Creates a CAM job"), } def IsActive(self): return FreeCAD.ActiveDocument is not None def Activated(self): dialog = PathJobDlg.JobCreate() dialog.setupTemplate() dialog.setupModel() if dialog.exec_() == 1: models = dialog.getModels() if models: self.Execute(models, dialog.getTemplate()) FreeCAD.ActiveDocument.recompute() @classmethod def Execute(cls, base, template): FreeCADGui.addModule("Path.Main.Gui.Job") if template: template = "'%s'" % template else: template = "None" FreeCADGui.doCommand( "Path.Main.Gui.Job.Create(%s, %s)" % ([o.Name for o in base], template) ) class CommandJobTemplateExport: """ Command to export a template of a given job. Opens a dialog to select the file to store the template in. If the template is stored in Path's file path (see preferences) and named in accordance with job_*.json it will automatically be found on Job creation and be available for selection. """ def __init__(self): pass def GetResources(self): return { "Pixmap": "CAM_ExportTemplate", "MenuText": QT_TRANSLATE_NOOP("CAM_ExportTemplate", "Export Template"), "ToolTip": QT_TRANSLATE_NOOP( "CAM_ExportTemplate", "Exports the CAM job as a template to be used for other jobs", ), } def GetJob(self): # if there's only one Job in the document ... jobs = PathJob.Instances() if not jobs: return None if len(jobs) == 1: return jobs[0] # more than one job, is one of them selected? sel = FreeCADGui.Selection.getSelection() if len(sel) == 1: job = sel[0] if hasattr(job, "Proxy") and isinstance(job.Proxy, PathJob.ObjectJob): return job return None def IsActive(self): return self.GetJob() is not None def Activated(self): job = self.GetJob() dialog = PathJobDlg.JobTemplateExport(job) if dialog.exec_() == 1: self.SaveDialog(job, dialog) @classmethod def SaveDialog(cls, job, dialog): foo = QtGui.QFileDialog.getSaveFileName( QtGui.QApplication.activeWindow(), "Path - Job Template", str(Path.Preferences.getTemplateDirectory()), "job_*.json", )[0] if foo: if not os.path.basename(foo).startswith("job_"): foo = os.path.join(os.path.dirname(foo), "job_" + os.path.basename(foo)) if not foo.endswith(".json"): foo = foo + ".json" cls.Execute(job, foo, dialog) @classmethod def Execute(cls, job, path, dialog=None): attrs = job.Proxy.templateAttrs(job) # post processor settings if dialog and not dialog.includePostProcessing(): attrs.pop(PathJob.JobTemplate.PostProcessor, None) attrs.pop(PathJob.JobTemplate.PostProcessorArgs, None) attrs.pop(PathJob.JobTemplate.PostProcessorOutputFile, None) # tool controller settings toolControllers = dialog.includeToolControllers() if dialog else job.Tools.Group if toolControllers: tcAttrs = [tc.Proxy.templateAttrs(tc) for tc in toolControllers] attrs[PathJob.JobTemplate.ToolController] = tcAttrs # stock settings stockAttrs = None if dialog: if dialog.includeStock(): stockAttrs = PathStock.TemplateAttributes( job.Stock, dialog.includeStockExtent(), dialog.includeStockPlacement(), ) else: stockAttrs = PathStock.TemplateAttributes(job.Stock) if stockAttrs: attrs[PathJob.JobTemplate.Stock] = stockAttrs # setup sheet setupSheetAttrs = None if dialog: setupSheetAttrs = job.Proxy.setupSheet.templateAttributes( dialog.includeSettingToolRapid(), dialog.includeSettingCoolant(), dialog.includeSettingOperationHeights(), dialog.includeSettingOperationDepths(), dialog.includeSettingOpsSettings(), ) else: setupSheetAttrs = job.Proxy.setupSheet.templateAttributes(True, True, True) if setupSheetAttrs: attrs[PathJob.JobTemplate.SetupSheet] = setupSheetAttrs encoded = job.Proxy.setupSheet.encodeTemplateAttributes(attrs) # write template with open(str(path), "w") as fp: json.dump(encoded, fp, sort_keys=True, indent=2) if FreeCAD.GuiUp: # register the FreeCAD command FreeCADGui.addCommand("CAM_Job", CommandJobCreate()) FreeCADGui.addCommand("CAM_ExportTemplate", CommandJobTemplateExport()) FreeCAD.Console.PrintLog("Loading PathJobCmd… done\n")