Added suppor for default OutputFile with templates and a policy on how to deal with file name conflicts.
This commit is contained in:
@@ -28,6 +28,7 @@ from PySide import QtCore, QtGui
|
||||
import os
|
||||
import glob
|
||||
from PathScripts.PathPostProcessor import PostProcessor
|
||||
from PathScripts.PathPost import CommandPathPost as PathPost
|
||||
import Draft
|
||||
|
||||
|
||||
@@ -47,12 +48,24 @@ except AttributeError:
|
||||
def translate(context, text, disambig=None):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
|
||||
class OutputPolicy:
|
||||
Default = 'Use default'
|
||||
Dialog = 'Open File Dialog'
|
||||
DialogOnConflict = 'Open File Dialog on conflict'
|
||||
Overwrite = 'Overwrite existing file'
|
||||
AppendID = 'Append Unique ID on conflict'
|
||||
All = [Default, Dialog, DialogOnConflict, Overwrite, AppendID]
|
||||
|
||||
class ObjectPathJob:
|
||||
|
||||
def __init__(self, obj):
|
||||
# obj.addProperty("App::PropertyFile", "PostProcessor", "CodeOutput", "Select the Post Processor file for this project")
|
||||
obj.addProperty("App::PropertyFile", "OutputFile", "CodeOutput", QtCore.QT_TRANSLATE_NOOP("App::Property","The NC output file for this project"))
|
||||
obj.OutputFile = PathPost.defaultOutputFile()
|
||||
obj.setEditorMode("OutputFile", 0) # set to default mode
|
||||
obj.addProperty("App::PropertyEnumeration", "OutputPolicy", "CodeOutput", QtCore.QT_TRANSLATE_NOOP("App::Property","The policy on how to save output files and resolve name conflicts"))
|
||||
obj.OutputPolicy = OutputPolicy.All
|
||||
obj.OutputPolicy = OutputPolicy.Default
|
||||
|
||||
obj.addProperty("App::PropertyString", "Description", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","An optional description for this job"))
|
||||
obj.addProperty("App::PropertyEnumeration", "PostProcessor", "Output", QtCore.QT_TRANSLATE_NOOP("App::Property","Select the Post Processor"))
|
||||
@@ -270,6 +283,8 @@ class TaskPanel:
|
||||
self.obj.Label = str(self.form.leLabel.text())
|
||||
if hasattr(self.obj, "OutputFile"):
|
||||
self.obj.OutputFile = str(self.form.leOutputFile.text())
|
||||
if hasattr(self.obj, "OutputPolicy"):
|
||||
self.obj.OutputPolicy = str(self.form.cboOutputPolicy.currentText())
|
||||
|
||||
oldlist = self.obj.Group
|
||||
newlist = []
|
||||
@@ -291,21 +306,23 @@ class TaskPanel:
|
||||
|
||||
self.obj.Proxy.execute(self.obj)
|
||||
|
||||
def selectComboBoxText(self, widget, text):
|
||||
index = widget.findText(text, QtCore.Qt.MatchFixedString)
|
||||
if index >= 0:
|
||||
widget.blockSignals(True)
|
||||
widget.setCurrentIndex(index)
|
||||
widget.blockSignals(False)
|
||||
|
||||
def setFields(self):
|
||||
'''sets fields in the form to match the object'''
|
||||
|
||||
self.form.leLabel.setText(self.obj.Label)
|
||||
self.form.leOutputFile.setText(self.obj.OutputFile)
|
||||
self.selectComboBoxText(self.form.cboOutputPolicy, self.obj.OutputPolicy)
|
||||
|
||||
postindex = self.form.cboPostProcessor.findText(
|
||||
self.obj.PostProcessor, QtCore.Qt.MatchFixedString)
|
||||
if postindex >= 0:
|
||||
self.form.cboPostProcessor.blockSignals(True)
|
||||
self.form.cboPostProcessor.setCurrentIndex(postindex)
|
||||
self.form.cboPostProcessor.blockSignals(False)
|
||||
# make sure the proxy loads post processor script values and settings
|
||||
self.obj.Proxy.onChanged(self.obj, "PostProcessor")
|
||||
self.updateTooltips()
|
||||
self.selectComboBoxText(self.form.cboPostProcessor, self.obj.PostProcessor)
|
||||
self.obj.Proxy.onChanged(self.obj, "PostProcessor")
|
||||
self.updateTooltips()
|
||||
|
||||
for child in self.obj.Group:
|
||||
self.form.PathsList.addItem(child.Name)
|
||||
@@ -335,6 +352,7 @@ class TaskPanel:
|
||||
# Connect Signals and Slots
|
||||
self.form.cboPostProcessor.currentIndexChanged.connect(self.getFields)
|
||||
self.form.leOutputFile.editingFinished.connect(self.getFields)
|
||||
self.form.cboOutputPolicy.currentIndexChanged.connect(self.getFields)
|
||||
self.form.leLabel.editingFinished.connect(self.getFields)
|
||||
self.form.btnSelectFile.clicked.connect(self.setFile)
|
||||
self.form.PathsList.indexesMoved.connect(self.getFields)
|
||||
|
||||
@@ -42,6 +42,85 @@ except AttributeError:
|
||||
|
||||
class CommandPathPost:
|
||||
|
||||
DefaultOutputFile = "DefaultOutputFile"
|
||||
DefaultOutputPolicy = "DefaultOutputPolicy"
|
||||
|
||||
@classmethod
|
||||
def saveDefaults(cls, path, policy):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
preferences.SetString(cls.DefaultOutputFile, path)
|
||||
preferences.SetString(cls.DefaultOutputPolicy, policy)
|
||||
|
||||
@classmethod
|
||||
def defaultOutputFile(cls):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
return preferences.GetString(cls.DefaultOutputFile, "")
|
||||
|
||||
@classmethod
|
||||
def defaultOutputPolicy(cls):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
return preferences.GetString(cls.DefaultOutputPolicy, "")
|
||||
|
||||
def resolveFileName(self, job):
|
||||
path = "tmp.tap"
|
||||
if job.OutputFile:
|
||||
path = job.OutputFile
|
||||
filename = path
|
||||
if '%D' in filename:
|
||||
D = FreeCAD.ActiveDocument.FileName
|
||||
if D:
|
||||
D = os.path.dirname(D)
|
||||
else:
|
||||
FreeCAD.Console.PrintError("Please save document in order to resolve output path!\n")
|
||||
return None
|
||||
filename = filename.replace('%D', D)
|
||||
|
||||
if '%d' in filename:
|
||||
d = FreeCAD.ActiveDocument.Label
|
||||
filename = filename.replace('%d', d)
|
||||
|
||||
if '%j' in filename:
|
||||
j = job.Label
|
||||
filename = filename.replace('%j', j)
|
||||
|
||||
if '%M' in filename:
|
||||
pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")
|
||||
M = pref.GetString("MacroPath", FreeCAD.getUserAppDataDir())
|
||||
filename = filename.replace('%M', M)
|
||||
|
||||
policy = job.OutputPolicy
|
||||
if not policy or policy == 'Use default':
|
||||
policy = self.defaultOutputPolicy()
|
||||
|
||||
openDialog = policy == 'Open File Dialog'
|
||||
if os.path.isdir(filename) or not os.path.isdir(os.path.dirname(filename)):
|
||||
# Either the entire filename resolves into a directory or the parent directory doesn't exist.
|
||||
# Either way I don't know what to do - ask for help
|
||||
openDialog = True
|
||||
|
||||
if os.path.isfile(filename) and not openDialog:
|
||||
if policy == 'Open File Dialog on conflict':
|
||||
openDialog = True
|
||||
elif policy == 'Append Unique ID on conflict':
|
||||
fn, ext = os.path.splitext(filename)
|
||||
nr = fn[-3:]
|
||||
n = 1
|
||||
if nr.isdigit():
|
||||
n = int(nr)
|
||||
while os.path.isfile("%s%03d%s" % (fn, n, ext)):
|
||||
n = n + 1
|
||||
filename = "%s%03d%s" % (fn, n, ext)
|
||||
|
||||
if openDialog:
|
||||
foo = QtGui.QFileDialog.getSaveFileName(QtGui.qApp.activeWindow(), "Output File", filename)
|
||||
if foo:
|
||||
filename = foo[0]
|
||||
else:
|
||||
filename = None
|
||||
|
||||
#print("resolveFileName(%s, %s) -> '%s'" % (path, policy, filename))
|
||||
return filename
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-Post',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Post", "Post Process"),
|
||||
@@ -64,7 +143,6 @@ class CommandPathPost:
|
||||
|
||||
# default to the dumper post and default .tap file
|
||||
postname = "dumper"
|
||||
filename = "tmp.tap"
|
||||
postArgs = ""
|
||||
|
||||
print "in activated %s" %(obj)
|
||||
@@ -73,7 +151,7 @@ class CommandPathPost:
|
||||
# output filename
|
||||
if hasattr(obj[0], "Group") and hasattr(obj[0], "Path"):
|
||||
# # Check for a selected post post processor if it's set
|
||||
proj = obj[0]
|
||||
job = obj[0]
|
||||
|
||||
if hasattr(obj[0], "PostProcessor"):
|
||||
postobj = obj[0]
|
||||
@@ -85,15 +163,17 @@ class CommandPathPost:
|
||||
lessextn = os.path.splitext(postobj.PostProcessor)[0]
|
||||
postname = os.path.split(lessextn)[1]
|
||||
|
||||
if proj.OutputFile:
|
||||
filename = proj.OutputFile
|
||||
if hasattr(postobj, "PostProcessorArgs"):
|
||||
postArgs = postobj.PostProcessorArgs
|
||||
|
||||
processor = PostProcessor.load(postname)
|
||||
processor.export(obj, filename, postArgs)
|
||||
filename = self.resolveFileName(job)
|
||||
if filename:
|
||||
processor = PostProcessor.load(postname)
|
||||
processor.export(obj, filename, postArgs)
|
||||
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
else:
|
||||
FreeCAD.ActiveDocument.abortTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
|
||||
@@ -26,6 +26,7 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
from PySide import QtCore, QtGui
|
||||
from PathScripts.PathPostProcessor import PostProcessor
|
||||
from PathScripts.PathPost import CommandPathPost as PathPost
|
||||
|
||||
|
||||
class Page:
|
||||
@@ -46,6 +47,17 @@ class Page:
|
||||
blacklist.append(item.text())
|
||||
PostProcessor.saveDefaults(processor, args, blacklist)
|
||||
|
||||
path = str(self.form.leOutputFile.text())
|
||||
policy = str(self.form.cboOutputPolicy.currentText())
|
||||
PathPost.saveDefaults(path, policy)
|
||||
|
||||
def selectComboEntry(self, widget, text):
|
||||
index = widget.findText(text, QtCore.Qt.MatchFixedString)
|
||||
if index >= 0:
|
||||
widget.blockSignals(True)
|
||||
widget.setCurrentIndex(index)
|
||||
widget.blockSignals(False)
|
||||
|
||||
def loadSettings(self):
|
||||
self.form.defaultPostProcessor.addItem("")
|
||||
blacklist = PostProcessor.blacklist()
|
||||
@@ -58,18 +70,15 @@ class Page:
|
||||
item.setCheckState(QtCore.Qt.CheckState.Checked)
|
||||
item.setFlags( QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled | QtCore.Qt.ItemFlag.ItemIsUserCheckable)
|
||||
self.form.postProcessorList.addItem(item)
|
||||
|
||||
postindex = self.form.defaultPostProcessor.findText(PostProcessor.default(), QtCore.Qt.MatchFixedString)
|
||||
|
||||
if postindex >= 0:
|
||||
self.form.defaultPostProcessor.blockSignals(True)
|
||||
self.form.defaultPostProcessor.setCurrentIndex(postindex)
|
||||
self.form.defaultPostProcessor.blockSignals(False)
|
||||
self.selectComboEntry(self.form.defaultPostProcessor, PostProcessor.default())
|
||||
|
||||
self.form.defaultPostProcessorArgs.setText(PostProcessor.defaultArgs())
|
||||
self.form.leOutputFile.setText(PathPost.defaultOutputFile())
|
||||
self.selectComboEntry(self.form.cboOutputPolicy, PathPost.defaultOutputPolicy())
|
||||
|
||||
self.form.postProcessorList.itemEntered.connect(self.setProcessorListTooltip)
|
||||
self.form.defaultPostProcessor.currentIndexChanged.connect(self.updateDefaultPostProcessorToolTip)
|
||||
self.form.browseFileSystem.clicked.connect(self.browseFileSystem)
|
||||
|
||||
def getPostProcessor(self, name):
|
||||
if not name in self.processor.keys():
|
||||
@@ -100,3 +109,8 @@ class Page:
|
||||
else:
|
||||
self.form.defaultPostProcessor.setToolTip(self.postProcessorDefaultTooltip)
|
||||
self.form.defaultPostProcessorArgs.setToolTip(self.postProcessorArgsDefaultTooltip)
|
||||
|
||||
def browseFileSystem(self):
|
||||
foo = QtGui.QFileDialog.getExistingDirectory(QtGui.qApp.activeWindow(), "Path - Output File/Directory", self.form.defaultOutputPath.text())
|
||||
if foo:
|
||||
self.form.defaultOutputPath.setText(foo)
|
||||
|
||||
Reference in New Issue
Block a user