diff --git a/CadQuery/Gui/ImportCQ.py b/CadQuery/Gui/ImportCQ.py index a16778d..f960528 100644 --- a/CadQuery/Gui/ImportCQ.py +++ b/CadQuery/Gui/ImportCQ.py @@ -1,26 +1,101 @@ """Adds the ability to open files from disk to the CadQuery FreeCAD module""" # (c) 2014 Jeremy Wright LGPL v3 +import os +import sys import FreeCAD, FreeCADGui from PySide import QtGui +import module_locator +import Settings #Distinguish python built-in open function from the one declared here if open.__module__ == '__builtin__': pythonopen = open +def AutoExecute(self): + """We should be able to pass the Gui.Commands.CadQueryExecuteScript function directly to the file_reloaded + connect function, but that causes a segfault in FreeCAD. This function is a work-around for that. This + function is passed to file_reloaded signal and in turn calls the CadQueryExecuteScript.Activated function.""" + import Gui.Command + + Gui.Command.CadQueryExecuteScript().Activated() + + def open(filename): #All of the Gui.* calls in the Python console break after opening if we don't do this FreeCADGui.doCommand("import FreeCADGui as Gui") + # 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(msg + "\r\n") + + # The extra version numbers won't work on Windows + if sys.platform.startswith('win'): + interpreter = 'python' + + # Set up so that we can import from our embedded packages + module_base_path = module_locator.module_path() + libs_dir_path = os.path.join(module_base_path, 'Libs') + sys.path.insert(0, libs_dir_path) + + from pyqode.core.modes import FileWatcherMode + from pyqode.core.modes import RightMarginMode + from pyqode.python.widgets import PyCodeEdit + + # Make sure we get the right libs under the FreeCAD installation + fc_base_path = os.path.dirname(os.path.dirname(module_base_path)) + fc_lib_path = os.path.join(fc_base_path, 'lib') + #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") + # The code editor can be displayed as a docked window or as a FreeCAD tab + if Settings.tabbed_mode: + # Set up the text area for our CQ code + server_path = os.path.join(module_base_path, 'cq_server.py') + + # Windows needs some extra help with paths + if sys.platform.startswith('win'): + codePane = PyCodeEdit(server_script=server_path, interpreter=interpreter + , args=['-s', fc_lib_path, libs_dir_path]) + else: + codePane = PyCodeEdit(server_script=server_path, interpreter=interpreter + , args=['-s', libs_dir_path]) + + # Allow easy use of an external editor + if Settings.use_external_editor: + codePane.modes.append(FileWatcherMode()) + codePane.modes.get(FileWatcherMode).file_reloaded.connect(AutoExecute) + codePane.modes.get(FileWatcherMode).auto_reload = True + + # Set the margin to be at 119 characters instead of 79 + codePane.modes.get(RightMarginMode).position = Settings.max_line_length + + codePane.setObjectName("cqCodePane") + + mdi = mw.findChild(QtGui.QMdiArea) + # add a widget to the mdi area + sub = mdi.addSubWindow(codePane) + sub.setWindowTitle('script_template') + sub.setWindowIcon(QtGui.QIcon(':/icons/applications-python.svg')) + sub.show() + mw.update() + else: + # We need this so we can load the file into it + codePane = mw.findChild(QtGui.QPlainTextEdit, "cqCodePane") #Pull the text of the CQ script file into our code pane - cqCodePane.file.open(filename) + codePane.file.open(filename) msg = QtGui.QApplication.translate( "cqCodeWidget", diff --git a/CadQuery/InitGui.py b/CadQuery/InitGui.py index 5b7ce8c..ec2fc1c 100644 --- a/CadQuery/InitGui.py +++ b/CadQuery/InitGui.py @@ -68,8 +68,6 @@ class CadQueryWorkbench (Workbench): sys.path.insert(1, fc_bin_path) import cadquery - from pyqode.core.modes import FileWatcherMode - from pyqode.python.widgets import PyCodeEdit from PySide import QtGui, QtCore msg = QtGui.QApplication.translate( @@ -84,23 +82,6 @@ class CadQueryWorkbench (Workbench): QtGui.QApplication.UnicodeUTF8) FreeCAD.Console.PrintMessage(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(msg + "\r\n") - - #The extra version numbers won't work on Windows - if sys.platform.startswith('win'): - interpreter = 'python' - #Getting the main window will allow us to start setting things up the way we want mw = FreeCADGui.getMainWindow() @@ -110,66 +91,11 @@ class CadQueryWorkbench (Workbench): if widget.objectName() == "Report view": 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 - server_path = os.path.join(module_base_path, 'cq_server.py') - - #Windows needs some extra help with paths - if sys.platform.startswith('win'): - codePane = PyCodeEdit(server_script=server_path, interpreter=interpreter - , args=['-s', fc_lib_path, libs_dir_path]) - else: - codePane = PyCodeEdit(server_script=server_path, interpreter=interpreter - , args=['-s', libs_dir_path]) - - # Allow easy use of an external editor - if Settings.use_external_editor: - codePane.modes.append(FileWatcherMode()) - codePane.modes.get(FileWatcherMode).file_reloaded.connect(self.AutoExecute) - codePane.modes.get(FileWatcherMode).auto_reload = True - - codePane.setObjectName("cqCodePane") - - #Add the text area to our dock widget - cqCodeWidget.setWidget(codePane) - - #Set up the paths to allow us to open and execute our introduction example - #example_path = os.path.join(module_base_path, 'Examples') - #example_path = os.path.join(example_path, 'Ex000_Introduction.py') - - # TODO: Enable this for FreeCAD 0.16 or greater - # Make sure we get the correct MdiArea object - # for child in mw.children(): - # if child.__class__ == QtGui.QMdiArea: - # mdiArea = child - # - # # Set up the editor in a new subwindow - # #sub_window = QtGui.QMdiSubWindow(mw.centralWidget()) - # sub_window = QtGui.QMdiSubWindow(mdiArea) - # #sub_window.setWidget(codePane) - # sub_window.setWidget(QtGui.QPlainTextEdit()) - # sub_window.setWindowTitle('Ex000_Introduction.py') - # sub_window.setWindowIcon(QtGui.QIcon(':/icons/applications-python.svg')) - # - # #mw.centralWidget().addSubWindow(sub_window) - # mdiArea.addSubWindow(sub_window) - # Set up the paths to allow us to open the template template_path = os.path.join(module_base_path, 'Templates') template_path = os.path.join(template_path, 'script_template.py') ImportCQ.open(template_path) - docname = os.path.splitext(os.path.basename(template_path))[0] - #FreeCAD.newDocument(docname) - #Command.CadQueryExecuteScript().Activated() - - #Get a nice view of our example - #FreeCADGui.activeDocument().activeView().viewAxometric() - #FreeCADGui.SendMsgToActiveView("ViewFit") def AutoExecute(self): """We should be able to pass the Gui.Commands.CadQueryExecuteScript function directly to the file_reloaded diff --git a/CadQuery/Settings.py b/CadQuery/Settings.py index e7571ce..aef8290 100644 --- a/CadQuery/Settings.py +++ b/CadQuery/Settings.py @@ -1,2 +1,4 @@ execute_on_save = False # Automatically execute a script every time you save -use_external_editor = False # Automatically reloads and executes a file when an external change is made \ No newline at end of file +use_external_editor = False # Automatically reloads and executes a file when an external change is made +max_line_length = 79 # The number of characters per line that is allowed before a warning is given +tabbed_mode = True # Whether or not the editor should make use of FreeCAD tabs \ No newline at end of file