diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9d0fc19..4800f47c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,8 @@ CHANGELOG for FlatCAM beta
- some PEP changes, some method descriptions updated
- added a placeholder text to 2Sided Tool
+- added a new menu entry in the context menu of the Tcl Shell: 'Save Log' which will save the content of the Tcl Shell browser window to a file
+
23.04.2020
diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index cb5a7f0d..eeddfbfd 100644
--- a/FlatCAMApp.py
+++ b/FlatCAMApp.py
@@ -3971,7 +3971,7 @@ class App(QtCore.QObject):
self.date = ''.join(c for c in self.date if c not in ':-')
self.date = self.date.replace(' ', '_')
- filter__ = "Config File (*.FlatConfig);;All Files (*.*)"
+ filter__ = "Config File .FlatConfig (*.FlatConfig);;All Files (*.*)"
try:
filename, _f = FCFileSaveDialog.get_saved_filename(
caption=_("Export FlatCAM Preferences"),
@@ -4032,6 +4032,67 @@ class App(QtCore.QObject):
self.file_saved.emit("preferences", filename)
self.inform.emit('[success] %s: %s' % (_("Exported preferences to"), filename))
+ def save_to_file(self, content_to_save):
+ """
+ Save something to a file.
+
+ :return: None
+ """
+ self.report_usage("save_to_file")
+ App.log.debug("save_to_file()")
+
+ self.date = str(datetime.today()).rpartition('.')[0]
+ self.date = ''.join(c for c in self.date if c not in ':-')
+ self.date = self.date.replace(' ', '_')
+
+ filter__ = "HTML File .html (*.html);;All Files (*.*)"
+ path_to_save = self.defaults["global_last_save_folder"] if\
+ self.defaults["global_last_save_folder"] is not None else self.data_path
+ try:
+ filename, _f = FCFileSaveDialog.get_saved_filename(
+ caption=_("Save to file"),
+ directory=path_to_save + '/file_' + self.date,
+ filter=filter__
+ )
+ except TypeError:
+ filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save to file"), filter=filter__)
+
+ filename = str(filename)
+
+ if filename == "":
+ self.inform.emit('[WARNING_NOTCL] %s' % _("Saving to file cancelled."))
+ return
+ else:
+ try:
+ f = open(filename, 'w')
+ defaults_file_content = f.read()
+ f.close()
+ except PermissionError:
+ self.inform.emit('[WARNING] %s' %
+ _("Permission denied, saving not possible.\n"
+ "Most likely another app is holding the file open and not accessible."))
+ return
+ except IOError:
+ App.log.debug('Creating a new file ...')
+ f = open(filename, 'w')
+ f.close()
+ except Exception:
+ e = sys.exc_info()[0]
+ App.log.error("Could not load the file.")
+ App.log.error(str(e))
+ self.inform.emit('[ERROR_NOTCL] %s' % _("Could not load the file."))
+ return
+
+ # Save content
+ try:
+ with open(filename, "w") as f:
+ f.write(content_to_save)
+ except Exception:
+ self.inform.emit('[ERROR_NOTCL] %s %s' % (_("Failed to write defaults to file."), str(filename)))
+ return
+
+ self.inform.emit('[success] %s: %s' % (_("Exported file to"), filename))
+
def save_geometry(self, x, y, width, height, notebook_width):
"""
Will save the application geometry and positions in the defaults discitionary to be restored at the next
diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py
index 7d5b4e49..08abd842 100644
--- a/flatcamGUI/GUIElements.py
+++ b/flatcamGUI/GUIElements.py
@@ -2568,13 +2568,19 @@ class _BrowserTextEdit(QTextEdit):
def contextMenuEvent(self, event):
self.menu = self.createStandardContextMenu(event.pos())
- clear_action = QAction("Clear", self)
+
+ if self.app:
+ save_action = QAction(_("Save Log"), self)
+ self.menu.addAction(save_action)
+ save_action.triggered.connect(lambda: self.save_log(app=self.app))
+
+ clear_action = QAction(_("Clear"), self)
clear_action.setShortcut(QKeySequence(Qt.Key_Delete)) # it's not working, the shortcut
self.menu.addAction(clear_action)
clear_action.triggered.connect(self.clear)
if self.app:
- close_action = QAction("Close", self)
+ close_action = QAction(_("Close"), self)
self.menu.addAction(close_action)
close_action.triggered.connect(lambda: self.app.ui.shell_dock.hide())
@@ -2588,6 +2594,10 @@ class _BrowserTextEdit(QTextEdit):
self.moveCursor(QTextCursor.End)
self.insertHtml(text)
+ def save_log(self, app):
+ html_content = self.toHtml()
+ app.save_to_file(content_to_save=html_content)
+
class _ExpandableTextEdit(QTextEdit):
"""
diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py
index 0f8a5f0f..e5fb0af1 100644
--- a/flatcamTools/ToolShell.py
+++ b/flatcamTools/ToolShell.py
@@ -118,7 +118,7 @@ class TermWidget(QWidget):
scrollbar = self._browser.verticalScrollBar()
old_value = scrollbar.value()
- scrollattheend = old_value == scrollbar.maximum()
+ # scrollattheend = old_value == scrollbar.maximum()
self._browser.moveCursor(QTextCursor.End)
self._browser.insertHtml(text)
@@ -251,11 +251,12 @@ class FCShell(TermWidget):
self._sysShell = sysShell
def is_command_complete(self, text):
- def skipQuotes(text):
- quote = text[0]
- text = text[1:]
- endIndex = str(text).index(quote)
+ def skipQuotes(txt):
+ quote = txt[0]
+ text_val = txt[1:]
+ endIndex = str(text_val).index(quote)
return text[endIndex:]
+
while text:
if text[0] in ('"', "'"):
try:
diff --git a/tclCommands/TclCommandHelp.py b/tclCommands/TclCommandHelp.py
index d083f949..35348be0 100644
--- a/tclCommands/TclCommandHelp.py
+++ b/tclCommands/TclCommandHelp.py
@@ -9,7 +9,6 @@
from tclCommands.TclCommand import TclCommand
import collections
-import math
import gettext
import FlatCAMTranslation as fcTranslate
@@ -109,6 +108,7 @@ class TclCommandHelp(TclCommand):
displayed_text = ['> %s\n' % cmd for cmd in sorted(self.app.tcl_commands_storage)]
cmd_enum += '
'.join(displayed_text)
- cmd_enum += '
%s
%s' % (_("Type help for usage."), _("Example: help open_gerber"))
+ cmd_enum += '
%s
%s
' % (
+ _("Type help for usage."), _("Example: help open_gerber"))
self.app.shell.append_raw(cmd_enum)