def includedFiles(self):
     '''
     Returns all included files in the document.
     '''
     result = []
     b = self.document().begin()
     while b != self.document().end():
         text = b.text()
         index = self.index(text)
         if index > -1:
             startIndex = text.find('"', index)
             if startIndex > -1:
                 endIndex = text.find('"', startIndex + 1)
                 fileName = text[startIndex + 1:endIndex]
                 if len(fileName) > 0:
                     try:
                         path = interpret_path(fileName)
                         f = QFile(path)
                         ext = os.path.splitext(path)
                         if f.exists() and ext[1] in nm.settings().SEARCH_IN_EXT:
                             result.append(path)
                     except:
                         import traceback
                         print traceback.format_exc(1)
         b = b.next()
     return result
Beispiel #2
0
 def includedFiles(self):
     '''
     Returns all included files in the document.
     '''
     result = []
     b = self.document().begin()
     while b != self.document().end():
         text = b.text()
         index = self.index(text)
         if index > -1:
             startIndex = text.find('"', index)
             if startIndex > -1:
                 endIndex = text.find('"', startIndex + 1)
                 fileName = text[startIndex + 1:endIndex]
                 if len(fileName) > 0:
                     try:
                         path = interpret_path(fileName)
                         f = QFile(path)
                         ext = os.path.splitext(path)
                         if f.exists() and ext[1] in nm.settings(
                         ).SEARCH_IN_EXT:
                             result.append(path)
                     except:
                         import traceback
                         print traceback.format_exc(1)
         b = b.next()
     return result
 def focusInEvent(self, event):
     # check for file changes
     try:
         if self.filename and self.file_info:
             if self.file_info.lastModified() != QFileInfo(
                     self.filename).lastModified():
                 self.file_info = QFileInfo(self.filename)
                 result = MessageBox.question(self,
                                              "File changed",
                                              "File was changed, reload?",
                                              buttons=MessageBox.Yes
                                              | MessageBox.No)
                 if result == MessageBox.Yes:
                     f = QFile(self.filename)
                     if f.open(QIODevice.ReadOnly | QIODevice.Text):
                         self.setText(unicode(f.readAll(), "utf-8"))
                         self.document().setModified(False)
                         self.textChanged.emit()
                     else:
                         MessageBox.critical(
                             self, "Error",
                             "Cannot open launch file%s" % self.filename)
     except:
         pass
     QTextEdit.focusInEvent(self, event)
 def _connect(self, masteruri, screen_name, nodename, user=None):
     self._masteruri = masteruri
     if self.qfile is not None and self.qfile.isOpen():
         self.qfile.close()
         self.clear_signal.emit()
     host = get_hostname(masteruri)
     if nm.is_local(host):
         self._nodename = nodename
         if screen_name:
             screen_log = screen.get_logfile(node=nodename)
         else:
             screen_log = screen.get_ros_logfile(node=nodename)
         self.qfile = QFile(screen_log)
         self.setWindowTitle(nodename)
         if self.qfile.open(QIODevice.ReadOnly):
             self._first_fill = True
             self.qfile.seek(self.qfile.size() - 1)
             # self.lread()
             self._info = "END"
             self.thread = threading.Thread(target=self._read_log,
                                            kwargs={"filename": screen_log})
             self.thread.setDaemon(True)
             self.thread.start()
         else:
             self._valid = False
     else:
         self._connect_ssh(host, nodename, user)
     self.logger_handler = LoggerHandler(
         nodename,
         masteruri=masteruri,
         layout=self.scrollAreaWidgetContents.layout())
     self.logger_handler.update()
     return False
 def _included_files(self, path):
     '''
     Returns all included files in the given file.
     '''
     result = []
     with open(path, 'r') as f:
         data = f.read()
         reg = QRegExp("=[\s\t]*\".*\"")
         reg.setMinimal(True)
         pos = reg.indexIn(data)
         while pos != -1 and self._isrunning:
             try:
                 pp = interpret_path(reg.cap(0).strip('"'))
                 f = QFile(pp)
                 ext = os.path.splitext(pp)
                 if f.exists() and ext[1] in nm.settings().SEARCH_IN_EXT:
                     result.append(pp)
             except Exception as exp:
                 parsed_text = pp
                 try:
                     parsed_text = reg.cap(0).strip('"')
                 except:
                     pass
                 self.warning_signal.emit("Error while parse '%s': %s" %
                                          (parsed_text, exp))
             pos += reg.matchedLength()
             pos = reg.indexIn(data, pos)
     return result
 def _included_files(self, path):
     '''
     Returns all included files in the given file.
     '''
     result = []
     with open(path, 'r') as f:
         data = f.read()
         reg = QRegExp("=[\s\t]*\".*\"")
         reg.setMinimal(True)
         pos = reg.indexIn(data)
         while pos != -1 and self._isrunning:
             try:
                 pp = interpret_path(reg.cap(0).strip('"'))
                 f = QFile(pp)
                 ext = os.path.splitext(pp)
                 if f.exists() and ext[1] in nm.settings().SEARCH_IN_EXT:
                     result.append(pp)
             except Exception as exp:
                 parsed_text = pp
                 try:
                     parsed_text = reg.cap(0).strip('"')
                 except:
                     pass
                 self.warning_signal.emit("Error while parse '%s': %s" % (parsed_text, exp))
             pos += reg.matchedLength()
             pos = reg.indexIn(data, pos)
     return result
 def included_files(cls, text_or_path,
                    regexp_retruns=[],
                    regexp_filelist=[QRegExp("\\btextfile\\b"),
                                     QRegExp("\\bfile\\b"),
                                     QRegExp("\\bdefault\\b"),
                                     QRegExp("\\bvalue=.*pkg:\/\/\\b"),
                                     QRegExp("\\bvalue=.*package:\/\/\\b"),
                                     QRegExp("\\bvalue=.*\$\(find\\b"),
                                     QRegExp("\\bargs=.*\$\(find\\b")],
                    recursive=True, unique=True):
     '''
     :param regexp_retruns: the list with patterns which are returned as result. If empy it's the same as 'regexp_filelist'
     :param regexp_filelist: the list with all patterns to find include files
     '''
     result = []
     lines = []
     pwd = '.'
     f = QFile(text_or_path)
     if f.exists():
         pwd = os.path.dirname(text_or_path)
         with open(text_or_path, 'r') as f:
             content = f.read()
             # remove the comments
             comment_pattern = QRegExp("<!--.*?-->")
             pos = comment_pattern.indexIn(content)
             while pos != -1:
                 content = content[:pos] + content[pos + comment_pattern.matchedLength():]
                 pos = comment_pattern.indexIn(content)
             lines = content.splitlines()
     else:
         lines = [text_or_path]
     line_index = 0
     for line in lines:
         index = cls._index(line, regexp_filelist)
         if index > -1:
             startIndex = line.find('"', index)
             if startIndex > -1:
                 endIndex = line.find('"', startIndex + 1)
                 fileName = line[startIndex + 1:endIndex]
                 if len(fileName) > 0:
                     try:
                         path = cls.interpretPath(fileName, pwd)
                         if os.path.isfile(path):
                             if not regexp_retruns or cls._index(line, regexp_retruns) > -1:
                                 if not unique:
                                     result.append((line_index, path))
                                 else:
                                     result.append(path)
                             ext = os.path.splitext(path)
                             if recursive and ext[1] in nm.settings().SEARCH_IN_EXT:
                                 result += cls.included_files(path, regexp_retruns, regexp_filelist)
                     except Exception:
                         import traceback
                         print traceback.format_exc()
         line_index += 1
     if unique:
         return list(set(result))
     return result
 def included_files(cls, text_or_path, regexp_list=[QRegExp("\\btextfile\\b"),
                                                    QRegExp("\\bfile\\b"),
                                                    QRegExp("\\bdefault\\b"),
                                                    QRegExp("\\bvalue=.*pkg:\/\/\\b"),
                                                    QRegExp("\\bvalue=.*package:\/\/\\b"),
                                                    QRegExp("\\bvalue=.*\$\(find\\b"),
                                                    QRegExp("\\bargs=.*\$\(find\\b")],
                    recursive=True, unique=True):
     result = []
     lines = []
     pwd = '.'
     f = QFile(text_or_path)
     if f.exists():
         pwd = os.path.dirname(text_or_path)
         with open(text_or_path, 'r') as f:
             content = f.read()
             # remove the comments
             comment_pattern = QRegExp("<!--.*?-->")
             pos = comment_pattern.indexIn(content)
             while pos != -1:
                 content = content[:pos] + content[pos + comment_pattern.matchedLength():]
                 pos = comment_pattern.indexIn(content)
             lines = content.splitlines()
     else:
         lines = [text_or_path]
     line_index = 0
     for line in lines:
         index = cls._index(line, regexp_list)
         if index > -1:
             startIndex = line.find('"', index)
             if startIndex > -1:
                 endIndex = line.find('"', startIndex + 1)
                 fileName = line[startIndex + 1:endIndex]
                 if len(fileName) > 0:
                     try:
                         path = cls.interpretPath(fileName, pwd)
                         if os.path.isfile(path):
                             if not unique:
                                 result.append((line_index, path))
                             else:
                                 result.append(path)
                             ext = os.path.splitext(path)
                             if recursive and ext[1] in nm.settings().SEARCH_IN_EXT:
                                 result += cls.included_files(path, regexp_list)
                     except Exception:
                         import traceback
                         print traceback.format_exc()
         line_index += 1
     if unique:
         return list(set(result))
     return result
Beispiel #9
0
    def __init__(self, filename, parent=None):
        self.parent = parent
        QTextEdit.__init__(self, parent)
        self.setObjectName(' - '.join(['Editor', filename]))
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.show_custom_context_menu)
        #        self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.setAcceptRichText(False)
        font = QFont()
        font.setFamily("Fixed".decode("utf-8"))
        font.setPointSize(12)
        self.setFont(font)
        self.setLineWrapMode(QTextEdit.NoWrap)
        self.setTabStopWidth(25)
        self.setAcceptRichText(False)
        self.setCursorWidth(2)
        self.setFontFamily("courier new")
        self.setProperty("backgroundVisible", True)
        self.regexp_list = [
            QRegExp("\\binclude\\b"),
            QRegExp("\\btextfile\\b"),
            QRegExp("\\bfile\\b"),
            QRegExp("\\bvalue=.*pkg:\/\/\\b"),
            QRegExp("\\bvalue=.*package:\/\/\\b"),
            QRegExp("\\bvalue=.*\$\(find\\b"),
            QRegExp("\\bargs=.*\$\(find\\b"),
            QRegExp("\\bdefault=.*\$\(find\\b")
        ]
        self.filename = filename
        self.file_info = None
        if self.filename:
            f = QFile(filename)
            if f.open(QIODevice.ReadOnly | QIODevice.Text):
                self.file_info = QFileInfo(filename)
                self.setText(unicode(f.readAll(), "utf-8"))

        self.path = '.'
        # enables drop events
        self.setAcceptDrops(True)
        if filename.endswith('.launch'):
            self.hl = XmlHighlighter(self.document())
            self.cursorPositionChanged.connect(self._document_position_changed)
        else:
            self.hl = YamlHighlighter(self.document())
        # variables for threaded search
        self._search_thread = None
        self._stop = False
Beispiel #10
0
 def mouseReleaseEvent(self, event):
     '''
     Opens the new editor, if the user clicked on the included file and sets the
     default cursor.
     '''
     if event.modifiers() == Qt.ControlModifier or event.modifiers() == Qt.ShiftModifier:
         cursor = self.cursorForPosition(event.pos())
         index = self.index(cursor.block().text())
         if index > -1:
             startIndex = cursor.block().text().find('"', index)
             if startIndex > -1:
                 endIndex = cursor.block().text().find('"', startIndex + 1)
                 fileName = cursor.block().text()[startIndex + 1:endIndex]
                 if len(fileName) > 0:
                     try:
                         qf = QFile(interpret_path(fileName))
                         if not qf.exists():
                             # create a new file, if it does not exists
                             result = QMessageBox.question(self, "File not found", '\n\n'.join(["Create a new file?", qf.fileName()]), QMessageBox.Yes | QMessageBox.No)
                             if result == QMessageBox.Yes:
                                 d = os.path.dirname(qf.fileName())
                                 if not os.path.exists(d):
                                     os.makedirs(d)
                                 with open(qf.fileName(), 'w') as f:
                                     if qf.fileName().endswith('.launch'):
                                         f.write('<launch>\n\n</launch>')
                                 event.setAccepted(True)
                                 self.load_request_signal.emit(qf.fileName())
                         else:
                             event.setAccepted(True)
                             self.load_request_signal.emit(qf.fileName())
                     except Exception, e:
                         WarningMessageBox(QMessageBox.Warning, "File not found %s" % fileName, str(e)).exec_()
 def mouseReleaseEvent(self, event):
     '''
     Opens the new editor, if the user clicked on the included file and sets the
     default cursor.
     '''
     if event.modifiers() == Qt.ControlModifier or event.modifiers() == Qt.ShiftModifier:
         cursor = self.cursorForPosition(event.pos())
         inc_files = LaunchConfig.included_files(cursor.block().text(), recursive=False)
         if inc_files:
             try:
                 qf = QFile(inc_files[0])
                 if not qf.exists():
                     # create a new file, if it does not exists
                     result = MessageBox.question(self, "File not found", '\n\n'.join(["Create a new file?", qf.fileName()]), buttons=MessageBox.Yes | MessageBox.No)
                     if result == MessageBox.Yes:
                         d = os.path.dirname(qf.fileName())
                         if not os.path.exists(d):
                             os.makedirs(d)
                         with open(qf.fileName(), 'w') as f:
                             if qf.fileName().endswith('.launch'):
                                 f.write('<launch>\n\n</launch>')
                         event.setAccepted(True)
                         self.load_request_signal.emit(qf.fileName())
                 else:
                     event.setAccepted(True)
                     self.load_request_signal.emit(qf.fileName())
             except Exception, e:
                 MessageBox.critical(self, "Error", "File not found %s" % inc_files[0], detailed_text=utf8(e))
 def focusInEvent(self, event):
     # check for file changes
     try:
         if self.filename and self.file_info:
             if self.file_info.lastModified() != QFileInfo(self.filename).lastModified():
                 self.file_info = QFileInfo(self.filename)
                 result = MessageBox.question(self, "File changed", "File was changed, reload?", buttons=MessageBox.Yes | MessageBox.No)
                 if result == MessageBox.Yes:
                     f = QFile(self.filename)
                     if f.open(QIODevice.ReadOnly | QIODevice.Text):
                         self.setText(unicode(f.readAll(), "utf-8"))
                         self.document().setModified(False)
                         self.textChanged.emit()
                     else:
                         MessageBox.critical(self, "Error", "Cannot open launch file%s" % self.filename)
     except:
         pass
     QTextEdit.focusInEvent(self, event)
    def __init__(self, filename, parent=None):
        self.parent = parent
        QTextEdit.__init__(self, parent)
        self.setObjectName(' - '.join(['Editor', filename]))
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.show_custom_context_menu)
#        self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.setAcceptRichText(False)
        font = QFont()
        font.setFamily("Fixed".decode("utf-8"))
        font.setPointSize(12)
        self.setFont(font)
        self.setLineWrapMode(QTextEdit.NoWrap)
        self.setTabStopWidth(25)
        self.setAcceptRichText(False)
        self.setCursorWidth(2)
        self.setFontFamily("courier new")
        self.setProperty("backgroundVisible", True)
        self.regexp_list = [QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"),
                            QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"),
                            QRegExp("\\bvalue=.*package:\/\/\\b"),
                            QRegExp("\\bvalue=.*\$\(find\\b"),
                            QRegExp("\\bargs=.*\$\(find\\b"),
                            QRegExp("\\bdefault=.*\$\(find\\b")]
        self.filename = filename
        self.file_info = None
        if self.filename:
            f = QFile(filename)
            if f.open(QIODevice.ReadOnly | QIODevice.Text):
                self.file_info = QFileInfo(filename)
                self.setText(unicode(f.readAll(), "utf-8"))

        self.path = '.'
        # enables drop events
        self.setAcceptDrops(True)
        if filename.endswith('.launch'):
            self.hl = XmlHighlighter(self.document())
            self.cursorPositionChanged.connect(self._document_position_changed)
        else:
            self.hl = YamlHighlighter(self.document())
        # variables for threaded search
        self._search_thread = None
        self._stop = False
Beispiel #14
0
    def _save_dot(self):
        file_name, _ = QFileDialog.getSaveFileName(self._widget, self.tr('Save as DOT'), 'rosgraph.dot', self.tr('DOT graph (*.dot)'))
        if file_name is None or file_name == '':
            return

        handle = QFile(file_name)
        if not handle.open(QIODevice.WriteOnly | QIODevice.Text):
            return

        handle.write(self._current_dotcode)
        handle.close()
Beispiel #15
0
    def save(self, force=False):
        '''
        Saves changes to the file.
        :return: saved, errors, msg
        :rtype: bool, bool, str
        '''
        if force or self.document().isModified() or not QFileInfo(
                self.filename).exists():
            f = QFile(self.filename)
            if f.open(QIODevice.WriteOnly | QIODevice.Text):
                f.write(self.toPlainText().encode('utf-8'))
                self.document().setModified(False)
                self.file_info = QFileInfo(self.filename)

                ext = os.path.splitext(self.filename)
                # validate the xml structure of the launch files
                if ext[1] in self.CONTEXT_FILE_EXT:
                    imported = False
                    try:
                        from lxml import etree
                        imported = True
                        parser = etree.XMLParser()
                        etree.fromstring(self.toPlainText().encode('utf-8'),
                                         parser)
                    except Exception as e:
                        if imported:
                            self.markLine(e.position[0])
                            return True, True, "%s" % e
                # validate the yaml structure of yaml files
                elif ext[1] in self.YAML_VALIDATION_FILES:
                    try:
                        import yaml
                        yaml.load(self.toPlainText().encode('utf-8'))
                    except yaml.MarkedYAMLError as e:
                        return True, True, "%s" % e
                return True, False, ''
            else:
                return False, True, "Cannot write XML file"
        return False, False, ''
    def save(self, force=False):
        '''
        Saves changes to the file.
        :return: saved, errors, msg
        :rtype: bool, bool, str
        '''
        if force or self.document().isModified() or not QFileInfo(self.filename).exists():
            f = QFile(self.filename)
            if f.open(QIODevice.WriteOnly | QIODevice.Text):
                f.write(self.toPlainText().encode('utf-8'))
                self.document().setModified(False)
                self.file_info = QFileInfo(self.filename)

                ext = os.path.splitext(self.filename)
                # validate the xml structure of the launch files
                if ext[1] in self.CONTEXT_FILE_EXT:
                    imported = False
                    try:
                        from lxml import etree
                        imported = True
                        parser = etree.XMLParser()
                        etree.fromstring(self.toPlainText().encode('utf-8'), parser)
                    except Exception as e:
                        if imported:
                            self.markLine(e.position[0])
                            return True, True, "%s" % e
                # validate the yaml structure of yaml files
                elif ext[1] in self.YAML_VALIDATION_FILES:
                    try:
                        import yaml
                        yaml.load(self.toPlainText().encode('utf-8'))
                    except yaml.MarkedYAMLError as e:
                        return True, True, "%s" % e
                return True, False, ''
            else:
                return False, True, "Cannot write XML file"
        return False, False, ''
Beispiel #17
0
 def mouseReleaseEvent(self, event):
     '''
     Opens the new editor, if the user clicked on the included file and sets the
     default cursor.
     '''
     if event.modifiers() == Qt.ControlModifier or event.modifiers(
     ) == Qt.ShiftModifier:
         cursor = self.cursorForPosition(event.pos())
         index = self.index(cursor.block().text())
         if index > -1:
             startIndex = cursor.block().text().find('"', index)
             if startIndex > -1:
                 endIndex = cursor.block().text().find('"', startIndex + 1)
                 fileName = cursor.block().text()[startIndex + 1:endIndex]
                 if len(fileName) > 0:
                     try:
                         qf = QFile(interpret_path(fileName))
                         if not qf.exists():
                             # create a new file, if it does not exists
                             result = QMessageBox.question(
                                 self, "File not found", '\n\n'.join(
                                     ["Create a new file?",
                                      qf.fileName()]),
                                 QMessageBox.Yes | QMessageBox.No)
                             if result == QMessageBox.Yes:
                                 d = os.path.dirname(qf.fileName())
                                 if not os.path.exists(d):
                                     os.makedirs(d)
                                 with open(qf.fileName(), 'w') as f:
                                     if qf.fileName().endswith('.launch'):
                                         f.write('<launch>\n\n</launch>')
                                 event.setAccepted(True)
                                 self.load_request_signal.emit(
                                     qf.fileName())
                         else:
                             event.setAccepted(True)
                             self.load_request_signal.emit(qf.fileName())
                     except Exception, e:
                         WarningMessageBox(QMessageBox.Warning,
                                           "File not found %s" % fileName,
                                           str(e)).exec_()
    def _save_dot(self):
        file_name, _ = QFileDialog.getSaveFileName(self._widget, self.tr('Save as DOT'), 'rospackgraph.dot', self.tr('DOT graph (*.dot)'))
        if file_name is None or file_name == '':
            return

        handle = QFile(file_name)
        if not handle.open(QIODevice.WriteOnly | QIODevice.Text):
            return

        handle.write(self._current_dotcode)
        handle.close()
 def mouseReleaseEvent(self, event):
     '''
     Opens the new editor, if the user clicked on the included file and sets the
     default cursor.
     '''
     if event.modifiers() == Qt.ControlModifier or event.modifiers(
     ) == Qt.ShiftModifier:
         cursor = self.cursorForPosition(event.pos())
         inc_files = LaunchConfig.included_files(cursor.block().text(),
                                                 recursive=False)
         if inc_files:
             try:
                 qf = QFile(inc_files[0])
                 if not qf.exists():
                     # create a new file, if it does not exists
                     result = MessageBox.question(
                         self,
                         "File not found",
                         '\n\n'.join(["Create a new file?",
                                      qf.fileName()]),
                         buttons=MessageBox.Yes | MessageBox.No)
                     if result == MessageBox.Yes:
                         d = os.path.dirname(qf.fileName())
                         if not os.path.exists(d):
                             os.makedirs(d)
                         with open(qf.fileName(), 'w') as f:
                             if qf.fileName().endswith('.launch'):
                                 f.write('<launch>\n\n</launch>')
                         event.setAccepted(True)
                         self.load_request_signal.emit(qf.fileName())
                 else:
                     event.setAccepted(True)
                     self.load_request_signal.emit(qf.fileName())
             except Exception, e:
                 MessageBox.critical(self,
                                     "Error",
                                     "File not found %s" % inc_files[0],
                                     detailed_text=utf8(e))
class ScreenWidget(QWidget):
    '''
    Shows the output of a screen.
    '''

    clear_signal = Signal()
    cleared_signal = Signal()

    output = Signal(str)
    output_prefix = Signal(str)
    error_signal = Signal(str)
    auth_signal = Signal(str, str, str)  # host, nodename, user

    def __init__(self,
                 masteruri,
                 screen_name,
                 nodename,
                 user=None,
                 parent=None):
        '''
        Creates the window, connects the signals and init the class.
        '''
        QWidget.__init__(self, parent)
        # load the UI file
        screen_dock_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), '..', 'ui',
            'logscreen', 'ScreenWidget.ui')
        loadUi(screen_dock_file, self)
        self.setObjectName("ScreenWidget")
        self.setWindowIcon(nm.settings().icon('crystal_clear_show_io.png'))
        # self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable)
        self.pauseButton.setIcon(nm.settings().icon('sekkyumu_pause.png'))
        self._valid = True
        self._lock = threading.RLock()
        self.finished = False
        self.qfile = None
        self.thread = None
        self._info = ''
        self._masteruri = ''
        self._nodename = ''
        self._first_fill = True
        self._seek_start = -1
        self._seek_end = -1
        self._pause_read_end = False
        self._ssh_output_file = None
        self._ssh_error_file = None
        self._ssh_input_file = None
        self._on_pause = False
        self._char_format_end = None
        self.loggers.setVisible(False)
        self.loglevelButton.toggled.connect(self.on_toggle_loggers)
        self.logger_handler = None
        # connect to the button signals
        self.output.connect(self._on_output)
        self.output_prefix.connect(self._on_output_prefix)
        self.error_signal.connect(self._on_error)
        self.auth_signal.connect(self.on_request_pw)
        self.clearCloseButton.clicked.connect(self.clear)
        # self.pauseButton.clicked.connect(self.stop)
        self.pauseButton.toggled.connect(self.pause)
        self.clear_signal.connect(self.clear)
        self.textBrowser.verticalScrollBar().valueChanged.connect(
            self.on_scrollbar_position_changed)
        self.textBrowser.verticalScrollBar().rangeChanged.connect(
            self.on_scrollbar_range_changed)
        self.textBrowser.set_reader(self)
        self.tf = TerminalFormats()
        self.hl = ScreenHighlighter(self.textBrowser.document())
        self.searchFrame.setVisible(False)
        self.grepFrame.setVisible(False)
        self.grepLineEdit.textChanged.connect(self.on_grep_changed)
        self._shortcut_search = QShortcut(
            QKeySequence(self.tr("Ctrl+F", "Activate search")), self)
        self._shortcut_search.activated.connect(self.on_search)
        self._shortcut_grep = QShortcut(
            QKeySequence(self.tr("Ctrl+G", "Activate grep")), self)
        self._shortcut_grep.activated.connect(self.on_grep)
        self.searchLineEdit.editingFinished.connect(self.on_search_prev)
        self.searchNextButton.clicked.connect(self.on_search_next)
        self.searchPrevButton.clicked.connect(self.on_search_prev)
        # self.visibilityChanged.connect(self.stop)
        self._connect(masteruri, screen_name, nodename, user)

    def masteruri(self):
        return self._masteruri

    def name(self):
        return self._nodename

    def clear(self):
        '''
        Removes all messages and emit the `cleared_signal`.
        '''
        self.textBrowser.clear()
        self.infoLabel.setText('')
        self.cleared_signal.emit()

    def finish(self):
        self.finished = True
        self.output.disconnect()
        self.output_prefix.disconnect()
        self.close()

    def closeEvent(self, event):
        self.stop()
        QWidget.closeEvent(self, event)

    def hide(self):
        self.stop()
        QWidget.hide(self)

    def close(self):
        self.stop()
        QWidget.close(self)

    def on_search(self):
        self.searchFrame.setVisible(not self.searchFrame.isVisible())
        if self.searchFrame.isVisible():
            self.searchLineEdit.setFocus()
            self.searchLineEdit.selectAll()
        else:
            cursor = self.textBrowser.textCursor()
            cursor.clearSelection()
            self.textBrowser.setTextCursor(cursor)
            self.textBrowser.setFocus()

    def on_search_next(self):
        self._perform_search(forward=True)

    def on_search_prev(self):
        self._perform_search(forward=False)

    def _perform_search(self, forward=False):
        search_str = self.searchLineEdit.text()
        if search_str:
            cursor = self.textBrowser.textCursor()
            if forward:
                search_result = self.textBrowser.document().find(
                    search_str, cursor)
            else:
                search_result = self.textBrowser.document().find(
                    search_str, cursor, QTextDocument.FindBackward)
            if search_result.position() > -1:
                self.textBrowser.setTextCursor(search_result)
                self.searchLabel.setText('')
                # self.searchLabel.setText('%d' % search_result.position())
            else:
                self.searchLabel.setText('no results')
        else:
            self.searchLabel.setText('')

    def on_grep(self):
        self.grepFrame.setVisible(not self.grepFrame.isVisible())
        if self.grepFrame.isVisible():
            self.grepLineEdit.setFocus()
            self.on_grep_changed(self.grepLineEdit.text())
            self.hl.set_grep_text('')
            self.grepLineEdit.selectAll()
        else:
            self.on_grep_changed('')
            self.textBrowser.setFocus()

    def on_grep_changed(self, text):
        self.hl.set_grep_text(text)

    def stop(self):
        '''
        '''
        if self.qfile is not None and self.qfile.isOpen():
            self.qfile.close()
            self.qfile = None
            self._seek_start = -1
            self._seek_end = -1
            self._pause_read_end = False
            # self.clear()
        try:
            self._ssh_output_file.close()
            self._ssh_error_file.close()
            # send Ctrl+C to remote process
            self._ssh_input_file.write('%s\n' % chr(3))
            self._ssh_input_file.close()
        except Exception:
            pass

    def pause(self, state):
        self._on_pause = state

    def valid(self):
        return self._valid

    def _connect(self, masteruri, screen_name, nodename, user=None):
        self._masteruri = masteruri
        if self.qfile is not None and self.qfile.isOpen():
            self.qfile.close()
            self.clear_signal.emit()
        host = get_hostname(masteruri)
        if nm.is_local(host):
            self._nodename = nodename
            if screen_name:
                screen_log = screen.get_logfile(node=nodename)
            else:
                screen_log = screen.get_ros_logfile(node=nodename)
            self.qfile = QFile(screen_log)
            self.setWindowTitle(nodename)
            if self.qfile.open(QIODevice.ReadOnly):
                self._first_fill = True
                self.qfile.seek(self.qfile.size() - 1)
                # self.lread()
                self._info = "END"
                self.thread = threading.Thread(target=self._read_log,
                                               kwargs={"filename": screen_log})
                self.thread.setDaemon(True)
                self.thread.start()
            else:
                self._valid = False
        else:
            self._connect_ssh(host, nodename, user)
        self.logger_handler = LoggerHandler(
            nodename,
            masteruri=masteruri,
            layout=self.scrollAreaWidgetContents.layout())
        self.logger_handler.update()
        return False

    def _read_log(self, filename, lines=80):
        while self.qfile is not None and self.qfile.isOpen():
            with self._lock:
                if self._first_fill:
                    chars_count = self._seek_count_lines(lines)
                    self._seek_start = self.qfile.pos()
                    data = self.qfile.read(chars_count)
                    if sys.version_info > (3, 0):
                        data = data.decode('utf-8')
                    self.output.emit(data)
                    self._seek_end = self.qfile.pos()
                    self._first_fill = False
                else:
                    if self._seek_end != -1:
                        self.qfile.seek(self._seek_end)
                    if (not self._pause_read_end
                            and self.qfile.bytesAvailable()):
                        start = self.qfile.pos()
                        data = self.qfile.readAll().data()
                        if sys.version_info > (3, 0):
                            data = data.decode('utf-8')
                        self.output.emit(data)
                        self._seek_end = self.qfile.pos()
                        self._info = "NEW: %d" % (self._seek_end - start)
            time.sleep(0.25)

    def reverse_read(self, lines=20):
        with self._lock:
            if self.qfile is not None and self.qfile.isOpen():
                if lines == -1:
                    self.qfile.seek(0)
                    chars_count = self._seek_start
                else:
                    self.qfile.seek(self._seek_start)
                    chars_count = self._seek_count_lines(lines)
                self._seek_start = self.qfile.pos()
                data = self.qfile.read(chars_count)
                if sys.version_info > (3, 0):
                    data = data.decode('utf-8')
                self.output_prefix.emit(data)

    def _seek_count_lines(self, lines=20):
        if self.qfile.pos() < 2:
            self.qfile.seek(0)
            return self.qfile.pos()
        count = 0
        chars_count = 2
        line_size = 0
        count_reached = False
        self.qfile.seek(self.qfile.pos() - 2)
        while (not count_reached) and (self.qfile.pos() > 0):
            ch = self.qfile.read(1)
            self.qfile.seek(self.qfile.pos() - 2)
            chars_count += 1
            line_size += 1
            if line_size > 120:
                count += 1
                line_size = 0
            if ch == '\n':
                count += 1
                line_size = 0
                if count >= lines:
                    count_reached = True
        return chars_count + 1

    def _on_output_prefix(self, msg):
        '''
        This text will be prepended
        '''
        if self.finished or self._on_pause:
            return
        if msg:
            cursor = QTextCursor(self.textBrowser.document())
            self.tf.insert_formated(cursor, msg.rstrip())
            self.textBrowser.setTextCursor(cursor)
            self.textBrowser.moveCursor(QTextCursor.Start)
            self._update_info_label()

    def _on_output(self, msg):
        '''
        This text will be appended.
        '''
        if self.finished or self._on_pause:
            return
        if msg:
            at_end = self.textBrowser.verticalScrollBar().value(
            ) > self.textBrowser.verticalScrollBar().maximum() - 20
            cursor_select = self.textBrowser.textCursor()
            # store selection and do not scroll to the appended text
            if not cursor_select.hasSelection():
                cursor_select = None
            cursor = self.textBrowser.textCursor()
            cursor.movePosition(QTextCursor.End)
            if self.hl.has_grep_text():
                # grep new text
                lines = msg.splitlines(True)
                for line in lines:
                    if self.hl.contains_grep_text(line):
                        self._char_format_end = self.tf.insert_formated(
                            cursor, line, char_format=None)
            else:
                self._char_format_end = self.tf.insert_formated(
                    cursor, msg, char_format=self._char_format_end)
            if cursor_select is not None:
                # restore selection
                self.textBrowser.setTextCursor(cursor_select)
            elif at_end:
                self.textBrowser.moveCursor(QTextCursor.End)
            self._update_info_label()
            if not self.finished:
                self.show()

    def on_scrollbar_position_changed(self, value):
        self._update_info_label()

    def on_scrollbar_range_changed(self, min, max):
        self._update_info_label()

    def _on_error(self, msg):
        self.textBrowser.append(msg)
        self._update_info_label('SSH ERROR')

    def _update_info_label(self, info=''):
        info_text = info
        vbar_value = self.textBrowser.verticalScrollBar().value()
        if not info_text:
            if vbar_value == 0:
                if self._seek_start == 0:
                    info_text = 'START'
                else:
                    info_text += "%d %%" % (self._seek_start * 100 /
                                            self._seek_end)
            elif vbar_value == self.textBrowser.verticalScrollBar().maximum():
                info_text = 'END'
            else:
                info_text = "%d / %d" % (
                    vbar_value / 20,
                    self.textBrowser.verticalScrollBar().maximum() / 20)
        self.infoLabel.setText(info_text + '\t%s / %s' %
                               (sizeof_fmt(self._seek_end - self._seek_start),
                                sizeof_fmt(self._seek_end)))

    def _connect_ssh(self, host, nodename, user=None, pw=None):
        try:
            if user is not None:
                self.infoLabel.setText('connecting to %s@%s' % (user, host))
            else:
                self.infoLabel.setText('connecting to %s' % host)
            ok = False
            self.ssh_input_file, self.ssh_output_file, self.ssh_error_file, ok = nm.ssh(
            ).ssh_exec(host, [
                nm.settings().start_remote_script, '--tail_screen_log',
                nodename
            ],
                       user,
                       pw,
                       auto_pw_request=False,
                       get_pty=True)
            if ok:
                thread = threading.Thread(target=self._read_ssh_output,
                                          args=((self.ssh_output_file, )))
                thread.setDaemon(True)
                thread.start()
                thread = threading.Thread(target=self._read_ssh_error,
                                          args=((self.ssh_error_file, )))
                thread.setDaemon(True)
                thread.start()
            elif self.ssh_output_file:
                self.ssh_output_file.close()
                self.ssh_error_file.close()
        except nm.AuthenticationRequest as e:
            self.auth_signal.emit(host, nodename, user)
        except Exception as e:
            self.error_signal.emit('%s\n' % e)

    def on_request_pw(self, host, nodename, user):
        res, user, pw = nm.ssh()._requestPW(user, host)
        if res:
            self._connect_ssh(host, nodename, user, pw)

    def _read_ssh_output(self, output_file):
        while not output_file.closed:
            text = output_file.readline()
            if text:
                self.output.emit(text)

    def _read_ssh_error(self, error_file):
        try:
            while not error_file.closed:
                text = error_file.readline()
                if text:
                    self.error_signal.emit(text)
        except Exception:
            pass

    def on_toggle_loggers(self, state):
        self.loggers.setVisible(state)
        if state:
            self.logger_handler.update()
Beispiel #21
0
    def _save_dataset(self):

        formats = ['CSV', 'PKL', 'H5', 'DLS', 'FANN']
        supported_formats = ''
        for f in formats:
            supported_formats += f + ';;'

        self._data_filename, self._data_format = QFileDialog.getSaveFileName(
            self._widget, self.tr('Save dataset'), 'dataset_name',
            self.tr(supported_formats[:-2]))

        if self._data_filename is None or self._data_filename == '':
            return

        self._data_filename += '.' + self._data_format.lower()

        if self._data_format == 'CSV':

            # fill up the list of selected data leaves
            self._fill_selected_leaves_list()

            # create new stream file
            data_file = QFile(self._data_filename)
            if not data_file.open(QIODevice.WriteOnly | QIODevice.Text):
                return
            self._file_stream = QTextStream(data_file)

            # fill up single line record dictionary with topic keys
            self._line_record['timestamp'] = 0
            for leaf in self._selected_leaves:  #self._get_selected_items_list():
                self._line_record[leaf] = 0

            # write out header
            for key in self._line_record:
                self._file_stream << key << ','
            self._file_stream << '\n'

            # open bag file
            bag = rosbag.Bag(self._bag_filename)
            # cycle through selected base topics
            for topic, message, time in bag.read_messages(
                    self._get_selected_topics()):
                # traverse down the message slots
                # print('Traversing: ' + topic)
                self._line_record['timestamp'] = str(time)
                self._export_leaf_instance(message, '', '', topic, [])

            data_file.close()
            print('File saved: ' + self._data_filename)

        elif self._data_format == 'PKL':
            df = rosbag_pandas.bag_to_dataframe(self._bag_filename,
                                                self._get_selected_topics())
            df.to_pickle(self._data_filename)
            print('File saved: ' + self._data_filename)

        elif self._data_format == 'H5':
            df = rosbag_pandas.bag_to_dataframe(self._bag_filename,
                                                self._get_selected_topics())
            hdf_store = HDFStore(self._data_filename)
            hdf_store['df'] = df
            hdf_store.close()
            print('File saved: ' + self._data_filename)

        elif self._data_format == 'DLS':
            self._no_support_warning()

        elif self._data_format == 'FANN':
            self._no_support_warning()

        else:
            self._no_support_warning()
import sys
from python_qt_binding.QtWidgets import QApplication, QWidget, QVBoxLayout
from python_qt_binding.QtCore import QFile, QIODevice, QObject
from rqt_graph.ros_graph import RosGraph


class FakePluginContext(QObject):
    def __init__(self):
        super(FakePluginContext, self).__init__()
        self.setObjectName('FakePluginContext')

    def serial_number(self):
        return 0

    def add_widget(self, widget):
        pass


if __name__ == "__main__":
    app = QApplication(sys.argv)
    fpc = FakePluginContext()
    r = RosGraph(fpc)

    handle = QFile(sys.argv[1])
    if not handle.open(QIODevice.WriteOnly | QIODevice.Text):
        exit(1)

    handle.write(r._generate_dotcode())
    handle.close()