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 \x0a \x0a \x0a \x0a image/svg+xml\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a Q\x0a C\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 @@ + + + + + + + + + image/svg+xml + + + + + + + + Q + C + + + 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 @@ + + + + + + + + + + image/svg+xml + + + + + + + Q C + 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