diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index d082602a..5c1a9570 100644
--- a/FlatCAMApp.py
+++ b/FlatCAMApp.py
@@ -1700,7 +1700,7 @@ class App(QtCore.QObject):
"""
pass
- def shell_message(self, msg, show=False, error=False, warning=False, success=False):
+ def shell_message(self, msg, show=False, error=False, warning=False, success=False, selected=False):
"""
Shows a message on the FlatCAM Shell
@@ -1720,8 +1720,10 @@ class App(QtCore.QObject):
else:
if success:
self.shell.append_success(msg + "\n")
- else:
- self.shell.append_output(msg + "\n")
+ if success:
+ self.shell.append_selected(msg + "\n")
+ else:
+ self.shell.append_output(msg + "\n")
except AttributeError:
log.debug("shell_message() is called before Shell Class is instantiated. The message is: %s", str(msg))
@@ -1894,13 +1896,19 @@ class App(QtCore.QObject):
elif level.lower() == "error_notcl":
self.shell_message(msg, error=True, show=False)
+
elif level.lower() == "warning_notcl":
self.shell_message(msg, warning=True, show=False)
elif level.lower() == "success":
self.shell_message(msg, success=True, show=False)
+
+ elif level.lower() == "selected":
+ self.shell_message(msg, selected=True, show=False)
+
else:
self.shell_message(msg, show=False)
+
else:
self.ui.fcinfo.set_status(str(msg), level="info")
@@ -4440,6 +4448,9 @@ class App(QtCore.QObject):
# and as a convenience move the focus to the Project tab because Selected tab is now empty
self.ui.notebook.setCurrentWidget(self.ui.project_tab)
+ # delete any text in the status bar, implicitly the last object name that was selected
+ self.inform.emit("")
+
else:
# case when there is only an object under the click and we toggle it
if len(objects_under_the_click_list) == 1:
@@ -4448,6 +4459,20 @@ class App(QtCore.QObject):
# create the selection box around the selected object
curr_sel_obj = self.collection.get_active()
self.draw_selection_shape(curr_sel_obj)
+
+ if curr_sel_obj.kind == 'gerber':
+ self.inform.emit('[selected]%s selected' %
+ ('green', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'excellon':
+ self.inform.emit('[selected]%s selected' %
+ ('brown', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'cncjob':
+ self.inform.emit('[selected]%s selected' %
+ ('blue', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'geometry':
+ self.inform.emit('[selected]%s selected' %
+ ('red', str(curr_sel_obj.options['name'])))
+
elif self.collection.get_active().options['name'] not in objects_under_the_click_list:
self.collection.set_all_inactive()
self.delete_selection_shape()
@@ -4455,9 +4480,25 @@ class App(QtCore.QObject):
# create the selection box around the selected object
curr_sel_obj = self.collection.get_active()
self.draw_selection_shape(curr_sel_obj)
+
+ if curr_sel_obj.kind == 'gerber':
+ self.inform.emit('[selected]%s selected' %
+ ('green', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'excellon':
+ self.inform.emit('[selected]%s selected' %
+ ('brown', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'cncjob':
+ self.inform.emit('[selected]%s selected' %
+ ('blue', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'geometry':
+ self.inform.emit('[selected]%s selected' %
+ ('red', str(curr_sel_obj.options['name'])))
+
else:
self.collection.set_all_inactive()
self.delete_selection_shape()
+ self.inform.emit("")
+
else:
# If there is no selected object
# make active the first element of the overlapped objects list
@@ -4482,6 +4523,19 @@ class App(QtCore.QObject):
# create the selection box around the selected object
self.draw_selection_shape(curr_sel_obj)
+ if curr_sel_obj.kind == 'gerber':
+ self.inform.emit('[selected]%s selected' %
+ ('green', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'excellon':
+ self.inform.emit('[selected]%s selected' %
+ ('brown', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'cncjob':
+ self.inform.emit('[selected]%s selected' %
+ ('blue', str(curr_sel_obj.options['name'])))
+ elif curr_sel_obj.kind == 'geometry':
+ self.inform.emit('[selected]%s selected' %
+ ('red', str(curr_sel_obj.options['name'])))
+
# for obj in self.collection.get_list():
# obj.plot()
# curr_sel_obj.plot(color=self.FC_dark_blue, face_color=self.FC_light_blue)
diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py
index b6bb0bef..024ef608 100644
--- a/FlatCAMGUI.py
+++ b/FlatCAMGUI.py
@@ -4016,9 +4016,11 @@ class FlatCAMInfoBar(QtWidgets.QWidget):
layout.addStretch()
- def set_text_(self, text):
+ def set_text_(self, text, color=None):
self.text.setText(text)
self.text.setToolTip(text)
+ if color:
+ self.text.setStyleSheet('color: %s' % str(color))
def set_status(self, text, level="info"):
level = str(level)
@@ -4029,9 +4031,11 @@ class FlatCAMInfoBar(QtWidgets.QWidget):
self.pmap = QtGui.QPixmap('share/greenlight12.png')
elif level == "WARNING" or level == "WARNING_NOTCL":
self.pmap = QtGui.QPixmap('share/yellowlight12.png')
+ elif level == "selected" or level == "SELECTED":
+ self.pmap = QtGui.QPixmap('share/bluelight12.png')
else:
self.pmap = QtGui.QPixmap('share/graylight12.png')
- self.icon.setPixmap(self.pmap)
self.set_text_(text)
+ self.icon.setPixmap(self.pmap)
# end of file
diff --git a/GUIElements.py b/GUIElements.py
index d2242559..54dc0c54 100644
--- a/GUIElements.py
+++ b/GUIElements.py
@@ -1,14 +1,18 @@
from PyQt5 import QtGui, QtCore, QtWidgets
-from PyQt5.QtCore import pyqtSignal, pyqtSlot
+from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
+from PyQt5.QtWidgets import QTextEdit, QCompleter, QAction
+from PyQt5.QtGui import QColor, QKeySequence, QPalette, QTextCursor
from copy import copy
import re
import logging
+import html
log = logging.getLogger('base')
EDIT_SIZE_HINT = 70
+
class RadioSet(QtWidgets.QWidget):
activated_custom = QtCore.pyqtSignal()
@@ -1218,3 +1222,158 @@ class Dialog_box(QtWidgets.QWidget):
self.location, self.ok = dialog_box.getText(self, title, label)
+
+class _BrowserTextEdit(QTextEdit):
+
+ def __init__(self, version):
+ QTextEdit.__init__(self)
+ self.menu = None
+ self.version = version
+
+ def contextMenuEvent(self, event):
+ self.menu = self.createStandardContextMenu(event.pos())
+ 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)
+ self.menu.exec_(event.globalPos())
+
+
+ def clear(self):
+ QTextEdit.clear(self)
+ text = "FlatCAM %s (c)2014-2019 Juan Pablo Caram (Type help to get started)\n\n" % self.version
+ text = html.escape(text)
+ text = text.replace('\n', '
')
+ self.moveCursor(QTextCursor.End)
+ self.insertHtml(text)
+
+
+class _ExpandableTextEdit(QTextEdit):
+ """
+ Class implements edit line, which expands themselves automatically
+ """
+
+ historyNext = pyqtSignal()
+ historyPrev = pyqtSignal()
+
+ def __init__(self, termwidget, *args):
+ QTextEdit.__init__(self, *args)
+ self.setStyleSheet("font: 9pt \"Courier\";")
+ self._fittedHeight = 1
+ self.textChanged.connect(self._fit_to_document)
+ self._fit_to_document()
+ self._termWidget = termwidget
+
+ self.completer = MyCompleter()
+
+ self.model = QtCore.QStringListModel()
+ self.completer.setModel(self.model)
+ self.set_model_data(keyword_list=[])
+ self.completer.insertText.connect(self.insertCompletion)
+
+ def set_model_data(self, keyword_list):
+ self.model.setStringList(keyword_list)
+
+ def insertCompletion(self, completion):
+ tc = self.textCursor()
+ extra = (len(completion) - len(self.completer.completionPrefix()))
+ tc.movePosition(QTextCursor.Left)
+ tc.movePosition(QTextCursor.EndOfWord)
+ tc.insertText(completion[-extra:])
+ self.setTextCursor(tc)
+ self.completer.popup().hide()
+
+ def focusInEvent(self, event):
+ if self.completer:
+ self.completer.setWidget(self)
+ QTextEdit.focusInEvent(self, event)
+
+ def keyPressEvent(self, event):
+ """
+ Catch keyboard events. Process Enter, Up, Down
+ """
+ if event.matches(QKeySequence.InsertParagraphSeparator):
+ text = self.toPlainText()
+ if self._termWidget.is_command_complete(text):
+ self._termWidget.exec_current_command()
+ return
+ elif event.matches(QKeySequence.MoveToNextLine):
+ text = self.toPlainText()
+ cursor_pos = self.textCursor().position()
+ textBeforeEnd = text[cursor_pos:]
+
+ if len(textBeforeEnd.split('\n')) <= 1:
+ self.historyNext.emit()
+ return
+ elif event.matches(QKeySequence.MoveToPreviousLine):
+ text = self.toPlainText()
+ cursor_pos = self.textCursor().position()
+ text_before_start = text[:cursor_pos]
+ # lineCount = len(textBeforeStart.splitlines())
+ line_count = len(text_before_start.split('\n'))
+ if len(text_before_start) > 0 and \
+ (text_before_start[-1] == '\n' or text_before_start[-1] == '\r'):
+ line_count += 1
+ if line_count <= 1:
+ self.historyPrev.emit()
+ return
+ elif event.matches(QKeySequence.MoveToNextPage) or \
+ event.matches(QKeySequence.MoveToPreviousPage):
+ return self._termWidget.browser().keyPressEvent(event)
+
+ tc = self.textCursor()
+ if event.key() == Qt.Key_Tab and self.completer.popup().isVisible():
+ self.completer.insertText.emit(self.completer.getSelected())
+ self.completer.setCompletionMode(QCompleter.PopupCompletion)
+ return
+
+ QTextEdit.keyPressEvent(self, event)
+ tc.select(QTextCursor.WordUnderCursor)
+ cr = self.cursorRect()
+
+ if len(tc.selectedText()) > 0:
+ self.completer.setCompletionPrefix(tc.selectedText())
+ popup = self.completer.popup()
+ popup.setCurrentIndex(self.completer.completionModel().index(0, 0))
+
+ cr.setWidth(self.completer.popup().sizeHintForColumn(0)
+ + self.completer.popup().verticalScrollBar().sizeHint().width())
+ self.completer.complete(cr)
+ else:
+ self.completer.popup().hide()
+
+ def sizeHint(self):
+ """
+ QWidget sizeHint impelemtation
+ """
+ hint = QTextEdit.sizeHint(self)
+ hint.setHeight(self._fittedHeight)
+ return hint
+
+ def _fit_to_document(self):
+ """
+ Update widget height to fit all text
+ """
+ documentsize = self.document().size().toSize()
+ self._fittedHeight = documentsize.height() + (self.height() - self.viewport().height())
+ self.setMaximumHeight(self._fittedHeight)
+ self.updateGeometry()
+
+ def insertFromMimeData(self, mime_data):
+ # Paste only plain text.
+ self.insertPlainText(mime_data.text())
+
+
+class MyCompleter(QCompleter):
+ insertText = pyqtSignal(str)
+
+ def __init__(self, parent=None):
+ QCompleter.__init__(self)
+ self.setCompletionMode(QCompleter.PopupCompletion)
+ self.highlighted.connect(self.setHighlighted)
+
+ def setHighlighted(self, text):
+ self.lastSelected = text
+
+ def getSelected(self):
+ return self.lastSelected
diff --git a/README.md b/README.md
index 3363d5bf..8919f409 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,12 @@ CAD program, and create G-Code for Isolation routing.
- added some new icons in the help menu and reorganized this menu
- added a new function and the shortcut 'leftquote' (left of Key 1) for toggle of the notebook section
- changed the Shortcut list shortcut key to F3
+- moved some graphical classes out of Tool Shell to GUIElements.py where they belong
+- when selecting an object on canvas by single click, it's name is displayed in status bar. When nothing is selected a blank message (nothing) it's displayed
+- in Move Tool I've added the type of object that was moved in the status bar message
+- color coded the status bar bullet to blue for selection
+- the name of the selected objects are displayed in the status bar color coded: green for Gerber objects, Brown for Excellon, Red for Geometry and Blue for CNCJobs.
+
6.02.2019
diff --git a/flatcamTools/ToolMove.py b/flatcamTools/ToolMove.py
index 562aff80..9f920af4 100644
--- a/flatcamTools/ToolMove.py
+++ b/flatcamTools/ToolMove.py
@@ -139,12 +139,13 @@ class ToolMove(FlatCAMTool):
proc.done()
# delete the selection bounding box
self.delete_shape()
+ self.app.inform.emit('[success]%s object was moved ...' %
+ str(sel_obj.kind).capitalize())
self.app.worker_task.emit({'fcn': job_move, 'params': [self]})
self.clicked_move = 0
self.toggle()
- self.app.inform.emit("[success]Object was moved ...")
return
except TypeError:
diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py
index 80e94437..22171252 100644
--- a/flatcamTools/ToolShell.py
+++ b/flatcamTools/ToolShell.py
@@ -6,165 +6,12 @@
# MIT Licence #
############################################################
+# from PyQt5.QtCore import pyqtSignal
+from PyQt5.QtCore import Qt
+from PyQt5.QtGui import QTextCursor
+from PyQt5.QtWidgets import QVBoxLayout, QWidget
+from GUIElements import _BrowserTextEdit, _ExpandableTextEdit
import html
-from PyQt5.QtCore import pyqtSignal
-from PyQt5.QtCore import Qt, QStringListModel
-from PyQt5.QtGui import QColor, QKeySequence, QPalette, QTextCursor
-from PyQt5.QtWidgets import QLineEdit, QSizePolicy, QTextEdit, QVBoxLayout, QWidget, QCompleter, QAction
-
-class _BrowserTextEdit(QTextEdit):
-
- def __init__(self, version):
- QTextEdit.__init__(self)
- self.menu = None
- self.version = version
-
- def contextMenuEvent(self, event):
- self.menu = self.createStandardContextMenu(event.pos())
- 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)
- self.menu.exec_(event.globalPos())
-
-
- def clear(self):
- QTextEdit.clear(self)
- text = "FlatCAM %s (c)2014-2019 Juan Pablo Caram (Type help to get started)\n\n" % self.version
- text = html.escape(text)
- text = text.replace('\n', '
')
- self.moveCursor(QTextCursor.End)
- self.insertHtml(text)
-
-class _ExpandableTextEdit(QTextEdit):
- """
- Class implements edit line, which expands themselves automatically
- """
-
- historyNext = pyqtSignal()
- historyPrev = pyqtSignal()
-
- def __init__(self, termwidget, *args):
- QTextEdit.__init__(self, *args)
- self.setStyleSheet("font: 9pt \"Courier\";")
- self._fittedHeight = 1
- self.textChanged.connect(self._fit_to_document)
- self._fit_to_document()
- self._termWidget = termwidget
-
- self.completer = MyCompleter()
-
- self.model = QStringListModel()
- self.completer.setModel(self.model)
- self.set_model_data(keyword_list=[])
- self.completer.insertText.connect(self.insertCompletion)
-
- def set_model_data(self, keyword_list):
- self.model.setStringList(keyword_list)
-
- def insertCompletion(self, completion):
- tc = self.textCursor()
- extra = (len(completion) - len(self.completer.completionPrefix()))
- tc.movePosition(QTextCursor.Left)
- tc.movePosition(QTextCursor.EndOfWord)
- tc.insertText(completion[-extra:])
- self.setTextCursor(tc)
- self.completer.popup().hide()
-
- def focusInEvent(self, event):
- if self.completer:
- self.completer.setWidget(self)
- QTextEdit.focusInEvent(self, event)
-
- def keyPressEvent(self, event):
- """
- Catch keyboard events. Process Enter, Up, Down
- """
- if event.matches(QKeySequence.InsertParagraphSeparator):
- text = self.toPlainText()
- if self._termWidget.is_command_complete(text):
- self._termWidget.exec_current_command()
- return
- elif event.matches(QKeySequence.MoveToNextLine):
- text = self.toPlainText()
- cursor_pos = self.textCursor().position()
- textBeforeEnd = text[cursor_pos:]
-
- if len(textBeforeEnd.split('\n')) <= 1:
- self.historyNext.emit()
- return
- elif event.matches(QKeySequence.MoveToPreviousLine):
- text = self.toPlainText()
- cursor_pos = self.textCursor().position()
- text_before_start = text[:cursor_pos]
- # lineCount = len(textBeforeStart.splitlines())
- line_count = len(text_before_start.split('\n'))
- if len(text_before_start) > 0 and \
- (text_before_start[-1] == '\n' or text_before_start[-1] == '\r'):
- line_count += 1
- if line_count <= 1:
- self.historyPrev.emit()
- return
- elif event.matches(QKeySequence.MoveToNextPage) or \
- event.matches(QKeySequence.MoveToPreviousPage):
- return self._termWidget.browser().keyPressEvent(event)
-
- tc = self.textCursor()
- if event.key() == Qt.Key_Tab and self.completer.popup().isVisible():
- self.completer.insertText.emit(self.completer.getSelected())
- self.completer.setCompletionMode(QCompleter.PopupCompletion)
- return
-
- QTextEdit.keyPressEvent(self, event)
- tc.select(QTextCursor.WordUnderCursor)
- cr = self.cursorRect()
-
- if len(tc.selectedText()) > 0:
- self.completer.setCompletionPrefix(tc.selectedText())
- popup = self.completer.popup()
- popup.setCurrentIndex(self.completer.completionModel().index(0, 0))
-
- cr.setWidth(self.completer.popup().sizeHintForColumn(0)
- + self.completer.popup().verticalScrollBar().sizeHint().width())
- self.completer.complete(cr)
- else:
- self.completer.popup().hide()
-
- def sizeHint(self):
- """
- QWidget sizeHint impelemtation
- """
- hint = QTextEdit.sizeHint(self)
- hint.setHeight(self._fittedHeight)
- return hint
-
- def _fit_to_document(self):
- """
- Update widget height to fit all text
- """
- documentsize = self.document().size().toSize()
- self._fittedHeight = documentsize.height() + (self.height() - self.viewport().height())
- self.setMaximumHeight(self._fittedHeight)
- self.updateGeometry()
-
- def insertFromMimeData(self, mime_data):
- # Paste only plain text.
- self.insertPlainText(mime_data.text())
-
-
-class MyCompleter(QCompleter):
- insertText = pyqtSignal(str)
-
- def __init__(self, parent=None):
- QCompleter.__init__(self)
- self.setCompletionMode(QCompleter.PopupCompletion)
- self.highlighted.connect(self.setHighlighted)
-
- def setHighlighted(self, text):
- self.lastSelected = text
-
- def getSelected(self):
- return self.lastSelected
class TermWidget(QWidget):
@@ -234,7 +81,7 @@ class TermWidget(QWidget):
"""
Convert text to HTML for inserting it to browser
"""
- assert style in ('in', 'out', 'err', 'warning', 'success')
+ assert style in ('in', 'out', 'err', 'warning', 'success', 'selected')
text = html.escape(text)
text = text.replace('\n', '
')
@@ -247,6 +94,8 @@ class TermWidget(QWidget):
text = '%s' % text
elif style == 'success':
text = '%s' % text
+ elif style == 'selected':
+ text = '%s' % text
else:
text = '%s' % text # without span
is ignored!!!
@@ -313,6 +162,11 @@ class TermWidget(QWidget):
"""
self._append_to_browser('success', text)
+ def append_selected(self, text):
+ """Appent text to output widget
+ """
+ self._append_to_browser('selected', text)
+
def append_warning(self, text):
"""Appent text to output widget
"""
@@ -352,6 +206,7 @@ class TermWidget(QWidget):
self._edit.setPlainText(self._history[self._historyIndex])
self._edit.moveCursor(QTextCursor.End)
+
class FCShell(TermWidget):
def __init__(self, sysShell, version, *args):
TermWidget.__init__(self, version, *args)
diff --git a/share/bluelight12.png b/share/bluelight12.png
new file mode 100644
index 00000000..050aa906
Binary files /dev/null and b/share/bluelight12.png differ