diff --git a/CadQuery/CadQuery_rc.py b/CadQuery/CadQuery_rc.py
new file mode 100644
index 0000000..ce3a5d7
--- /dev/null
+++ b/CadQuery/CadQuery_rc.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created: Mon Nov 17 14:44:25 2014
+# by: The Resource Compiler for PySide (Qt v4.8.4)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PySide import QtCore
+
+qt_resource_data = "\x00\x00\x07\x19\x0a\x0a\x0a\x0a"
+qt_resource_name = "\x00\x05\x00o\xa6S\x00i\x00c\x00o\x00n\x00s\x00\x0b\x05r\xb2\xa7\x00C\x00Q\x00_\x00L\x00o\x00g\x00o\x00.\x00s\x00v\x00g"
+qt_resource_struct = "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+def qInitResources():
+ QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/CadQuery/CadQuery_rc.pyc b/CadQuery/CadQuery_rc.pyc
new file mode 100644
index 0000000..9944b21
Binary files /dev/null and b/CadQuery/CadQuery_rc.pyc differ
diff --git a/CadQuery/Gui/CadQueryGui.py b/CadQuery/Gui/CadQueryGui.py
new file mode 100644
index 0000000..7fc4078
--- /dev/null
+++ b/CadQuery/Gui/CadQueryGui.py
@@ -0,0 +1,3 @@
+class CadQueryGui():
+ def __workbench__(self):
+ pass
\ No newline at end of file
diff --git a/CadQuery/Gui/CadQueryGui.pyc b/CadQuery/Gui/CadQueryGui.pyc
new file mode 100644
index 0000000..4388c32
Binary files /dev/null and b/CadQuery/Gui/CadQueryGui.pyc differ
diff --git a/CadQuery/Gui/Command.py b/CadQuery/Gui/Command.py
new file mode 100644
index 0000000..06236ab
--- /dev/null
+++ b/CadQuery/Gui/Command.py
@@ -0,0 +1,188 @@
+import tempfile
+import FreeCAD, FreeCADGui
+from PySide import QtGui
+import ExportCQ, ImportCQ, CadQuery_rc
+
+#Distinguish python built-in open function from the one declared here
+if open.__module__ == '__builtin__':
+ pythonopen = open
+
+
+def clearAll():
+ doc = FreeCAD.ActiveDocument
+
+ #Make sure we have an active document to work with
+ if doc is not None:
+ for obj in doc.Objects:
+ doc.removeObject(obj.Label)
+
+
+class CadQueryCloseScript:
+ """Allows the user to close a file without saving"""
+
+ def GetResources(self):
+ return {"MenuText": "Close Script",
+ "ToolTip": "Closes the CadQuery script"}
+
+ def IsActive(self):
+ return True
+
+ def Activated(self):
+ #Getting the main window will allow us to find the children we need to work with
+ mw = FreeCADGui.getMainWindow()
+
+ #We need this so we can load the file into it
+ cqCodePane = mw.findChild(QtGui.QPlainTextEdit, "cqCodePane")
+
+ reply = QtGui.QMessageBox.question(cqCodePane, "QMessageBox.question()", "Save script before closing?", QtGui.QMessageBox.Yes |
+ QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel)
+
+ if reply == QtGui.QMessageBox.Cancel:
+ return
+
+ if reply == QtGui.QMessageBox.Yes:
+ #If we've got a file name already save it there, otherwise give a save-as dialog
+ if len(cqCodePane.file.path) == 0:
+ filename = QtGui.QFileDialog.getSaveFileName(mw, mw.tr("Save CadQuery Script As"), "/home/",
+ mw.tr("CadQuery Files (*.py)"))
+ else:
+ filename = cqCodePane.file.path
+
+ #Make sure we got a valid file name
+ if filename == None:
+ ExportCQ.save(filename)
+
+ #Clear our script and whatever was rendered by it out
+ cqCodePane.file.close()
+ clearAll()
+
+
+class CadQueryExecuteScript:
+ """CadQuery's command to execute a script file"""
+
+ def GetResources(self):
+ return {"MenuText": "Execute Script",
+ "Accel": "F2",
+ "ToolTip": "Executes the CadQuery script",
+ "Pixmap": ":/icons/macro-execute.svg"}
+
+ def IsActive(self):
+ return True
+ # if FreeCAD.ActiveDocument is None:
+ # return False
+ # else:
+ # return True
+
+ def Activated(self):
+ #Getting the main window will allow us to find the children we need to work with
+ mw = FreeCADGui.getMainWindow()
+
+ #We need this so we can load the file into it
+ cqCodePane = mw.findChild(QtGui.QPlainTextEdit, "cqCodePane")
+
+ clearAll()
+
+ #Save our code to a tempfile and render it
+ tempFile = tempfile.NamedTemporaryFile(delete=False)
+ tempFile.write(cqCodePane.toPlainText())
+ tempFile.close()
+ FreeCAD.Console.PrintMessage("\r\n")
+ execfile(tempFile.name)
+
+ msg = QtGui.QApplication.translate(
+ "cqCodeWidget",
+ "Executed ",
+ None,
+ QtGui.QApplication.UnicodeUTF8)
+ FreeCAD.Console.PrintMessage("\r\n" + msg + cqCodePane.file.path)
+
+
+class CadQueryOpenScript():
+ """CadQuery's command to open a script file."""
+ previousPath = None
+
+ def GetResources(self):
+ return {"MenuText": "Open Script",
+ "Accel": "Alt+O",
+ "ToolTip": "Opens a CadQuery script from disk",
+ "Pixmap": ":/icons/document-open.svg"}
+
+ def IsActive(self):
+ return True
+ # if FreeCAD.ActiveDocument is None:
+ # return False
+ # else:
+ # return True
+
+ def Activated(self):
+ mw = FreeCADGui.getMainWindow()
+
+ #Try to keep track of the previous path used to open as a convenience to the user
+ if self.previousPath is None:
+ self.previousPath = "/home/"
+
+ filename = QtGui.QFileDialog.getOpenFileName(mw, mw.tr("Open CadQuery Script"), self.previousPath,
+ mw.tr("CadQuery Files (*.py)"))
+
+ self.previousPath = filename[0]
+
+ #Make sure the user didn't click cancel
+ if filename[0]:
+ #We've created a library that FreeCAD can use as well to open CQ files
+ ImportCQ.open(filename[0])
+
+
+class CadQuerySaveScript:
+ """CadQuery's command to save a script file"""
+
+ def GetResources(self):
+ return {"MenuText": "Save Script",
+ "Accel": "Alt+S",
+ "ToolTip": "Saves the CadQuery script to disk",
+ "Pixmap": ":/icons/document-save.svg"}
+
+ def IsActive(self):
+ return True
+ # if FreeCAD.ActiveDocument is None:
+ # return False
+ # else:
+ # return True
+
+ def Activated(self):
+ #Rely on our export library to help us save the file
+ ExportCQ.save()
+
+class CadQuerySaveAsScript:
+ """CadQuery's command to save-as a script file"""
+ previousPath = None
+
+ def GetResources(self):
+ return {"MenuText": "Save Script As",
+ "Accel": "",
+ "ToolTip": "Saves the CadQuery script to disk in a location other than the original",
+ "Pixmap": ":/icons/document-save-as.svg"}
+
+ def IsActive(self):
+ return True
+ # if FreeCAD.ActiveDocument is None:
+ # return False
+ # else:
+ # return True
+
+ def Activated(self):
+ mw = FreeCADGui.getMainWindow()
+
+ #Try to keep track of the previous path used to open as a convenience to the user
+ if self.previousPath is None:
+ self.previousPath = "/home/"
+
+ filename = QtGui.QFileDialog.getSaveFileName(mw, mw.tr("Save CadQuery Script As"), self.previousPath,
+ mw.tr("CadQuery Files (*.py)"))
+
+ self.previousPath = filename[0]
+
+ #Make sure the user didn't click cancel
+ if filename[0]:
+ #Save the file before the re-render
+ ExportCQ.save(filename[0])
+ execfile(filename[0])
\ No newline at end of file
diff --git a/CadQuery/Gui/Command.pyc b/CadQuery/Gui/Command.pyc
new file mode 100644
index 0000000..f236545
Binary files /dev/null and b/CadQuery/Gui/Command.pyc differ
diff --git a/CadQuery/Gui/ExportCQ.py b/CadQuery/Gui/ExportCQ.py
new file mode 100644
index 0000000..bc08663
--- /dev/null
+++ b/CadQuery/Gui/ExportCQ.py
@@ -0,0 +1,30 @@
+import FreeCAD, FreeCADGui
+from PySide import QtGui
+
+def export(self, filename):
+ save(filename)
+
+def save(filename=None):
+ """
+ Allows us to save the CQ script file to disk.
+ :param filename: The path and file name to save to. If not provided we try to pull it from the code pane itself
+ """
+
+ #Getting the main window will allow us to find the children we need to work with
+ mw = FreeCADGui.getMainWindow()
+
+ #We need this so we can load the file into it
+ cqCodePane = mw.findChild(QtGui.QPlainTextEdit, "cqCodePane")
+
+ #If we weren't provided a file name, we need to find it from the text field
+ if filename is None:
+ cqCodePane.file.save()
+ else:
+ cqCodePane.file.save(filename)
+
+ msg = QtGui.QApplication.translate(
+ "cqCodeWidget",
+ "Saved ",
+ None,
+ QtGui.QApplication.UnicodeUTF8)
+ FreeCAD.Console.PrintMessage("\r\n" + msg + cqCodePane.file.path)
diff --git a/CadQuery/Gui/ExportCQ.pyc b/CadQuery/Gui/ExportCQ.pyc
new file mode 100644
index 0000000..c6b87e6
Binary files /dev/null and b/CadQuery/Gui/ExportCQ.pyc differ
diff --git a/CadQuery/Gui/ImportCQ.py b/CadQuery/Gui/ImportCQ.py
new file mode 100644
index 0000000..86342bc
--- /dev/null
+++ b/CadQuery/Gui/ImportCQ.py
@@ -0,0 +1,33 @@
+import os, FreeCAD, FreeCADGui
+from PySide import QtGui
+
+#Distinguish python built-in open function from the one declared here
+if open.__module__ == '__builtin__':
+ pythonopen = open
+
+def open(filename):
+ docname = os.path.splitext(os.path.basename(filename))[0]
+ doc = FreeCAD.newDocument(docname)
+
+ #All of the Gui.* calls in the Python console break after opening if we don't do this
+ FreeCADGui.doCommand("import FreeCADGui as Gui")
+
+ #Getting the main window will allow us to find the children we need to work with
+ mw = FreeCADGui.getMainWindow()
+
+ #We need this so we can load the file into it
+ cqCodePane = mw.findChild(QtGui.QPlainTextEdit, "cqCodePane")
+
+ #Pull the text of the CQ script file into our code pane
+ cqCodePane.file.open(filename)
+
+ execfile(filename)
+
+ msg = QtGui.QApplication.translate(
+ "cqCodeWidget",
+ "Opened ",
+ None,
+ QtGui.QApplication.UnicodeUTF8)
+ FreeCAD.Console.PrintMessage("\r\n" + msg + filename)
+
+ return doc
\ No newline at end of file
diff --git a/CadQuery/Gui/ImportCQ.pyc b/CadQuery/Gui/ImportCQ.pyc
new file mode 100644
index 0000000..292883e
Binary files /dev/null and b/CadQuery/Gui/ImportCQ.pyc differ
diff --git a/CadQuery/Gui/Resources/CadQuery.qrc b/CadQuery/Gui/Resources/CadQuery.qrc
new file mode 100644
index 0000000..0d6305a
--- /dev/null
+++ b/CadQuery/Gui/Resources/CadQuery.qrc
@@ -0,0 +1,5 @@
+
+
+ icons/CQ_Logo.svg
+
+
diff --git a/CadQuery/Gui/Resources/icons/CQ_Logo.svg b/CadQuery/Gui/Resources/icons/CQ_Logo.svg
new file mode 100644
index 0000000..b50ce53
--- /dev/null
+++ b/CadQuery/Gui/Resources/icons/CQ_Logo.svg
@@ -0,0 +1,56 @@
+
+
+
+
diff --git a/CadQuery/Gui/Resources/icons/CQ_Logo.svg~ b/CadQuery/Gui/Resources/icons/CQ_Logo.svg~
new file mode 100644
index 0000000..03044a8
--- /dev/null
+++ b/CadQuery/Gui/Resources/icons/CQ_Logo.svg~
@@ -0,0 +1,82 @@
+
+
+
+
diff --git a/CadQuery/Gui/__init__.py b/CadQuery/Gui/__init__.py
new file mode 100644
index 0000000..3df9393
--- /dev/null
+++ b/CadQuery/Gui/__init__.py
@@ -0,0 +1 @@
+__author__ = 'jwright'
diff --git a/CadQuery/Gui/__init__.pyc b/CadQuery/Gui/__init__.pyc
new file mode 100644
index 0000000..002d01d
Binary files /dev/null and b/CadQuery/Gui/__init__.pyc differ
diff --git a/CadQuery/Init.py b/CadQuery/Init.py
new file mode 100644
index 0000000..c40f1e4
--- /dev/null
+++ b/CadQuery/Init.py
@@ -0,0 +1,2 @@
+# FreeCAD init script of the CadQuery module
+# (c) 2001 Juergen Riegel LGPL
\ No newline at end of file
diff --git a/CadQuery/Init.pyc b/CadQuery/Init.pyc
new file mode 100644
index 0000000..376e9f7
Binary files /dev/null and b/CadQuery/Init.pyc differ
diff --git a/CadQuery/InitGui.py b/CadQuery/InitGui.py
new file mode 100644
index 0000000..eb7a23f
--- /dev/null
+++ b/CadQuery/InitGui.py
@@ -0,0 +1,139 @@
+# CadQuery gui init module
+# (c) 2001 Juergen Riegel LGPL
+import FreeCAD
+import FreeCADGui
+from Gui.Command import *
+
+class CadQueryWorkbench (Workbench):
+ """CadQuery workbench object"""
+ MenuText = "CadQuery"
+ ToolTip = "CadQuery workbench"
+ Icon = ":/icons/CQ_Logo.svg"
+
+ #Keeps track of which workbenches we have hidden so we can reshow them
+ closedWidgets = []
+
+ def Initialize(self):
+ import os
+ os.environ['QT_API'] = 'pyside'
+
+ #If we need a CQ menu, this would be the way to add it
+ commands = ['CadQueryOpenScript', 'CadQuerySaveScript', 'CadQuerySaveAsScript', 'CadQueryExecuteScript',
+ 'CadQueryCloseScript']
+ self.appendMenu('CadQuery', commands)
+
+ def Activated(self):
+ import cadquery
+ from PySide import QtGui
+ import sys
+
+ msg = QtGui.QApplication.translate(
+ "cqCodeWidget",
+ "CadQuery " + cadquery.__version__ + "\r\n"
+ "CadQuery is a parametric scripting language "
+ "for creating and traversing CAD models\r\n"
+ "Author: David Cowden\r\n"
+ "License: LGPL\r\n"
+ "Website: https://github.com/dcowden/cadquery\r\n",
+ None,
+ QtGui.QApplication.UnicodeUTF8)
+ FreeCAD.Console.PrintMessage(msg)
+
+ from PySide import QtGui
+ from PySide import QtCore
+
+ FreeCAD.addImportType("CadQuery Script (*.py)", "Gui.ImportCQ")
+ FreeCAD.addExportType("CadQuery Script (*.py)", "Gui.ExportCQ")
+
+ try:
+ import cadquery
+ except ImportError:
+ msg = QtGui.QApplication.translate(
+ "cqCodeWidget",
+ "The cadquery library is not installed, please install it before using this workbench.\r\n"
+ "Linux and MacOS Users: 'pip install --upgrade cadquery'\r\n"
+ "Windows Users: 'Not sure yet.\r\n",
+ None,
+ QtGui.QApplication.UnicodeUTF8)
+ FreeCAD.Console.PrintError(msg)
+
+ try:
+ from pyqode.qt import QtWidgets
+ from pyqode.python.backend import server
+ from pyqode.python.widgets import PyCodeEdit
+ from pyqode.python.widgets import code_edit
+
+ except ImportError:
+ msg = QtGui.QApplication.translate(
+ "cqCodeWidget",
+ "The pyQode library is not installed, please install it before using this workbench.\r\n"
+ "Linux and MacOS Users: 'pip install --upgrade pyqode.core pyqode.qt pyqode.python'\r\n",
+ None,
+ QtGui.QApplication.UnicodeUTF8)
+ FreeCAD.Console.PrintError(msg)
+
+ #Make sure that we enforce a specific version (2.7) of the Python interpreter
+ ver = hex(sys.hexversion)
+ interpreter = "python%s.%s" % (ver[2], ver[4]) # => 'python2.7'
+
+ #If the user doesn't have Python 2.7, warn them
+ if interpreter != 'python2.7':
+ msg = QtGui.QApplication.translate(
+ "cqCodeWidget",
+ "Please install Python 2.7",
+ None,
+ QtGui.QApplication.UnicodeUTF8)
+ FreeCAD.Console.PrintError("\r\n" + msg)
+
+ #Getting the main window will allow us to start setting things up the way we want
+ mw = Gui.getMainWindow()
+
+ #Find all of the docks that are open so we can close them (except the Python console)
+ dockWidgets = mw.findChildren(QtGui.QDockWidget)
+
+ for widget in dockWidgets:
+ if widget.objectName() != "Report view":
+ #FreeCAD.Console.PrintMessage(str(widget.objectName()) + " is being hidden.\n")
+
+ #Only hide the widget if it isn't already hidden
+ if not widget.isHidden():
+ widget.setVisible(False)
+ FreeCAD.Console.PrintMessage(widget.objectName())
+ self.closedWidgets.append(widget)
+ else:
+ widget.setVisible(True)
+
+ #Add a new widget here that's a simple text area to begin with. It will become the CQ coding area
+ cqCodeWidget = QtGui.QDockWidget("CadQuery Code View")
+ cqCodeWidget.setObjectName("cqCodeView")
+ mw.addDockWidget(QtCore.Qt.LeftDockWidgetArea, cqCodeWidget)
+
+ #Set up the text area for our CQ code
+ codePane = PyCodeEdit(server_script=server.__file__, interpreter=interpreter)
+ codePane.setObjectName("cqCodePane")
+
+ #Add the text area to our dock widget
+ cqCodeWidget.setWidget(codePane)
+
+ def Deactivated(self):
+ from PySide import QtGui
+ from Gui import ExportCQ
+
+ #Put the UI back the way we found it
+ FreeCAD.Console.PrintMessage("\r\nCadQuery Workbench Deactivated\r\n")
+
+ #Rely on our export library to help us save the file
+ ExportCQ.save()
+
+ #TODO: This won't work for now because the views are destroyed when they are hidden
+ for widget in self.closedWidgets:
+ FreeCAD.Console.PrintMessage(widget.objectName())
+ #widget.setVisible(True)
+
+FreeCADGui.addCommand('CadQueryOpenScript', CadQueryOpenScript())
+FreeCADGui.addCommand('CadQuerySaveScript', CadQuerySaveScript())
+FreeCADGui.addCommand('CadQuerySaveAsScript', CadQuerySaveAsScript())
+FreeCADGui.addCommand('CadQueryExecuteScript', CadQueryExecuteScript())
+FreeCADGui.addCommand('CadQueryCloseScript', CadQueryCloseScript())
+
+FreeCADGui.addWorkbench(CadQueryWorkbench())
diff --git a/CadQuery/InitGui.pyc b/CadQuery/InitGui.pyc
new file mode 100644
index 0000000..ec50806
Binary files /dev/null and b/CadQuery/InitGui.pyc differ
diff --git a/CadQuery/__init__.py b/CadQuery/__init__.py
new file mode 100644
index 0000000..3df9393
--- /dev/null
+++ b/CadQuery/__init__.py
@@ -0,0 +1 @@
+__author__ = 'jwright'
diff --git a/CadQuery/__init__.pyc b/CadQuery/__init__.pyc
new file mode 100644
index 0000000..a3fcc47
Binary files /dev/null and b/CadQuery/__init__.pyc differ