From 64a06fe3576e70cb5f7b8dcde28b2d57c7f442e6 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sat, 22 Dec 2018 07:12:16 -0500 Subject: [PATCH] Added the ability for the code editor to reload the contents of a changed file from disk. --- CQGui/ExportCQ.py | 6 +----- CQGui/ImportCQ.py | 40 ++++++++++++++++------------------------ CodeEditor.py | 34 ++++++++++++++++++++++++++++++++++ Init.py | 4 ++-- changes.md | 10 ++++++++++ 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/CQGui/ExportCQ.py b/CQGui/ExportCQ.py index b28e31c..f148d8d 100644 --- a/CQGui/ExportCQ.py +++ b/CQGui/ExportCQ.py @@ -17,11 +17,7 @@ def save(filename=None): #Grab our code editor so we can interact with it cqCodePane = Shared.getActiveCodePane() - #If we weren't provided a file name, we need to find it from the text field - if filename is None: - cqCodePane.save() - else: - cqCodePane.save(filename) + cqCodePane.save(filename) msg = QtGui.QApplication.translate( "cqCodeWidget", diff --git a/CQGui/ImportCQ.py b/CQGui/ImportCQ.py index 803077c..946a41a 100644 --- a/CQGui/ImportCQ.py +++ b/CQGui/ImportCQ.py @@ -4,6 +4,7 @@ import os import sys import FreeCAD, FreeCADGui from PySide import QtGui +from PySide import QtCore import module_locator from CodeEditor import CodeEditor @@ -49,33 +50,24 @@ def open(filename): # Grab just the file name from the path/file that's being executed docname = os.path.basename(filename) - # Set up the text area for our CQ code - # server_path = os.path.join(module_base_path, 'cq_server.py') + # Pull the font size from the FreeCAD-stored settings + fontSize = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").GetInt("fontSize") - use_external_editor = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").GetBool("useExternalEditor") + # Set up the code editor + codePane = CodeEditor() + codePane.setFont(QtGui.QFont('SansSerif', fontSize)) + codePane.setObjectName("cqCodePane_" + os.path.splitext(os.path.basename(filename))[0]) - # If the user wants to use an external editor, don't bother with the built-in editor - if use_external_editor: - pass - else: - # Pull the font size from the FreeCAD-stored settings - fontSize = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").GetInt("fontSize") + mdi = mw.findChild(QtGui.QMdiArea) + # add a code editor widget to the mdi area + sub = mdi.addSubWindow(codePane) + sub.setWindowTitle(docname) + sub.setWindowIcon(QtGui.QIcon(':/icons/applications-python.svg')) + sub.show() + mw.update() - # Set up the code editor - codePane = CodeEditor() - codePane.setFont(QtGui.QFont('SansSerif', fontSize)) - codePane.setObjectName("cqCodePane_" + os.path.splitext(os.path.basename(filename))[0]) - - mdi = mw.findChild(QtGui.QMdiArea) - # add a code editor widget to the mdi area - sub = mdi.addSubWindow(codePane) - sub.setWindowTitle(docname) - sub.setWindowIcon(QtGui.QIcon(':/icons/applications-python.svg')) - sub.show() - mw.update() - - #Pull the text of the CQ script file into our code pane - codePane.open(filename) + #Pull the text of the CQ script file into our code pane + codePane.open(filename) msg = QtGui.QApplication.translate( "cqCodeWidget", diff --git a/CodeEditor.py b/CodeEditor.py index 8d6265c..21bb6ef 100644 --- a/CodeEditor.py +++ b/CodeEditor.py @@ -1,3 +1,4 @@ +import os.path import FreeCAD from PySide import QtCore from PySide.QtCore import QSize, QRect, Qt, QRegExp @@ -95,8 +96,33 @@ class CodeEditor(QPlainTextEdit): self.setPlainText(self.file_contents) + self.parent_dir = os.path.abspath(os.path.join(self.file_path, os.pardir)) + + # Watch the file we've opened + self.fileSysWatcher = QtCore.QFileSystemWatcher() + self.fileSysWatcher.addPath(self.parent_dir) + QtCore.QObject.connect(self.fileSysWatcher, QtCore.SIGNAL("directoryChanged(QString)"), self, QtCore.SLOT("slotDirChanged(QString)")) + + # Reloads the content of the open file if the contents on disk change + def reload(self): + with open(self.file_path) as f: self.file_contents = f.read() + + self.setPlainText(self.file_contents) + + # Tells whether or not the contents of the file we're working with has changed + def changedOnDisk(self): + with open(self.file_path) as f: file_contents = f.read() + + if file_contents != self.file_contents: + return True + else: + return False + # Saves the text in the code editor to a file def save(self, filename): + if filename == None: + filename = self.file_path + with open(filename, "w") as code_file: code_file.write(self.toPlainText()) @@ -135,6 +161,14 @@ class CodeEditor(QPlainTextEdit): extraSelections.append(selection) self.setExtraSelections(extraSelections) + @QtCore.Slot("QString") + def slotDirChanged(self, path): + # Make sure that the contents of our file actually changed + if self.changedOnDisk(): + FreeCAD.Console.PrintMessage("Contents of " + self.file_path + " changed, reloading \r\n") + + self.reload() + def keyPressEvent(self,event): self.dirty = True customKey=False diff --git a/Init.py b/Init.py index 0d9f7eb..9914c11 100644 --- a/Init.py +++ b/Init.py @@ -36,11 +36,11 @@ if os.path.exists(fc_bin_path): has_run_before = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").GetBool("runBefore") if not has_run_before: - FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetBool("useExternalEditor", False) FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetInt("fontSize", 12) FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetString("executeKeybinding", "F9") - FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetBool("executeOnSave", False) + FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetBool("executeOnSave", True) FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetBool("showLineNumbers", True) + # FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetBool("useExternalEditor", False) # Make sure we don't overwrite someone's existing settings FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/cadquery-freecad-module").SetBool("runBefore", True) \ No newline at end of file diff --git a/changes.md b/changes.md index e900204..c8eee0d 100644 --- a/changes.md +++ b/changes.md @@ -1,6 +1,16 @@ Changes ======= +v1.3.0 +----- + * PyQode editor has been replaced by a custom editor due to compatibility problems with Qt5/PySide 2 + * Settings have now been moved into FreeCAD user parameters + * Execute-on-save setting is now on by default + * Execute-script key has been changed to F9 to avoid conflicts with FreeCAD's F2, but key is still configurable + * New code editor automatically reloads contents of script file if changed on disk, enabling use of external editor by default + * Setting added to show/hide line numbers in code editor + * Default font size for code editor changed to 12, but size is still configurable + v1.2.0 ----- * Made a copy of the PyQode editor which is abandoned, so that a custom version can be maintained here