Example #1
0
    def findByNodePath(self, nodePath):
        """ Recursively searches for the child having the nodePath. Starts at self.
        """
        def _auxGetByPath(parts, item):
            "Aux function that does the actual recursive search"
            #logger.debug("_auxGetByPath item={}, parts={}".format(item, parts))

            if len(parts) == 0:
                return item

            head, tail = parts[0], parts[1:]
            if head == '':
                # Two consecutive slashes. Just go one level deeper.
                return _auxGetByPath(tail, item)
            else:
                childItem = item.childByNodeName(head)
                return _auxGetByPath(tail, childItem)

        # The actual body of findByNodePath starts here

        check_is_a_string(nodePath)
        assert not nodePath.startswith(
            '/'), "nodePath may not start with a slash"

        if not nodePath:
            raise IndexError("Item not found: {!r}".format(nodePath))

        return _auxGetByPath(nodePath.split('/'), self)
Example #2
0
    def __init__(self, nodeName, defaultFamily='Helvetica'):
        """ Constructor.

            :param defaultFamily: A string representing the defaultValue.
            :editable: True if the underlying QFontComboBox is editable. The default is False as
                it does not work well with the FontCti.

            For the (other) parameters see the AbstractCti constructor documentation.
        """
        check_is_a_string(defaultFamily)

        # Get a list of of configValues by reading them from a temporary QFontComboBox.
        tempFontComboBox = QtWidgets.QFontComboBox()
        configValues = []
        defaultData = 0
        for idx in range(tempFontComboBox.count()):
            fontFamily = tempFontComboBox.itemText(idx)
            configValues.append(fontFamily)
            if fontFamily.lower() == defaultFamily.lower():
                defaultData = idx

        # Set after self._displayValues are defined. The parent constructor calls _enforceDataType
        super(FontChoiceCti, self).__init__(nodeName,
                                            defaultData,
                                            configValues=configValues)
Example #3
0
    def findItemAndIndexPath(self, path, startIndex=None):
        """ Searches all the model recursively (starting at startIndex) for an item where
            item.nodePath == path.

            Returns list of (item, itemIndex) tuples from the start index to that node.
            Raises IndexError if the item cannot be found.

            If startIndex is None, or path starts with a slash, searching begins at the (invisible)
            root item.
        """
        def _getIndexAndItemByName(nodeName, parentItem, parentIndex):
            """ Searches the parent for a direct child having the nodeName.
                Returns (item, itemIndex) tuple. Raises IndexError if the item cannot be found.
            """
            if self.canFetchMore(parentIndex):
                self.fetchMore(parentIndex)

            for rowNr, childItem in enumerate(parentItem.childItems):
                if childItem.nodeName == nodeName:
                    childIndex = self.index(rowNr, 0, parentIndex=parentIndex)
                    return (childItem, childIndex)
            raise IndexError("Item not found: {!r}".format(path))

        def _auxGetByPath(parts, item, index):
            "Aux function that does the actual recursive search"
            #logger.debug("_auxGetByPath item={}, parts={}".format(item, parts))

            if len(parts) == 0:
                return [(item, index)]

            head, tail = parts[0], parts[1:]
            if head == '':
                # Two consecutive slashes. Just go one level deeper.
                return _auxGetByPath(tail, item, index)
            else:
                childItem, childIndex = _getIndexAndItemByName(
                    head, item, index)
                return [(item, index)] + _auxGetByPath(tail, childItem,
                                                       childIndex)

        # The actual body of findItemAndIndexPath starts here

        check_is_a_string(path)
        if not path:
            raise IndexError("Item not found: {!r}".format(path))

        if startIndex is None or path.startswith('/'):
            startIndex = QtCore.QModelIndex()
            startItem = self.invisibleRootItem
        else:
            startItem = self.getItem(startIndex, None)

        if not startItem:
            raise IndexError(
                "Item not found: {!r}. No start item!".format(path))

        return _auxGetByPath(path.split('/'), startItem, startIndex)
Example #4
0
    def __init__(self, collector, msg, parent=None):

        super(ErrorMsgInspector, self).__init__(collector, parent=parent)

        check_is_a_string(msg)
        self.msg = msg

        self._config = self._createConfig()

        self.setCurrentIndex(self.ERROR_PAGE_IDX)
Example #5
0
    def findItemAndIndexPath(self, path, startIndex=None):
        """ Searches all the model recursively (starting at startIndex) for an item where
            item.nodePath == path.

            Returns list of (item, itemIndex) tuples from the start index to that node.
            Raises IndexError if the item cannot be found.

            If startIndex is None, or path starts with a slash, searching begins at the (invisible)
            root item.
        """
        def _getIndexAndItemByName(nodeName, parentItem, parentIndex):
            """ Searches the parent for a direct child having the nodeName.
                Returns (item, itemIndex) tuple. Raises IndexError if the item cannot be found.
            """
            if self.canFetchMore(parentIndex):
                self.fetchMore(parentIndex)

            for rowNr, childItem in enumerate(parentItem.childItems):
                if childItem.nodeName == nodeName:
                    childIndex = self.index(rowNr, 0, parentIndex=parentIndex)
                    return (childItem, childIndex)
            raise IndexError("Item not found: {!r}".format(path))


        def _auxGetByPath(parts, item, index):
            "Aux function that does the actual recursive search"
            #logger.debug("_auxGetByPath item={}, parts={}".format(item, parts))

            if len(parts) == 0:
                return [(item, index)]

            head, tail = parts[0], parts[1:]
            if head == '':
                # Two consecutive slashes. Just go one level deeper.
                return _auxGetByPath(tail, item, index)
            else:
                childItem, childIndex = _getIndexAndItemByName(head, item, index)
                return [(item, index)] + _auxGetByPath(tail, childItem, childIndex)

        # The actual body of findItemAndIndexPath starts here

        check_is_a_string(path)
        if not path:
            raise IndexError("Item not found: {!r}".format(path))

        if startIndex is None or path.startswith('/'):
            startIndex = QtCore.QModelIndex()
            startItem = self.invisibleRootItem
        else:
            startItem = self.getItem(startIndex, None)

        if not startItem:
            raise IndexError("Item not found: {!r}. No start item!".format(path))

        return _auxGetByPath(path.split('/'), startItem, startIndex)
Example #6
0
    def _registerExtension(self, extension, rtiRegItem):
        """ Links an file name extension to a repository tree item.
        """
        check_is_a_string(extension)
        check_class(rtiRegItem, RtiRegItem)

        logger.debug("  Registering extension {!r} for {}".format(extension, rtiRegItem))

        # TODO: type checking
        if extension in self._extensionMap:
            logger.info("Overriding extension {!r}: old={}, new={}"
                        .format(extension, self._extensionMap[extension], rtiRegItem))
        self._extensionMap[extension] = rtiRegItem
Example #7
0
    def _registerExtension(self, extension, rtiRegItem):
        """ Links an file name extension to a repository tree item.
        """
        check_is_a_string(extension)
        check_class(rtiRegItem, RtiRegItem)

        logger.debug("  Registering extension {!r} for {}".format(
            extension, rtiRegItem))

        # TODO: type checking
        if extension in self._extensionMap:
            logger.info("Overriding extension {!r}: old={}, new={}".format(
                extension, self._extensionMap[extension], rtiRegItem))
        self._extensionMap[extension] = rtiRegItem
Example #8
0
def makeReplacementField(formatSpec, altFormatSpec='', testValue=None):
    """ Prepends a colon and wraps the formatSpec in curly braces to yield a replacement field.

        The format specification is part of a replacement field, which can be used in new-style
        string formatting. See:
            https://docs.python.org/3/library/string.html#format-string-syntax
            https://docs.python.org/3/library/string.html#format-specification-mini-language

        If the formatSpec does not contain a colon or exclamation mark, a colon is prepended.

        If the formatSpec starts and end in quotes (single or double) only the quotes are removed,
        no curly braces or colon charactes are added. This allows users to define a format spec.

        :param formatSpec: e.g. '5.2f' will return '{:5.2f}'
        :param altFormatSpec: alternative that will be used if the formatSpec evaluates to False
        :param testValue: if not None, result.format(testValue) will be evaluated as a test.
        :return: string
    """
    check_is_a_string(formatSpec)
    check_is_a_string(altFormatSpec)
    fmt = altFormatSpec if not formatSpec else formatSpec

    if is_quoted(fmt):
        fmt = fmt[1:-1]  # remove quotes
    else:
        if fmt and ':' not in fmt and '!' not in fmt:
            fmt = ':' + fmt
        fmt = '{' + fmt + '}'

    # Test resulting replacement field
    if testValue is not None:
        try:
            _dummy = fmt.format(testValue)
        except Exception:
            msg = (
                "Format specifier failed: replacement-field={!r}, test-value={!r}"
                .format(fmt, testValue))
            logger.error(msg)
            raise ValueError(msg)

    logger.debug("Resulting replacement field: {!r}".format(fmt))
    return fmt
Example #9
0
    def __init__(self, fullName, fullClassName, pythonPath=''):
        """ Constructor.

            :param fullName: fullName comprising of library and name, separated by a slash.
                Can contain spaces. E.g.: 'library name/My Widget'
                Must be unique when spaces are removed and converted to lower case.
            :param fullClassName: full name of the underlying class.
                E.g.: 'argos.plugins.rti.ncdf.NcdfFileInspector'
            :param pythonPath: directory that will be added to the sys.path before importing.
                Can be multiple directories separated by a colon (:)
        """
        check_is_a_string(fullClassName)
        self._identifier = nameToIdentifier(fullName)
        self._fullName = fullName
        self._fullClassName = fullClassName
        self._pythonPath = pythonPath

        self._cls = None # The underlying class. Not yet imported.
        self._triedImport = False
        self._exception = None # Any exception that occurs during the class import
Example #10
0
    def __init__(self, nodeName, defaultFamily='Helvetica'):
        """ Constructor.

            :param defaultFamily: A string representing the defaultValue.
            :editable: True if the underlying QFontComboBox is editable. The default is False as
                it does not work well with the FontCti.

            For the (other) parameters see the AbstractCti constructor documentation.
        """
        check_is_a_string(defaultFamily)

        # Get a list of of configValues by reading them from a temporary QFontComboBox.
        tempFontComboBox = QtWidgets.QFontComboBox()
        configValues = []
        defaultData = 0
        for idx in range(tempFontComboBox.count()):
            fontFamily = tempFontComboBox.itemText(idx)
            configValues.append(fontFamily)
            if fontFamily.lower() == defaultFamily.lower():
                defaultData = idx

        # Set after self._displayValues are defined. The parent constructor calls _enforceDataType
        super(FontChoiceCti, self).__init__(nodeName, defaultData, configValues=configValues)