Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions meshroom/ui/qml/GraphEditor/NodeEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ Panel {
toggle: true // Enable toggling the actual text field by the search button
Layout.minimumWidth: searchBar.width
maxWidth: 150
enabled: tabBar.currentIndex === 0 || tabBar.currentIndex === 5
enabled: tabBar.currentIndex === 0 || tabBar.currentIndex === 6
}

MaterialToolButton {
Expand Down Expand Up @@ -540,6 +540,19 @@ Panel {
}
}

Loader {
active: (tabBar.currentIndex === 4)
Layout.fillHeight: true
Layout.fillWidth: true
sourceComponent: NodeFileBrowser {
id: nodeFileBrowser

Layout.fillHeight: true
Layout.fillWidth: true
node: root.node
}
}

NodeDocumentation {
id: nodeDocumentation

Expand Down Expand Up @@ -580,7 +593,7 @@ Panel {
property bool isBackdropNode: root.node !== null && root.node.isBackdropNode

// The indices of the tab bar which can be shown for incomputable nodes
readonly property var nonComputableTabIndices: [0, 4, 5]
readonly property var nonComputableTabIndices: [0, 5, 6]

Layout.fillWidth: true
width: childrenRect.width
Expand Down Expand Up @@ -625,6 +638,13 @@ Panel {
leftPadding: 8
rightPadding: leftPadding
}
TabButton {
visible: tabBar.isComputableType
width: !visible ? 0 : tabBar.width / tabBar.count
text: "Files"
leftPadding: 8
rightPadding: leftPadding
}
TabButton {
text: "Documentation"
leftPadding: 8
Expand All @@ -643,7 +663,7 @@ Panel {
if ((root.node && !root.node.isComputableType) && (nonComputableTabIndices.indexOf(tabBar.currentIndex) === -1)) {
if (root.node.isBackdropNode) {
// Backdrop nodes can only show the Documentation & Notes tabs
tabBar.currentIndex = 4 // Notes tab
tabBar.currentIndex = 5 // Documentation tab
} else {
tabBar.currentIndex = 0
}
Expand Down
180 changes: 180 additions & 0 deletions meshroom/ui/qml/GraphEditor/NodeFileBrowser.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt.labs.folderlistmodel

import Controls 1.0
import MaterialIcons 2.2
import Utils 1.0

/**
* NodeFileBrowser displays the cache folder of a Node as a navigable file browser.
*/
FocusScope {
id: root

property variant node: null

// The root folder URL (node's internal cache folder)
readonly property url rootFolderUrl: node ? Filepath.stringToUrl(node.internalFolder) : ""
// Currently displayed folder URL
property url currentFolder: rootFolderUrl

// Reset to root folder when node changes
onRootFolderUrlChanged: {
root.currentFolder = root.rootFolderUrl
}

SystemPalette { id: activePalette }

FolderListModel {
id: folderModel
folder: root.currentFolder
showFiles: true
showDirs: true
showDirsFirst: true
showHidden: false
sortField: FolderListModel.Name
nameFilters: ["*"]
}

ColumnLayout {
anchors.fill: parent
spacing: 0

// Toolbar: navigate up button, current path label, open-in-OS button
ToolBar {
Layout.fillWidth: true

RowLayout {
anchors.fill: parent
spacing: 2

// Navigate up button
MaterialToolButton {
text: MaterialIcons.arrow_upward
font.pointSize: 11
padding: 4
enabled: root.currentFolder.toString() !== root.rootFolderUrl.toString()
ToolTip.text: "Go to parent folder"
ToolTip.visible: hovered
onClicked: {
root.currentFolder = Filepath.stringToUrl(Filepath.dirname(Filepath.urlToString(root.currentFolder)))
}
}

// Current folder path label
Label {
id: pathLabel
Layout.fillWidth: true
elide: Text.ElideLeft
text: root.node ? Filepath.urlToString(root.currentFolder) : ""
ToolTip.text: text
ToolTip.visible: hovered && truncated
font.pointSize: 8
verticalAlignment: Text.AlignVCenter
}

// Open current folder in OS file manager
MaterialToolButton {
text: MaterialIcons.folder_open
font.pointSize: 11
padding: 4
enabled: root.node !== null
ToolTip.text: "Open folder in file manager"
ToolTip.visible: hovered
onClicked: Qt.openUrlExternally(root.currentFolder)
}
}
}

// File list
ListView {
id: fileListView
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
focus: true
model: folderModel
keyNavigationEnabled: true
highlightFollowsCurrentItem: true

ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }

// Placeholder when folder is empty or does not exist
Label {
anchors.centerIn: parent
visible: folderModel.count === 0 && root.node !== null
color: Qt.lighter(activePalette.mid, 1.2)
text: "No files found"
}

delegate: ItemDelegate {
id: delegateItem
width: fileListView.width
height: 24
padding: 0
leftPadding: 6

// fileIsDir is a FolderListModel role available in the delegate context
readonly property bool isDir: fileIsDir
readonly property string itemFilePath: filePath

RowLayout {
anchors.fill: parent
anchors.leftMargin: 6
spacing: 6

// File/folder icon
MaterialLabel {
text: delegateItem.isDir ? MaterialIcons.folder : MaterialIcons.insert_drive_file
color: delegateItem.isDir ? "#e8a000" : activePalette.text
font.pointSize: 10
Layout.alignment: Qt.AlignVCenter
}

// File/folder name
Label {
Layout.fillWidth: true
// fileName is a FolderListModel role available in the delegate context
text: fileName
elide: Text.ElideRight
font.pointSize: 8
verticalAlignment: Text.AlignVCenter
}

// File size (only for files, fileSize role from FolderListModel)
Label {
visible: !delegateItem.isDir
text: {
if (fileSize < 0)
return ""
if (fileSize < 1024)
return fileSize + " B"
if (fileSize < 1024 * 1024)
return (fileSize / 1024).toFixed(1) + " KB"
if (fileSize < 1024 * 1024 * 1024)
return (fileSize / (1024 * 1024)).toFixed(1) + " MB"
return (fileSize / (1024 * 1024 * 1024)).toFixed(2) + " GB"
}
color: activePalette.mid
font.pointSize: 7
rightPadding: 8
verticalAlignment: Text.AlignVCenter
}
}

highlighted: fileListView.currentIndex === index

onDoubleClicked: {
if (delegateItem.isDir) {
// fileURL is a FolderListModel role providing the URL
root.currentFolder = fileURL
} else {
Qt.openUrlExternally(fileURL)
}
}
}
}
}
}
3 changes: 2 additions & 1 deletion meshroom/ui/qml/GraphEditor/qmldir
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ CompatibilityBadge 1.0 CompatibilityBadge.qml
CompatibilityManager 1.0 CompatibilityManager.qml
singleton GraphEditorSettings 1.0 GraphEditorSettings.qml
TaskManager 1.0 TaskManager.qml
ScriptEditor 1.0 ScriptEditor.qml
ScriptEditor 1.0 ScriptEditor.qml
NodeFileBrowser 1.0 NodeFileBrowser.qml