Beispiel #1
0
    def update_view(self):
        """
        Updates file/folder view
        :return:
        """

        self.view.clear()
        qdir = QDir(self.directory)
        qdir.setNameFilters(self.get_filter_patterns())
        filters = QDir.Dirs | QDir.AllDirs | QDir.Files | QDir.NoDot | QDir.NoDotDot
        if self.show_hidden.isChecked():
            filters = filters | QDir.Hidden
        entries = qdir.entryInfoList(filters=filters,
                                     sort=QDir.DirsFirst | QDir.Name)
        file_path = self.get_file_path('..')
        if os.path.exists(file_path) and file_path != self.directory:
            icon = QFileIconProvider().icon(QFileInfo(self.directory))
            QListWidgetItem(icon, '..', self.view, 0)
        for info in entries:
            icon = QFileIconProvider().icon(info)
            suf = info.completeSuffix()
            name, tp = (info.fileName(), 0) if info.isDir() else (
                '%s%s' % (info.baseName(), '.%s' % suf if suf else ''), 1)
            QListWidgetItem(icon, name, self.view, tp)
        self.view.setFocus()
Beispiel #2
0
    def get_drives_widget(self):
        """
        Returns a QGroupBox widget that contains all disk drivers of the PC in a vertical layout
        :return: QGroupBox
        """

        w = QGroupBox('')
        w.setParent(self)
        box = layouts.VerticalLayout()
        box.setAlignment(Qt.AlignTop)
        places = [(getpass.getuser(),
                   os.path.realpath(os.path.expanduser('~')))]
        places += [
            (q, q) for q in
            [os.path.realpath(x.absolutePath()) for x in QDir().drives()]
        ]
        for label, loc in places:
            icon = QFileIconProvider().icon(QFileInfo(loc))
            drive_btn = QRadioButton(label)
            drive_btn.setIcon(icon)
            drive_btn.setToolTip(loc)
            drive_btn.setProperty('path', loc)
            drive_btn.clicked.connect(self.go_to_drive)
            self.places[loc] = drive_btn
            box.addWidget(drive_btn)
        w.setLayout(box)
        return w
Beispiel #3
0
 def updateFileStatus(self, truncated=False):
     """ Cache the status of a file.
     
     :Parameters:
         truncated : `bool`
             If the file was truncated on read, and therefore should never be edited.
     """
     if self.path:
         self.fileInfo = QFileInfo(self.path)
         if truncated:
             self.status = self.FILE_TRUNCATED
         elif self.fileInfo.isWritable():
             self.status = self.FILE_WRITABLE
         else:
             self.status = self.FILE_NOT_WRITABLE
     else:
         self.status = self.FILE_NEW
Beispiel #4
0
    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            data = event.mimeData().urls()
            file_info = QFileInfo(data[0].toLocalFile())
            file_name = file_info.absoluteFilePath()
            if file_name and os.path.isfile(file_name):
                file_extension = os.path.splitext(file_name)[-1]
                data_extension = skeleton.SkeletonFileData.get_data_extension()
                if not data_extension.startswith('.'):
                    data_extension = '.{}'.format(data_extension)
                if file_extension == data_extension:
                    self._show_bones_hierarchy(file_name)
                    event.accept()
        elif event.mimeData().hasText():
            self.setText(event.mimeData().text())

        event.accept()
Beispiel #5
0
 def parseMatch(self, match, linkPath, nativeAbsPath, fileInfo):
     """ Parse a RegEx match of a patch to another file.
     
     Override for specific language parsing.
     
     :Parameters:
         match
             RegEx match object
         linkPath : `str`
             Displayed file path matched by the RegEx
         nativeAbsPath : `str`
             OS-native absolute file path for the file being parsed
         fileInfo : `QFileInfo`
             File info object for the file being parsed
     :Returns:
         HTML link
     :Rtype:
         `str`
     :Raises ValueError:
         If path does not exist or cannot be resolved.
     """
     # linkPath = `str` displayed file path
     # fullPath = `str` absolute file path
     # Example: <a href="fullPath">linkPath</a>
     if QFileInfo(linkPath).isAbsolute():
         fullPath = QFileInfo(expandPath(linkPath, nativeAbsPath)).absoluteFilePath()
         logger.debug("Parsed link is absolute (%s). Expanded to %s", linkPath, fullPath)
     else:
         # Relative path from the current file to the link.
         fullPath = fileInfo.dir().absoluteFilePath(expandPath(linkPath, nativeAbsPath))
         logger.debug("Parsed link is relative (%s). Expanded to %s", linkPath, fullPath)
     
     # Make the HTML link.
     if self.exists[fullPath]:
         return '<a href="file://{}">{}</a>'.format(fullPath, linkPath)
     elif '*' in linkPath or '&lt;UDIM&gt;' in linkPath or '.#.' in linkPath:
         # Create an orange link for files with wildcards in the path,
         # designating zero or more files may exist.
         return '<a title="Multiple files may exist" class="mayNotExist" href="file://{}">{}</a>'.format(
                fullPath, linkPath)
     return '<a title="File not found" class="badLink" href="file://{}">{}</a>'.format(fullPath, linkPath)
Beispiel #6
0
 def parseMatch(self, match, linkPath, nativeAbsPath, fileInfo):
     """ Parse a RegEx match of a patch to another file.
     
     Override for specific language parsing.
     
     :Parameters:
         match
             RegEx match object
         linkPath : `str`
             Displayed file path matched by the RegEx
         nativeAbsPath : `str`
             OS-native absolute file path for the file being parsed
         fileInfo : `QFileInfo`
             File info object for the file being parsed
     :Returns:
         HTML link
     :Rtype:
         `str`
     :Raises ValueError:
         If path does not exist or cannot be resolved.
     """
     # This group number must be carefully kept in sync based on the default RegEx from the parent class. 
     queryStr = "?line=" + match.group(2) if match.group(2) is not None else ""
     
     if QFileInfo(linkPath).isAbsolute():
         fullPath = QFileInfo(expandPath(linkPath, nativeAbsPath)).absoluteFilePath()
     else:
         # Relative path from the current file to the link.
         fullPath = fileInfo.dir().absoluteFilePath(expandPath(linkPath, nativeAbsPath))
     
     # Make the HTML link.
     if self.exists[fullPath]:
         return '<a href="file://{}{}">{}</a>'.format(fullPath, queryStr, linkPath)
     elif '*' in linkPath or '&lt;UDIM&gt;' in linkPath or '.#.' in linkPath:
         # Create an orange link for files with wildcards in the path,
         # designating zero or more files may exist.
         return '<a title="Multiple files may exist" class="mayNotExist" href="file://{}{}">{}</a>'.format(
                fullPath, queryStr, linkPath)
     return '<a title="File not found" class="badLink" href="file://{}{}">{}</a>'.format(
            fullPath, queryStr, linkPath)
Beispiel #7
0
def icon_from_filename(file_path):
    """
    Returns icon of the given file path
    :param file_path: str
    :return: QIcon
    """

    global _ICON_PROVIDER

    if not _ICON_PROVIDER:
        _ICON_PROVIDER = QFileIconProvider()

    file_info = QFileInfo(file_path)
    file_icon = _ICON_PROVIDER.icon(file_info)
    if not file_icon or file_icon.isNull():
        return QApplication.style().standardIcon(QStyle.SP_FileIcon)
    else:
        return file_icon
Beispiel #8
0
class FileStatus(object):
    """ File status cache class allowing overriding with additional statuses for custom integration of things like a
    revision control system.
    """
    FILE_NEW          = 0  # New file, never saved.      Ok to edit, save.
    FILE_NOT_WRITABLE = 1  # File not writable.          Nothing allowed.
    FILE_WRITABLE     = 2  # File writable.              Ok to edit, save.
    FILE_TRUNCATED    = 4  # File was truncated on read. Nothing allowed.
    
    def __init__(self, url=None, update=True, truncated=False):
        """ Initialize the FileStatus cache
        
        :Parameters:
            url : `QtCore.QUrl`
                File URL
            update : `bool`
                Immediately update file status or not, like checking if it's writable.
            truncated : `bool`
                If the file was truncated on read, and therefore should never be edited.
        """
        self.url = url if url else QUrl()
        self.path = "" if self.url.isEmpty() else self.url.toLocalFile()
        self.status = self.FILE_NEW
        self.fileInfo = None
        if update:
            self.updateFileStatus(truncated)
    
    def updateFileStatus(self, truncated=False):
        """ Cache the status of a file.
        
        :Parameters:
            truncated : `bool`
                If the file was truncated on read, and therefore should never be edited.
        """
        if self.path:
            if self.fileInfo is None:
                self.fileInfo = QFileInfo(self.path)
                self.fileInfo.setCaching(False)
            if truncated:
                self.status = self.FILE_TRUNCATED
            elif self.fileInfo.isWritable():
                self.status = self.FILE_WRITABLE
            else:
                self.status = self.FILE_NOT_WRITABLE
        else:
            self.status = self.FILE_NEW
    
    @property
    def icon(self):
        """ Get an icon to display representing the file's status.
        
        :Returns:
            Icon (may be blank)
        :Rtype:
            `QIcon`
        """
        if self.status == self.FILE_NOT_WRITABLE:
            return QIcon(":images/images/lock")
        return QIcon()
    
    @property
    def text(self):
        """ Get a status string to display for the file.
        
        :Returns:
            File status (may be an empty string)
        :Rtype:
            `str`
        """
        if self.status == self.FILE_NEW:
            return ""
        elif self.status == self.FILE_NOT_WRITABLE:
            return "File not writable"
        elif self.status == self.FILE_WRITABLE:
            return "File writable"
        elif self.status == self.FILE_TRUNCATED:
            return "File too large to fully display"
        else:
            logger.error("Unexpected file status code: %s", self.status)
            return ""
    
    @property
    def writable(self):
        """ Get if the file is writable.
        
        :Returns:
            If the file is writable
        :Rtype:
            `bool`
        """
        return self.status in [self.FILE_NEW, self.FILE_WRITABLE]
Beispiel #9
0
    def parseMatch(self, match, linkPath, nativeAbsPath, fileInfo):
        """ Parse a RegEx match of a path to another file.
        
        Override for specific language parsing.
        
        :Parameters:
            match
                RegEx match object
            linkPath : `str`
                Displayed file path matched by the RegEx
            nativeAbsPath : `str`
                OS-native absolute file path for the file being parsed
            fileInfo : `QFileInfo`
                File info object for the file being parsed
        :Returns:
            HTML link
        :Rtype:
            `str`
        :Raises ValueError:
            If path does not exist or cannot be resolved.
        """
        expanded_path = utils.expandPath(
            linkPath, nativeAbsPath, 
            self.sdf_format_args,
            extractedDir=self.extractedDir)
        if QFileInfo(linkPath).isAbsolute():
            fullPath = QFileInfo(expanded_path).absoluteFilePath()
            logger.debug("Parsed link is absolute (%s). Expanded to %s", linkPath, fullPath)
        else:
            # Relative path from the current file to the link.
            fullPath = fileInfo.dir().absoluteFilePath(expanded_path)
            logger.debug("Parsed link is relative (%s). Expanded to %s", linkPath, fullPath)
        
        # Override any previously set sdf format args.
        local_sdf_args = self.sdf_format_args.copy()
        if match.group(3):
            for kv in match.group(3).split("&amp;"):
                k, v = kv.split("=", 1)
                expanded_path = utils.expandPath(
                    v, nativeAbsPath, self.sdf_format_args,
                    extractedDir=self.extractedDir)
                local_sdf_args[k] = expanded_path.replace("&", "+").replace("=", ":")
        if local_sdf_args:
            queryParams = ["sdf=" + "+".join("{}:{}".format(k, v) for k, v in
                           sorted(local_sdf_args.items(), key=lambda x: x[0]))]
        else:
            queryParams = []
        
        # .usdz file references (e.g. @set.usdz[foo/bar.usd]@)
        if match.group(2):
            queryParams.append("layer=" + match.group(2))

        # Propogate the extracted archive if this resolved file is in the same archive
        if self.extractedDir and fullPath.startswith(self.extractedDir + sep):
            queryParams.append("extractedDir=" + self.extractedDir)
        
        # Make the HTML link.
        if self.exists[fullPath]:
            _, fullPathExt = splitext(fullPath)
            if fullPathExt == ".usdc" or (fullPathExt == ".usd" and utils.isUsdCrate(fullPath)):
                queryParams.insert(0, "binary=1")
                return '<a class="binary" href="file://{}?{}">{}</a>'.format(fullPath, "&".join(queryParams), linkPath)
            
            queryStr = "?" + "&".join(queryParams) if queryParams else ""
            return '<a href="file://{}{}">{}</a>'.format(fullPath, queryStr, linkPath)
        elif '*' in linkPath or '&lt;UDIM&gt;' in linkPath or '.#.' in linkPath:
            # Create an orange link for files with wildcards in the path,
            # designating zero or more files may exist.
            queryStr = "?" + "&".join(queryParams) if queryParams else ""
            return '<a title="Multiple files may exist" class="mayNotExist" href="file://{}{}">{}</a>'.format(
                   fullPath, queryStr, linkPath)
        
        queryStr = "?" + "&".join(queryParams) if queryParams else ""
        return '<a title="File not found" class="badLink" href="file://{}{}">{}</a>'.format(
               fullPath, queryStr, linkPath)