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
예제 #2
0
 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
예제 #4
0
 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
예제 #5
0
 def getIncludedFiles(cls,
                      inc_file,
                      regexp_list=[
                          QRegExp("\\binclude\\b"),
                          QRegExp("\\btextfile\\b"),
                          QRegExp("\\bfile\\b"),
                          QRegExp("\\bdefault\\b"),
                          QRegExp("\\bvalue=.*pkg:\/\/\\b"),
                          QRegExp("\\bvalue=.*package:\/\/\\b"),
                          QRegExp("\\bvalue=.*\$\(find\\b")
                      ]):
     '''
     Reads the configuration file and searches for included files. This files
     will be returned in a list.
     @param inc_file: path of the ROS launch file
     @param regexp_list: pattern of
     @return: the list with all files needed for the configuration
     @rtype: C{[str,...]}
     '''
     result = set()
     with open(inc_file, '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()
     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,
                                                  os.path.dirname(inc_file))
                         if os.path.isfile(path):
                             result.add(path)
                             if path.endswith('.launch'):
                                 result.update(
                                     cls.getIncludedFiles(
                                         path, regexp_list))
                     except:
                         pass
     return list(result)
예제 #6
0
class SyncHighlighter(QSyntaxHighlighter):
    '''
    Enabled the syntax highlightning for the sync interface.
    '''
    def __init__(self, parent=None):
        QSyntaxHighlighter.__init__(self, parent)
        self.rules = []
        self.commentStart = QRegExp("#")
        self.commentEnd = QRegExp("\n")
        self.commentFormat = QTextCharFormat()
        self.commentFormat.setFontItalic(True)
        self.commentFormat.setForeground(Qt.darkGray)
        f = QTextCharFormat()
        r = QRegExp()
        r.setMinimal(True)
        f.setFontWeight(QFont.Normal)
        f.setForeground(Qt.darkBlue)
        tagList = [
            "\\bignore_hosts\\b", "\\bsync_hosts\\b", "\\bignore_nodes\\b",
            "\\bsync_nodes\\b", "\\bignore_topics\\b",
            "\\bignore_publishers\\b", "\\bignore_topics\\b",
            "\\bsync_topics\\b", "\\bignore_subscribers\\b",
            "\\bsync_services\\b", "\\bsync_topics_on_demand\\b",
            "\\bsync_remote_nodes\\b"
        ]
        for tag in tagList:
            r.setPattern(tag)
            self.rules.append((QRegExp(r), QTextCharFormat(f)))

        f.setForeground(Qt.darkGreen)
        f.setFontWeight(QFont.Bold)
        attrList = ["\\b\\*|\\*\\B|\\/\\*"]
        for attr in attrList:
            r.setPattern(attr)
            self.rules.append((QRegExp(r), QTextCharFormat(f)))


#    f.setForeground(Qt.red)
#    f.setFontWeight(QFont.Bold)
#    attrList = ["\\s\\*"]
#    for attr in attrList:
#      r.setPattern(attr)
#      self.rules.append((QRegExp(r), QTextCharFormat(f)))

    def highlightBlock(self, text):
        for pattern, myformat in self.rules:
            index = pattern.indexIn(text)
            while index >= 0:
                length = pattern.matchedLength()
                self.setFormat(index, length, myformat)
                index = pattern.indexIn(text, index + length)

        self.setCurrentBlockState(0)
        startIndex = 0
        if self.previousBlockState() != 1:
            startIndex = self.commentStart.indexIn(text)
            if startIndex >= 0:
                commentLength = len(text) - startIndex
                self.setFormat(startIndex, commentLength, self.commentFormat)
예제 #7
0
class SyncHighlighter(QSyntaxHighlighter):
    '''
    Enabled the syntax highlightning for the sync interface.
    '''

    def __init__(self, parent=None):
        QSyntaxHighlighter.__init__(self, parent)
        self.rules = []
        self.commentStart = QRegExp("#")
        self.commentEnd = QRegExp("\n")
        self.commentFormat = QTextCharFormat()
        self.commentFormat.setFontItalic(True)
        self.commentFormat.setForeground(Qt.darkGray)
        f = QTextCharFormat()
        r = QRegExp()
        r.setMinimal(True)
        f.setFontWeight(QFont.Normal)
        f.setForeground(Qt.darkBlue)
        tagList = ["\\bignore_hosts\\b", "\\bsync_hosts\\b",
                   "\\bignore_nodes\\b", "\\bsync_nodes\\b",
                   "\\bignore_topics\\b", "\\bignore_publishers\\b",
                   "\\bignore_topics\\b", "\\bsync_topics\\b",
                   "\\bignore_subscribers\\b", "\\bsync_services\\b",
                   "\\bsync_topics_on_demand\\b", "\\bsync_remote_nodes\\b"]
        for tag in tagList:
            r.setPattern(tag)
            self.rules.append((QRegExp(r), QTextCharFormat(f)))

        f.setForeground(Qt.darkGreen)
        f.setFontWeight(QFont.Bold)
        attrList = ["\\b\\*|\\*\\B|\\/\\*"]
        for attr in attrList:
            r.setPattern(attr)
            self.rules.append((QRegExp(r), QTextCharFormat(f)))

#    f.setForeground(Qt.red)
#    f.setFontWeight(QFont.Bold)
#    attrList = ["\\s\\*"]
#    for attr in attrList:
#      r.setPattern(attr)
#      self.rules.append((QRegExp(r), QTextCharFormat(f)))

    def highlightBlock(self, text):
        for pattern, myformat in self.rules:
            index = pattern.indexIn(text)
            while index >= 0:
                length = pattern.matchedLength()
                self.setFormat(index, length, myformat)
                index = pattern.indexIn(text, index + length)

        self.setCurrentBlockState(0)
        startIndex = 0
        if self.previousBlockState() != 1:
            startIndex = self.commentStart.indexIn(text)
            if startIndex >= 0:
                commentLength = len(text) - startIndex
                self.setFormat(startIndex, commentLength, self.commentFormat)
예제 #8
0
 def getIncludedFiles(cls, inc_file, regexp_list=[QRegExp("\\binclude\\b"),
                                                  QRegExp("\\btextfile\\b"),
                                                  QRegExp("\\bfile\\b"),
                                                  QRegExp("\\bdefault\\b"),
                                                  QRegExp("\\bvalue=.*pkg:\/\/\\b"),
                                                  QRegExp("\\bvalue=.*package:\/\/\\b"),
                                                  QRegExp("\\bvalue=.*\$\(find\\b")]):
     '''
     Reads the configuration file and searches for included files. This files
     will be returned in a list.
     @param inc_file: path of the ROS launch file
     @param regexp_list: pattern of
     @return: the list with all files needed for the configuration
     @rtype: C{[str,...]}
     '''
     result = set()
     with open(inc_file, '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()
     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, os.path.dirname(inc_file))
                         if os.path.isfile(path):
                             result.add(path)
                             if path.endswith('.launch'):
                                 result.update(cls.getIncludedFiles(path, regexp_list))
                     except:
                         pass
     return list(result)
예제 #9
0
class YamlHighlighter(QSyntaxHighlighter):
    '''
    Enabled the syntax highlightning for the yaml files.
    '''
    def __init__(self, parent=None):
        QSyntaxHighlighter.__init__(self, parent)
        self.rules = []
        self.commentStart = QRegExp("#")
        self.commentEnd = QRegExp("\n|\r")
        self.default_format = QTextCharFormat()
        self.default_format.setForeground(QColor(24, 24, 24))
        self.commentFormat = QTextCharFormat()
        self.commentFormat.setFontItalic(True)
        self.commentFormat.setForeground(Qt.darkGray)

        tagList = ["\\btrue\\b", "\\bfalse\\b"]
        # create patterns for tags
        for tag in tagList:
            self.rules.append(
                (self._create_regexp(tag), self._create_format(Qt.blue)))

        # create pattern for digits
        self.rules.append((self._create_regexp("\\d+"),
                           self._create_format(QColor(127, 64, 127))))

        # create pattern for params
        self.rules.append((self._create_regexp("\s*[_.\w]*\s*:"),
                           self._create_format(Qt.darkBlue)))

        # create pattern for params
        self.rules.append(
            (self._create_regexp(":\s*:[_\.\w]*$|:\s*\@[_\.\w]*$"),
             self._create_format(Qt.darkBlue)))

        # create pattern for list signes
        self.rules.append((self._create_regexp("^\s*-"),
                           self._create_format(Qt.darkRed, 'bold')))

        # create pattern for ???
        self.rules.append(
            (self._create_regexp("^---$"), self._create_format(Qt.darkRed)))

        # create pattern for braces
        self.rules.append((self._create_regexp("[\[\]\{\}\,]"),
                           self._create_format(Qt.darkGreen)))

        # create patterns for strings
        self.rules.append((self._create_regexp("\".*\"|\'.*\'"),
                           self._create_format(Qt.blue)))

        # create patterns for substitutions
        self.rules.append((self._create_regexp("\\$\\(.*\\)"),
                           self._create_format(QColor(127, 64, 127))))

        # create patterns for DOCTYPE
        self.rules.append((self._create_regexp("<!DOCTYPE.*>"),
                           self._create_format(Qt.lightGray)))
        self.rules.append((self._create_regexp("<\\?xml.*\\?>"),
                           self._create_format(Qt.lightGray)))

    def highlightBlock(self, text):
        self.setFormat(0, len(text), self.default_format)
        for pattern, form in self.rules:
            index = pattern.indexIn(text)
            while index >= 0:
                length = pattern.matchedLength()
                self.setFormat(index, length, form)
                index = pattern.indexIn(text, index + length)

        # mark comment blocks
        self.setCurrentBlockState(0)
        startIndex = 0
        if self.previousBlockState() != 1:
            startIndex = self.commentStart.indexIn(text)
            if startIndex >= 0:
                commentLength = len(text) - startIndex
                self.setFormat(startIndex, commentLength, self.commentFormat)

    def _create_regexp(self, pattern=''):
        _regexp = QRegExp()
        _regexp.setMinimal(True)
        _regexp.setPattern(pattern)
        return _regexp

    def _create_format(self, color, style=''):
        _format = QTextCharFormat()
        _format.setForeground(color)
        if 'bold' in style:
            _format.setFontWeight(QFont.Bold)
        else:
            _format.setFontWeight(QFont.Normal)
        if 'italic' in style:
            _format.setFontItalic(True)
        return _format
예제 #10
0
class XmlHighlighter(QSyntaxHighlighter):
    '''
    Enabled the syntax highlightning for the ROS launch files.
    '''

    LAUNCH_LAUNCH_CHILDS = [
        'group', 'node', 'test', 'env', 'remap', 'rosparam', 'param',
        'machine', 'include', 'arg'
    ]
    LAUNCH_LAUNCH_ATTR = {'deprecated=': '"message"'}
    LAUNCH_GROUP_CHILDS = [
        'node', 'test', 'env', 'remap', 'rosparam', 'param', 'machine',
        'include', 'arg'
    ]
    LAUNCH_GROUP_ATTR = {'ns=': '"foo"', 'clear_params=': '"true|false"'}
    LAUNCH_MACHINE_CHILDS = ['env']
    LAUNCH_MACHINE_ATTR = {
        'name=': '"machine-name"',
        'address=': '"blah.willowgarage.com"',
        'env-loader=': '"/opt/ros/fuerte/env.sh"',
        'default=': '"true|false|never"',
        'user='******'"username"',
        'password='******'"passwhat"',
        'timeout=': '"10.0"'
    }
    LAUNCH_NODE_CHILDS = ['env', 'remap', 'rosparam', 'param']
    LAUNCH_NODE_ATTR = {
        'pkg=': '"mypackage"',
        'type=': '"nodetype"',
        'name=': '"nodename"',
        'args=': '"arg1"',
        'machine=': '"machine-name"',
        'respawn=': '"true"',
        'required=': '"true"',
        'ns=': '"foo"',
        'clear_params=': '"true|false"',
        'output=': '"log|screen"',
        'cwd=': '"ROS_HOME|node"',
        'launch-prefix=': '"prefix arguments"'
    }
    LAUNCH_INCLUDE_CHILDS = ['env', 'arg']
    LAUNCH_INCLUDE_ATTR = {
        'file=': '"$(find pkg-name)/path/filename.xml"',
        'ns=': '"foo"',
        'clear_params=': '"true|false"',
        'pass_all_args=': '"true|false"'
    }

    LAUNCH_REMAP_ATTR = {'from=': '"originalname"', 'to=': '"newname"'}
    LAUNCH_ENV_ATTR = {'name=': '"name"', 'value=': '"value"'}
    LAUNCH_PARAM_ATTR = {
        'name=': '"namespace/name"',
        'value=': '"value"',
        'type=': '"str|int|double|bool"',
        'textfile=': '"$(find pkg-name)/path/file.txt"',
        'binfile=': '"$(find pkg-name)/path/file"',
        'command=': '"$(find pkg-name)/exe \'$(find pkg-name)/arg.txt\'"'
    }

    LAUNCH_ROSPARAM_ATTR = {
        'command=': '"load|dump|delete"',
        'file=': '"$(find pkg-name)/path/foo.yaml"',
        'param=': '"name"',
        'ns=': '"foo"',
        'subst_value=': '"true|false"'
    }
    LAUNCH_ARG_ATTR = {
        'name=': '"name"',
        'value=': '"bar"',
        'default=': '"defbar"'
    }
    LAUNCH_TEST_CHILDS = ['env', 'remap', 'rosparam', 'param']
    LAUNCH_TEST_ATTR = {
        'pkg=': '"mypackage"',
        'type=': '"nodetype"',
        'name=': '"nodename"',
        'test-name=': '"test_name"',
        'args=': '"arg1"',
        'ns=': '"foo"',
        'clear_params=': '"true|false"',
        'retry=': '"0"',
        'cwd=': '"ROS_HOME|node"',
        'launch-prefix=': '"prefix arguments"',
        'time-limit=': '"60.0"'
    }

    LAUNCH_CHILDS = {
        'launch': LAUNCH_LAUNCH_CHILDS,
        'group': LAUNCH_GROUP_CHILDS,
        'machine': LAUNCH_MACHINE_CHILDS,
        'node': LAUNCH_NODE_CHILDS,
        'include': LAUNCH_INCLUDE_CHILDS,
        'remap': [],
        'env': [],
        'param': [],
        'rosparam': [],
        'arg': [],
        'test': LAUNCH_TEST_CHILDS
    }

    LAUNCH_ATT_GLOBAL = {'if=': '""', 'unless=': '""'}
    LAUNCH_LAUNCH_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_GROUP_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_MACHINE_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_NODE_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_INCLUDE_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_REMAP_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_ENV_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_PARAM_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_ROSPARAM_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_ARG_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_TEST_ATTR.update(LAUNCH_ATT_GLOBAL)

    LAUNCH_ATTR = {
        'launch': LAUNCH_LAUNCH_ATTR,
        'group': LAUNCH_GROUP_ATTR,
        'machine': LAUNCH_MACHINE_ATTR,
        'node': LAUNCH_NODE_ATTR,
        'include': LAUNCH_INCLUDE_ATTR,
        'remap': LAUNCH_REMAP_ATTR,
        'env': LAUNCH_ENV_ATTR,
        'param': LAUNCH_PARAM_ATTR,
        'rosparam': LAUNCH_ROSPARAM_ATTR,
        'arg': LAUNCH_ARG_ATTR,
        'test': LAUNCH_TEST_ATTR,
    }

    DEPRECATED_PARAMETER = {
        'associations': 'nm/associations',
        'kill_on_stop': 'nm/kill_on_stop',
    }
    STATE_COMMENT = 2
    STATE_STRING = 4

    def __init__(self, parent=None, is_launch=True):
        QSyntaxHighlighter.__init__(self, parent)
        self._is_launch = is_launch
        self.rules = []
        self.comment_start = QRegExp("<!--")
        self.comment_end = QRegExp("-->")
        self.comment_format = self._create_format(Qt.darkGray, 'italic')
        #        self.mark_background = QBrush(QColor(251, 247, 222))
        # create patterns for braces
        self.rules.append((self._create_regexp("</?|/?>"),
                           self._create_format(QColor(24, 24, 24))))
        # create patterns for TAG
        if self._is_launch:
            tag_list = '|'.join(
                ["\\b%s\\b" % t for t in self.LAUNCH_CHILDS.keys()])
            self.rules.append((self._create_regexp(tag_list),
                               self._create_format(Qt.darkRed)))
        else:
            self.rules.append(
                (self._create_regexp(">|/>|<[/.\w:]*[\s\t>]|<[/.\w:]*$"),
                 self._create_format(Qt.darkRed)))
        # create patterns for ATTRIBUTES
        if self._is_launch:
            attr_list = '|'.join(
                set([
                    "\\b%s" % attr for v in self.LAUNCH_ATTR.values()
                    for attr in v.keys()
                ]))
            self.rules.append((self._create_regexp(attr_list),
                               self._create_format(QColor(0, 100,
                                                          0))))  # darkGreen
        else:
            self.rules.append((self._create_regexp("[_.\w]*="),
                               self._create_format(QColor(0, 100,
                                                          0))))  # darkGreen
        # create patterns for substitutions
        self.rule_arg = (self._create_regexp("\\$\\(.*\\)"),
                         self._create_format(QColor(77, 0, 38)))
        # create patterns for DOCTYPE
        self.rules.append((self._create_regexp("<!DOCTYPE.*>"),
                           self._create_format(Qt.lightGray)))
        self.rules.append((self._create_regexp("<\\?xml.*\\?>"),
                           self._create_format(Qt.lightGray)))
        # create patterns for yaml parameter inside
        self.rules.append((self._create_regexp("[_.\w]*\s*:"),
                           self._create_format(Qt.darkBlue)))
        # create patterns for yaml oneline strings inside
        self.rules.append(
            (self._create_regexp("'.*'"), self._create_format(Qt.blue)))
        # create pattern for list signes
        self.rules.append((self._create_regexp("^\s*-"),
                           self._create_format(Qt.darkRed, 'bold')))
        # create pattern for digits
        self.rules.append((self._create_regexp("\\d+"),
                           self._create_format(QColor(127, 64, 127))))
        self.yaml_comment_rule = (self._create_regexp("#[.]*"),
                                  self._create_format(Qt.darkGray))
        # create deprecated
        self.dep_pattern = []
        if self.DEPRECATED_PARAMETER:
            attr_list = '|'.join(
                set([
                    r'name="%s"' % attr
                    for attr in self.DEPRECATED_PARAMETER.keys()
                ]))
            # print(attr_list)
            self.dep_pattern.append(
                (self._create_regexp(attr_list),
                 self._create_format(QColor(250, 0, 0), 'bold')))  # red
        # create patterns for strings
        self.string_pattern = QRegExp("\"")
        self.string_format = self._create_format(Qt.blue)
        # part to select an XML block
        self._tag_hl_range = []  # list with puples (start, length)
        self._tag_hl_last = []  # set with blocks of last highlighted tags
        self._color_hl_tag = QColor(255, 128, 0)

    def _create_regexp(self, pattern=''):
        _regexp = QRegExp()
        _regexp.setMinimal(True)
        _regexp.setPattern(pattern)
        return _regexp

    def _create_format(self, color, style=''):
        _format = QTextCharFormat()
        _format.setForeground(color)
        if 'bold' in style:
            _format.setFontWeight(QFont.Bold)
        else:
            _format.setFontWeight(QFont.Normal)
        if 'italic' in style:
            _format.setFontItalic(True)
        return _format

    def highlightBlock(self, text):
        for pattern, form in self.rules:
            index = pattern.indexIn(text)
            while index >= 0:
                length = pattern.matchedLength()
                frmt = form
                if self._in_hl_range(index, self._tag_hl_range):
                    frmt = QTextCharFormat(form)
                    if not self._end_tag_found:
                        frmt.setForeground(Qt.red)
                    else:
                        frmt.setForeground(self._color_hl_tag)
                    frmt.setFontWeight(QFont.Bold)
                self.setFormat(index, length, frmt)
                index = pattern.indexIn(text, index + length)
        # search for YAML comments
        index = self.yaml_comment_rule[0].indexIn(text)
        if index >= 0:
            self.setFormat(index, len(text) - index, self.yaml_comment_rule[1])
        self._tag_hl_range = []
        self.setCurrentBlockState(0)
        # detection for XML comments
        self._comments_idx = []
        idx_start_cmt = 0
        comment_length = 0
        if self.previousBlockState(
        ) == -1 or not self.previousBlockState() & self.STATE_COMMENT:
            idx_start_cmt = self.comment_start.indexIn(text)
        while idx_start_cmt >= 0:
            idx_end = self.comment_end.indexIn(text, idx_start_cmt)
            comment_length = 0
            if idx_end == -1:
                self.setCurrentBlockState(self.STATE_COMMENT)
                comment_length = len(text) - idx_start_cmt
            else:
                comment_length = idx_end - idx_start_cmt + self.comment_end.matchedLength(
                )
            self._comments_idx.append((idx_start_cmt, comment_length))
            self.setFormat(idx_start_cmt, comment_length, self.comment_format)
            idx_start_cmt = self.comment_start.indexIn(
                text, idx_start_cmt + comment_length)
        # format string and detection for multiline string
        idx_start = self.string_pattern.indexIn(text)
        if self.previousBlockState(
        ) != -1 and self.previousBlockState() & self.STATE_STRING:
            strlen = idx_start + self.string_pattern.matchedLength()
            if idx_start == -1:
                strlen = len(text)
                self.setCurrentBlockState(self.currentBlockState() +
                                          self.STATE_STRING)
            self.setFormat(0, strlen, self.string_format)
            idx_start = self.string_pattern.indexIn(text, strlen)
        idx_search = idx_start + 1
        while idx_start >= 0:
            # skip the strings which are in the comments
            if not self._in_hl_range(idx_search, self._comments_idx):
                idx_end = self.string_pattern.indexIn(text, idx_search)
                strlen = 0
                if not self._in_hl_range(idx_end, self._comments_idx):
                    if idx_end == -1:
                        self.setCurrentBlockState(self.currentBlockState() +
                                                  self.STATE_STRING)
                        strlen = len(text) - idx_start
                    else:
                        strlen = idx_end - idx_start + self.string_pattern.matchedLength(
                        )
                    idx_search = idx_start + strlen
                    self.setFormat(idx_start, strlen, self.string_format)
                    idx_start = self.string_pattern.indexIn(text, idx_search)
                    idx_search = idx_start + 1
                else:
                    idx_search = idx_end + 1
            else:
                idx_start = self.string_pattern.indexIn(text, idx_search)
                idx_search = idx_start + 1
        # mark arguments
        index = self.rule_arg[0].indexIn(text)
        while index >= 0:
            if not self._in_hl_range(index, self._comments_idx):
                length = self.rule_arg[0].matchedLength()
                self.setFormat(index, length, self.rule_arg[1])
            index = self.rule_arg[0].indexIn(text, index + length)
        # mark deprecated parameter
        for pattern, form in self.dep_pattern:
            index = pattern.indexIn(text)
            while index >= 0:
                length = pattern.matchedLength()
                frmt = form
                if self._in_hl_range(index, self._tag_hl_range):
                    frmt = QTextCharFormat(form)
                    if not self._end_tag_found:
                        frmt.setForeground(Qt.red)
                    else:
                        frmt.setForeground(self._color_hl_tag)
                    frmt.setFontWeight(QFont.Bold)
                self.setFormat(index, length, frmt)
                index = pattern.indexIn(text, index + length)

    def mark_block(self, block, position):
        text = block.text()
        word, idx_word = self._get_current_word(text, position)
        for hlblock in self._tag_hl_last:
            self.rehighlightBlock(hlblock)
        del self._tag_hl_last[:]
        self._tag_hl_range = [(idx_word, len(word))]
        next_block = block
        open_braces = 0
        closed_braces = 0
        idx_search = idx_word
        rindex = -1
        loop = 0
        tag_len = 0
        if self._isclosetag(word):
            # we are at the close tag: search for the open tag
            opentag = '<%s' % self._get_tag(word)
            tag_len = len(opentag)
            while rindex == -1 and next_block.isValid():
                rindex = text.rfind(opentag, 0, idx_search)
                obr, cbr = self._get_braces_count(
                    text[rindex if rindex != -1 else 0:idx_search])
                open_braces += obr
                closed_braces += cbr
                loop += 1
                if loop > 50000:
                    rindex = -1
                    break
                if rindex == -1:
                    next_block = next_block.previous()
                    text = next_block.text()
                    idx_search = len(text)
                elif open_braces <= closed_braces:
                    idx_search = rindex
                    rindex = -1
        elif self._isopentag(word):
            # we are at the open tag: search for the close tag
            closetag = QRegExp("</%s>|/>" % self._get_tag(word))
            closetag.setMinimal(True)
            while rindex == -1 and next_block.isValid():
                rindex = closetag.indexIn(text, idx_search)
                max_search_idx = rindex + closetag.matchedLength(
                ) if rindex != -1 else len(text)
                obr, cbr = self._get_braces_count(
                    text[idx_search:max_search_idx])
                open_braces += obr
                closed_braces += cbr
                loop += 1
                if loop > 50000:
                    rindex = -1
                    break
                if rindex == -1:
                    next_block = next_block.next()
                    text = next_block.text()
                    idx_search = 0
                elif open_braces > closed_braces:
                    idx_search = rindex + closetag.matchedLength()
                    rindex = -1
                tag_len = closetag.matchedLength()
        else:
            self._tag_hl_range = []
        self._end_tag_found = rindex != -1
        if self._tag_hl_range and block != next_block:
            self.rehighlightBlock(block)
            self._tag_hl_last.append(block)
        if rindex != -1:
            self._tag_hl_range.append((rindex, tag_len))
            self.rehighlightBlock(next_block)
            self._tag_hl_last.append(next_block)

    def _get_braces_count(self, text):
        closed_short = text.count('/>')
        closed_long = text.count('</')
        cmnt_long = text.count('<!')
        openbr = text.count('<') - closed_long - cmnt_long
        return openbr, closed_short + closed_long

    def _isopentag(self, word):
        return word.startswith('<') and '/' not in word

    def _isclosetag(self, word):
        return '/>' == word or word.startswith('</')

    def _get_tag(self, word):
        return word.strip('</>')

    def _get_current_word(self, text, position):
        word = ''
        idx_start = position
        for i in reversed(range(0, position)):
            if text[i] in [' ', '\n', '=', '"']:
                break
            else:
                word = "%s%s" % (text[i], word)
                idx_start = i
        for i in range(position, len(text)):
            if text[i] in [' ', '\n', '=', '"']:
                break
            else:
                word += text[i]
        return word, idx_start

    def _in_hl_range(self, value, ranges):
        for (start, length) in ranges:
            if value >= start and value <= start + length:
                return True
        return False

    def get_tag_of_current_block(self, block, position):
        text = block.text()
        next_block = block
        idx_search = position
        rindex = -1
        loop = 0
        # we are at the close tag: search for the open tag
        opentag = '<'
        while rindex == -1 and next_block.isValid():
            rindex = text.rfind(opentag, 0, idx_search)
            loop += 1
            if loop > 100:
                rindex = -1
                break
            if rindex == -1:
                next_block = next_block.previous()
                text = next_block.text()
                idx_search = len(text)
        tag = ''
        if rindex != -1:
            for i in range(rindex + 1, len(text)):
                if text[i] in [' ', '\n', '=', '"', '>']:
                    break
                else:
                    tag += text[i]
        return tag
예제 #11
0
 def mark_block(self, block, position):
     text = block.text()
     word, idx_word = self._get_current_word(text, position)
     for hlblock in self._tag_hl_last:
         self.rehighlightBlock(hlblock)
     del self._tag_hl_last[:]
     self._tag_hl_range = [(idx_word, len(word))]
     next_block = block
     open_braces = 0
     closed_braces = 0
     idx_search = idx_word
     rindex = -1
     loop = 0
     tag_len = 0
     if self._isclosetag(word):
         # we are at the close tag: search for the open tag
         opentag = '<%s' % self._get_tag(word)
         tag_len = len(opentag)
         while rindex == -1 and next_block.isValid():
             rindex = text.rfind(opentag, 0, idx_search)
             obr, cbr = self._get_braces_count(
                 text[rindex if rindex != -1 else 0:idx_search])
             open_braces += obr
             closed_braces += cbr
             loop += 1
             if loop > 50000:
                 rindex = -1
                 break
             if rindex == -1:
                 next_block = next_block.previous()
                 text = next_block.text()
                 idx_search = len(text)
             elif open_braces <= closed_braces:
                 idx_search = rindex
                 rindex = -1
     elif self._isopentag(word):
         # we are at the open tag: search for the close tag
         closetag = QRegExp("</%s>|/>" % self._get_tag(word))
         closetag.setMinimal(True)
         while rindex == -1 and next_block.isValid():
             rindex = closetag.indexIn(text, idx_search)
             max_search_idx = rindex + closetag.matchedLength(
             ) if rindex != -1 else len(text)
             obr, cbr = self._get_braces_count(
                 text[idx_search:max_search_idx])
             open_braces += obr
             closed_braces += cbr
             loop += 1
             if loop > 50000:
                 rindex = -1
                 break
             if rindex == -1:
                 next_block = next_block.next()
                 text = next_block.text()
                 idx_search = 0
             elif open_braces > closed_braces:
                 idx_search = rindex + closetag.matchedLength()
                 rindex = -1
             tag_len = closetag.matchedLength()
     else:
         self._tag_hl_range = []
     self._end_tag_found = rindex != -1
     if self._tag_hl_range and block != next_block:
         self.rehighlightBlock(block)
         self._tag_hl_last.append(block)
     if rindex != -1:
         self._tag_hl_range.append((rindex, tag_len))
         self.rehighlightBlock(next_block)
         self._tag_hl_last.append(next_block)
예제 #12
0
class XmlHighlighter(QSyntaxHighlighter):
    '''
    Enabled the syntax highlightning for the ROS launch files.
    '''

    LAUNCH_LAUNCH_CHILDS = ['group', 'node', 'test', 'env', 'remap', 'rosparam', 'param', 'machine', 'include', 'arg']
    LAUNCH_LAUNCH_ATTR = {'deprecated=': '"message"'}
    LAUNCH_GROUP_CHILDS = ['node', 'test', 'env', 'remap', 'rosparam', 'param', 'machine', 'include', 'arg']
    LAUNCH_GROUP_ATTR = {'ns=': '"foo"',
                         'clear_params=': '"true|false"'
                         }
    LAUNCH_MACHINE_CHILDS = ['env']
    LAUNCH_MACHINE_ATTR = {'name=': '"machine-name"',
                           'address=': '"blah.willowgarage.com"',
                           'env-loader=': '"/opt/ros/fuerte/env.sh"',
                           'default=': '"true|false|never"',
                           'user='******'"username"',
                           'password='******'"passwhat"',
                           'timeout=': '"10.0"'
                           }
    LAUNCH_NODE_CHILDS = ['env', 'remap', 'rosparam', 'param']
    LAUNCH_NODE_ATTR = {'pkg=': '"mypackage"',
                        'type=': '"nodetype"',
                        'name=': '"nodename"',
                        'args=': '"arg1"',
                        'machine=': '"machine-name"',
                        'respawn=': '"true"',
                        'required=': '"true"',
                        'ns=': '"foo"',
                        'clear_params=': '"true|false"',
                        'output=': '"log|screen"',
                        'cwd=': '"ROS_HOME|node"',
                        'launch-prefix=': '"prefix arguments"'
                        }
    LAUNCH_INCLUDE_CHILDS = ['env', 'arg']
    LAUNCH_INCLUDE_ATTR = {'file=': '"$(find pkg-name)/path/filename.xml"',
                           'ns=': '"foo"',
                           'clear_params=': '"true|false"'
                           }

    LAUNCH_REMAP_ATTR = {'from=': '"originalname"',
                         'to=': '"newname"'
                         }
    LAUNCH_ENV_ATTR = {'name=': '"name"',
                       'value=': '"value"'
                       }
    LAUNCH_PARAM_ATTR = {'name=': '"namespace/name"',
                         'value=': '"value"',
                         'type=': '"str|int|double|bool"',
                         'textfile=': '"$(find pkg-name)/path/file.txt"',
                         'binfile=': '"$(find pkg-name)/path/file"',
                         'command=': '"$(find pkg-name)/exe \'$(find pkg-name)/arg.txt\'"'
                         }

    LAUNCH_ROSPARAM_ATTR = {'command=': '"load|dump|delete"',
                            'file=': '"$(find pkg-name)/path/foo.yaml"',
                            'param=': '"name"',
                            'ns=': '"foo"',
                            'subst_value=': '"true|false"'
                            }
    LAUNCH_ARG_ATTR = {'name=': '"name"',
                       'value=': '"bar"',
                       'default=': '"defbar"'
                       }
    LAUNCH_TEST_CHILDS = ['env', 'remap', 'rosparam', 'param']
    LAUNCH_TEST_ATTR = {'pkg=': '"mypackage"',
                        'type=': '"nodetype"',
                        'name=': '"nodename"',
                        'test-name=': '"test_name"',
                        'args=': '"arg1"',
                        'ns=': '"foo"',
                        'clear_params=': '"true|false"',
                        'retry=': '"0"',
                        'cwd=': '"ROS_HOME|node"',
                        'launch-prefix=': '"prefix arguments"',
                        'time-limit=': '"60.0"'
                        }

    LAUNCH_CHILDS = {'launch': LAUNCH_LAUNCH_CHILDS,
                     'group': LAUNCH_GROUP_CHILDS,
                     'machine': LAUNCH_MACHINE_CHILDS,
                     'node': LAUNCH_NODE_CHILDS,
                     'include': LAUNCH_INCLUDE_CHILDS,
                     'remap': [],
                     'env': [],
                     'param': [],
                     'rosparam': [],
                     'arg': [],
                     'test': LAUNCH_TEST_CHILDS
                     }

    LAUNCH_ATT_GLOBAL = {'if=': '""', 'unless=': '""'}
    LAUNCH_LAUNCH_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_GROUP_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_MACHINE_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_NODE_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_INCLUDE_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_REMAP_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_ENV_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_PARAM_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_ROSPARAM_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_ARG_ATTR.update(LAUNCH_ATT_GLOBAL)
    LAUNCH_TEST_ATTR.update(LAUNCH_ATT_GLOBAL)

    LAUNCH_ATTR = {'launch': LAUNCH_LAUNCH_ATTR,
                   'group': LAUNCH_GROUP_ATTR,
                   'machine': LAUNCH_MACHINE_ATTR,
                   'node': LAUNCH_NODE_ATTR,
                   'include': LAUNCH_INCLUDE_ATTR,
                   'remap': LAUNCH_REMAP_ATTR,
                   'env': LAUNCH_ENV_ATTR,
                   'param': LAUNCH_PARAM_ATTR,
                   'rosparam': LAUNCH_ROSPARAM_ATTR,
                   'arg': LAUNCH_ARG_ATTR,
                   'test': LAUNCH_TEST_ATTR,
                   }

    STATE_COMMENT = 2
    STATE_STRING = 4

    def __init__(self, parent=None):
        QSyntaxHighlighter.__init__(self, parent)
        self.rules = []
        self.comment_start = QRegExp("<!--")
        self.comment_end = QRegExp("-->")
        self.comment_format = self._create_format(Qt.darkGray, 'italic')
#        self.mark_background = QBrush(QColor(251, 247, 222))
        # create patterns for braces
        self.rules.append((self._create_regexp("</?|/?>"), self._create_format(QColor(24, 24, 24))))
        # create patterns for TAG
        tag_list = '|'.join(["\\b%s\\b" % t for t in self.LAUNCH_CHILDS.keys()])
        self.rules.append((self._create_regexp(tag_list), self._create_format(Qt.darkRed)))
        # create patterns for ATTRIBUTES
        attr_list = '|'.join(set(["\\b%s" % attr for v in self.LAUNCH_ATTR.values() for attr in v.keys()]))
        self.rules.append((self._create_regexp(attr_list), self._create_format(QColor(0, 100, 0))))  # darkGreen
        # create patterns for substitutions
        self.rule_arg = (self._create_regexp("\\$\\(.*\\)"), self._create_format(QColor(77, 0, 38)))
        # create patterns for DOCTYPE
        self.rules.append((self._create_regexp("<!DOCTYPE.*>"), self._create_format(Qt.lightGray)))
        self.rules.append((self._create_regexp("<\\?xml.*\\?>"), self._create_format(Qt.lightGray)))
        # create patterns for yaml parameter inside
        self.rules.append((self._create_regexp("^\s*[_.\w]*\s*:"), self._create_format(Qt.darkBlue)))
        # create patterns for yaml oneline strings inside
        self.rules.append((self._create_regexp("'.*'"), self._create_format(Qt.blue)))
        # create pattern for list signes
        self.rules.append((self._create_regexp("^\s*-"), self._create_format(Qt.darkRed, 'bold')))
        # create pattern for digits
        self.rules.append((self._create_regexp("\\d+"), self._create_format(QColor(127, 64, 127))))
        # create patterns for strings
        self.string_pattern = QRegExp("\"")
        self.string_format = self._create_format(Qt.blue)
        # part to select an XML block
        self._tag_hl_range = []  # list with puples (start, length)
        self._tag_hl_last = set()  # set with blocks of last highlighted tags

    def _create_regexp(self, pattern=''):
        _regexp = QRegExp()
        _regexp.setMinimal(True)
        _regexp.setPattern(pattern)
        return _regexp

    def _create_format(self, color, style=''):
        _format = QTextCharFormat()
        _format.setForeground(color)
        if 'bold' in style:
            _format.setFontWeight(QFont.Bold)
        else:
            _format.setFontWeight(QFont.Normal)
        if 'italic' in style:
            _format.setFontItalic(True)
        return _format

    def highlightBlock(self, text):
        for pattern, form in self.rules:
            index = pattern.indexIn(text)
            while index >= 0:
                length = pattern.matchedLength()
                frmt = form
                if self._in_hl_range(index, self._tag_hl_range):
                    frmt = QTextCharFormat(form)
                    if not self._end_tag_found:
                        frmt.setForeground(Qt.red)
                    frmt.setFontWeight(QFont.Bold)
                self.setFormat(index, length, frmt)
                index = pattern.indexIn(text, index + length)
        self._tag_hl_range = []
        self.setCurrentBlockState(0)
        # detection for comments
        self._comments_idx = []
        idx_start_cmt = 0
        comment_length = 0
        if self.previousBlockState() == -1 or not self.previousBlockState() & self.STATE_COMMENT:
            idx_start_cmt = self.comment_start.indexIn(text)
        while idx_start_cmt >= 0:
            idx_end = self.comment_end.indexIn(text, idx_start_cmt)
            comment_length = 0
            if idx_end == -1:
                self.setCurrentBlockState(self.STATE_COMMENT)
                comment_length = len(text) - idx_start_cmt
            else:
                comment_length = idx_end - idx_start_cmt + self.comment_end.matchedLength()
            self._comments_idx.append((idx_start_cmt, comment_length))
            self.setFormat(idx_start_cmt, comment_length, self.comment_format)
            idx_start_cmt = self.comment_start.indexIn(text, idx_start_cmt + comment_length)
        # format string and detection for multiline string
        idx_start = self.string_pattern.indexIn(text)
        if self.previousBlockState() != -1 and self.previousBlockState() & self.STATE_STRING:
            strlen = idx_start + self.string_pattern.matchedLength()
            if idx_start == -1:
                strlen = len(text)
                self.setCurrentBlockState(self.currentBlockState() + self.STATE_STRING)
            self.setFormat(0, strlen, self.string_format)
            idx_start = self.string_pattern.indexIn(text, strlen)
        idx_search = idx_start + 1
        while idx_start >= 0:
            # skip the strings which are in the comments
            if not self._in_hl_range(idx_search, self._comments_idx):
                idx_end = self.string_pattern.indexIn(text, idx_search)
                strlen = 0
                if not self._in_hl_range(idx_end, self._comments_idx):
                    if idx_end == -1:
                        self.setCurrentBlockState(self.currentBlockState() + self.STATE_STRING)
                        strlen = len(text) - idx_start
                    else:
                        strlen = idx_end - idx_start + self.string_pattern.matchedLength()
                    idx_search = idx_start + strlen
                    self.setFormat(idx_start, strlen, self.string_format)
                    idx_start = self.string_pattern.indexIn(text, idx_search)
                    idx_search = idx_start + 1
                else:
                    idx_search = idx_end + 1
            else:
                idx_start = self.string_pattern.indexIn(text, idx_search)
                idx_search = idx_start + 1
        # mark arguments
        index = self.rule_arg[0].indexIn(text)
        while index >= 0:
            if not self._in_hl_range(index, self._comments_idx):
                length = self.rule_arg[0].matchedLength()
                self.setFormat(index, length, self.rule_arg[1])
            index = self.rule_arg[0].indexIn(text, index + length)

    def mark_block(self, block, position):
        text = block.text()
        word, idx_word = self._get_current_word(text, position)
        for hlblock in self._tag_hl_last:
            self.rehighlightBlock(hlblock)
        self._tag_hl_last.clear()
        self._tag_hl_range = [(idx_word, len(word))]
        next_block = block
        open_braces = 0
        closed_braces = 0
        idx_search = idx_word
        rindex = -1
        loop = 0
        tag_len = 0
        if self._isclosetag(word):
            # we are at the close tag: search for the open tag
            opentag = '<%s' % self._get_tag(word)
            tag_len = len(opentag)
            while rindex == -1 and next_block.isValid():
                rindex = text.rfind(opentag, 0, idx_search)
                obr, cbr = self._get_braces_count(text[rindex if rindex != -1 else 0:idx_search])
                open_braces += obr
                closed_braces += cbr
                loop += 1
                if loop > 50000:
                    rindex = -1
                    break
                if rindex == -1:
                    next_block = next_block.previous()
                    text = next_block.text()
                    idx_search = len(text)
                elif open_braces <= closed_braces:
                    idx_search = rindex
                    rindex = -1
        elif self._isopentag(word):
            # we are at the open tag: search for the close tag
            closetag = QRegExp("</%s>|/>" % self._get_tag(word))
            closetag.setMinimal(True)
            while rindex == -1 and next_block.isValid():
                rindex = closetag.indexIn(text, idx_search)
                max_search_idx = rindex + closetag.matchedLength() if rindex != -1 else len(text)
                obr, cbr = self._get_braces_count(text[idx_search:max_search_idx])
                open_braces += obr
                closed_braces += cbr
                loop += 1
                if loop > 50000:
                    rindex = -1
                    break
                if rindex == -1:
                    next_block = next_block.next()
                    text = next_block.text()
                    idx_search = 0
                elif open_braces > closed_braces:
                    idx_search = rindex + closetag.matchedLength()
                    rindex = -1
                tag_len = closetag.matchedLength()
        else:
            self._tag_hl_range = []
        self._end_tag_found = rindex != -1
        if self._tag_hl_range and block != next_block:
            self.rehighlightBlock(block)
            self._tag_hl_last.add(block)
        if rindex != -1:
            self._tag_hl_range.append((rindex, tag_len))
            self.rehighlightBlock(next_block)
            self._tag_hl_last.add(next_block)

    def _get_braces_count(self, text):
        closed_short = text.count('/>')
        closed_long = text.count('</')
        cmnt_long = text.count('<!')
        openbr = text.count('<') - closed_long - cmnt_long
        return openbr, closed_short + closed_long

    def _isopentag(self, word):
        return word.startswith('<') and '/' not in word

    def _isclosetag(self, word):
        return '/>' == word or word.startswith('</')

    def _get_tag(self, word):
        return word.strip('</>')

    def _get_current_word(self, text, position):
        word = ''
        idx_start = position
        for i in reversed(range(0, position)):
            if text[i] in [' ', '\n', '=', '"']:
                break
            else:
                word = "%s%s" % (text[i], word)
                idx_start = i
        for i in range(position, len(text)):
            if text[i] in [' ', '\n', '=', '"']:
                break
            else:
                word += text[i]
        return word, idx_start

    def _in_hl_range(self, value, ranges):
        for (start, length) in ranges:
            if value >= start and value <= start + length:
                return True
        return False

    def get_tag_of_current_block(self, block, position):
        text = block.text()
        next_block = block
        idx_search = position
        rindex = -1
        loop = 0
        # we are at the close tag: search for the open tag
        opentag = '<'
        while rindex == -1 and next_block.isValid():
            rindex = text.rfind(opentag, 0, idx_search)
            loop += 1
            if loop > 100:
                rindex = -1
                break
            if rindex == -1:
                next_block = next_block.previous()
                text = next_block.text()
                idx_search = len(text)
        tag = ''
        if rindex != -1:
            for i in range(rindex + 1, len(text)):
                if text[i] in [' ', '\n', '=', '"', '>']:
                    break
                else:
                    tag += text[i]
        return tag
예제 #13
0
 def mark_block(self, block, position):
     text = block.text()
     word, idx_word = self._get_current_word(text, position)
     for hlblock in self._tag_hl_last:
         self.rehighlightBlock(hlblock)
     self._tag_hl_last.clear()
     self._tag_hl_range = [(idx_word, len(word))]
     next_block = block
     open_braces = 0
     closed_braces = 0
     idx_search = idx_word
     rindex = -1
     loop = 0
     tag_len = 0
     if self._isclosetag(word):
         # we are at the close tag: search for the open tag
         opentag = '<%s' % self._get_tag(word)
         tag_len = len(opentag)
         while rindex == -1 and next_block.isValid():
             rindex = text.rfind(opentag, 0, idx_search)
             obr, cbr = self._get_braces_count(text[rindex if rindex != -1 else 0:idx_search])
             open_braces += obr
             closed_braces += cbr
             loop += 1
             if loop > 50000:
                 rindex = -1
                 break
             if rindex == -1:
                 next_block = next_block.previous()
                 text = next_block.text()
                 idx_search = len(text)
             elif open_braces <= closed_braces:
                 idx_search = rindex
                 rindex = -1
     elif self._isopentag(word):
         # we are at the open tag: search for the close tag
         closetag = QRegExp("</%s>|/>" % self._get_tag(word))
         closetag.setMinimal(True)
         while rindex == -1 and next_block.isValid():
             rindex = closetag.indexIn(text, idx_search)
             max_search_idx = rindex + closetag.matchedLength() if rindex != -1 else len(text)
             obr, cbr = self._get_braces_count(text[idx_search:max_search_idx])
             open_braces += obr
             closed_braces += cbr
             loop += 1
             if loop > 50000:
                 rindex = -1
                 break
             if rindex == -1:
                 next_block = next_block.next()
                 text = next_block.text()
                 idx_search = 0
             elif open_braces > closed_braces:
                 idx_search = rindex + closetag.matchedLength()
                 rindex = -1
             tag_len = closetag.matchedLength()
     else:
         self._tag_hl_range = []
     self._end_tag_found = rindex != -1
     if self._tag_hl_range and block != next_block:
         self.rehighlightBlock(block)
         self._tag_hl_last.add(block)
     if rindex != -1:
         self._tag_hl_range.append((rindex, tag_len))
         self.rehighlightBlock(next_block)
         self._tag_hl_last.add(next_block)
예제 #14
0
class LoggerHandler(QObject):
    '''
    Handles ROS logger requests
    '''

    loggers_signal = Signal(list)
    level_changed_signal = Signal(list)

    def __init__(self, nodename, masteruri, layout, parent=None):
        '''
        Creates a new item.
        '''
        QObject.__init__(self, parent)
        self.setObjectName("LoggerHandler")
        self.nodename = nodename
        self.masteruri = masteruri
        self._filter = QRegExp('', Qt.CaseInsensitive, QRegExp.Wildcard)
        self._logger_items = {}  # logger name: LoggerItem
        self.layout = layout
        self._change_all_cancel = False
        self._stored_values = {}
        self.loggers_signal.connect(self._handle_loggers)
        self._thread_update = None
        self._thread_set_all = None
        self._all_item = LoggerItem(self.nodename, self.masteruri, 'all', '')
        self._all_item.set_callback(self.change_all)

    def update(self):
        if self._thread_update is None:
            self._thread_update = threading.Thread(target=self._update_loggers)
            self._thread_update.setDaemon(True)
            self._thread_update.start()

    def _update_loggers(self):
        try:
            service_name = '%s/get_loggers' % self.nodename
            master = xmlrpcclient.ServerProxy(self.masteruri)
            code, _, serviceuri = master.lookupService(rospy.get_name(),
                                                       service_name)
            if code == 1:
                _req, resp = nm.starter().callService(serviceuri,
                                                      service_name,
                                                      GetLoggers,
                                                      service_args=[])
                self.loggers_signal.emit(resp.loggers)
        except (rospy.ServiceException, nm.StartException) as e:
            rospy.logwarn("Get loggers for %s failed: %s" % (self.nodename, e))
        except IOError as err:
            rospy.logwarn(
                "Get loggers for %s failed; cannot get service URI from %s: %s"
                % (self.nodename, self.masteruri, err))
        self._thread_update = None

    def _handle_loggers(self, loggers):
        new_logger = {}
        for logger in loggers:
            new_logger[logger.name] = logger.level
            self._stored_values[logger.name] = logger.level
        while self.layout.count() > 1:
            item = self.layout.takeAt(0)
            wd = item.widget()
            if wd.current_level is not None and wd.loggername != 'all':
                self._stored_values[wd.loggername] = wd.current_level
            wd.setParent(None)
        self._logger_items.clear()
        index = 0
        if not 'all' in self._stored_values:
            self.layout.insertWidget(0, self._all_item)
            index += 1
        for logger_name, logger_level in sorted(self._stored_values.items()):
            item = LoggerItem(self.nodename, self.masteruri, logger_name,
                              logger_level)
            self._logger_items[logger_name] = item
            if (not logger_name
                    in new_logger) or new_logger[logger_name] != logger_level:
                item.set_level(logger_level, True)
            self.layout.insertWidget(index, item)
            index += 1
            if self._filter.indexIn(logger.name) == -1:
                item.setVisible(False)

    def change_all(self,
                   loglevel,
                   ignore=[
                       'ros.roscpp.roscpp_internal',
                       'ros.roscpp.roscpp_internal.connections',
                       'ros.roscpp.superdebug', 'rospy.tcpros'
                   ]):
        '''
        Change the log level of all logger in a new thread.
        '''
        if self._thread_set_all is not None:
            self._thread_set_all.cancel()
            self._thread_set_all.success_signal.disconnect()
            self._thread_set_all.error_signal.disconnect()
        index = 1
        itemlist = []
        while index < self.layout.count():
            item = self.layout.itemAt(index).widget()
            if isinstance(item, LoggerItem) and item.loggername not in ignore:
                itemlist.append((item.loggername, item.current_level))
            index += 1
        self._thread_set_all = SetAllThread(self.nodename, self.masteruri,
                                            itemlist, loglevel)
        self._thread_set_all.success_signal.connect(self.on_success_set)
        self._thread_set_all.error_signal.connect(self.on_error_set)
        self._thread_set_all.setDaemon(True)
        self._thread_set_all.start()

    def on_success_set(self, nodename, logger, level):
        if logger in self._logger_items:
            self._logger_items[logger].on_succes_update(level)
        elif logger == 'all':
            self._all_item.on_succes_update(level)

    def on_error_set(self, nodename, logger, level):
        if logger in self._logger_items:
            self._logger_items[logger].on_error_update(level)
        elif logger == 'all':
            self._all_item.on_error_update(level)

    def filter(self, text):
        self._filter = QRegExp(text, Qt.CaseInsensitive, QRegExp.Wildcard)
        for name, item in self._logger_items.items():
            hidden = self._filter.indexIn(name) != -1
            item.setVisible(hidden)
예제 #15
0
class YamlHighlighter(QSyntaxHighlighter):
    '''
    Enabled the syntax highlightning for the yaml files.
    '''

    def __init__(self, parent=None):
        QSyntaxHighlighter.__init__(self, parent)
        self.rules = []
        self.commentStart = QRegExp("#")
        self.commentEnd = QRegExp("\n|\r")
        self.default_format = QTextCharFormat()
        self.default_format.setForeground(QColor(24, 24, 24))
        self.commentFormat = QTextCharFormat()
        self.commentFormat.setFontItalic(True)
        self.commentFormat.setForeground(Qt.darkGray)

        tagList = ["\\btrue\\b", "\\bfalse\\b"]
        # create patterns for tags
        for tag in tagList:
            self.rules.append((self._create_regexp(tag), self._create_format(Qt.blue)))

        # create pattern for digits
        self.rules.append((self._create_regexp("\\d+"), self._create_format(QColor(127, 64, 127))))

        # create pattern for params
        self.rules.append((self._create_regexp("^\s*[_.\w]*\s*:"), self._create_format(Qt.darkBlue)))

        # create pattern for params
        self.rules.append((self._create_regexp(":\s*:[_\.\w]*$|:\s*\@[_\.\w]*$"), self._create_format(Qt.darkBlue)))

        # create pattern for list signes
        self.rules.append((self._create_regexp("^\s*-"), self._create_format(Qt.darkRed, 'bold')))

        # create pattern for ???
        self.rules.append((self._create_regexp("^---$"), self._create_format(Qt.darkRed)))

        # create pattern for braces
        self.rules.append((self._create_regexp("[\[\]\{\}\,]"), self._create_format(Qt.darkGreen)))

        # create patterns for strings
        self.rules.append((self._create_regexp("\".*\"|\'.*\'"), self._create_format(Qt.blue)))

        # create patterns for substitutions
        self.rules.append((self._create_regexp("\\$\\(.*\\)"), self._create_format(QColor(127, 64, 127))))

        # create patterns for DOCTYPE
        self.rules.append((self._create_regexp("<!DOCTYPE.*>"), self._create_format(Qt.lightGray)))
        self.rules.append((self._create_regexp("<\\?xml.*\\?>"), self._create_format(Qt.lightGray)))

    def highlightBlock(self, text):
        self.setFormat(0, len(text), self.default_format)
        for pattern, form in self.rules:
            index = pattern.indexIn(text)
            while index >= 0:
                length = pattern.matchedLength()
                self.setFormat(index, length, form)
                index = pattern.indexIn(text, index + length)

        # mark comment blocks
        self.setCurrentBlockState(0)
        startIndex = 0
        if self.previousBlockState() != 1:
            startIndex = self.commentStart.indexIn(text)
            if startIndex >= 0:
                commentLength = len(text) - startIndex
                self.setFormat(startIndex, commentLength, self.commentFormat)

    def _create_regexp(self, pattern=''):
        _regexp = QRegExp()
        _regexp.setMinimal(True)
        _regexp.setPattern(pattern)
        return _regexp

    def _create_format(self, color, style=''):
        _format = QTextCharFormat()
        _format.setForeground(color)
        if 'bold' in style:
            _format.setFontWeight(QFont.Bold)
        else:
            _format.setFontWeight(QFont.Normal)
        if 'italic' in style:
            _format.setFontItalic(True)
        return _format