You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
9.3 KiB
298 lines
9.3 KiB
import QtQuick 2.2
|
|
import QtQuick.Controls 1.2
|
|
import QtQuick.Controls.Private 1.0 as ControlsPrivate
|
|
import QtQuick.Dialogs 1.2
|
|
import QtQuick.Dialogs.Private 1.1
|
|
import QtQuick.Layouts 1.1
|
|
import QtQuick.Window 2.1
|
|
import Qt.labs.folderlistmodel 2.1
|
|
import Qt.labs.settings 1.0
|
|
|
|
AbstractDialog {
|
|
|
|
id: root
|
|
|
|
property string folder: view.model.folder
|
|
property var nameFilters: []
|
|
property bool selectFolder: false
|
|
property bool selectExisting: true
|
|
property int selectedNameFilterIndex: -1
|
|
property var selectedNameFilterExtensions: []
|
|
property string selection: ""
|
|
property alias fileUrl: root.selection
|
|
|
|
|
|
function selectNameFilter(text) {
|
|
}
|
|
|
|
function clearSelection(text) {
|
|
selection = "";
|
|
}
|
|
|
|
function addSelection(text) {
|
|
selection = text;
|
|
}
|
|
|
|
onVisibleChanged: {
|
|
if (visible) {
|
|
view.needsWidthAdjustment = true
|
|
view.selection.clear()
|
|
view.focus = true
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
folder = fileIo.pathToUrl(fileIo.homePath);
|
|
view.model.nameFilters = root.selectedNameFilterExtensions
|
|
filterField.currentIndex = root.selectedNameFilterIndex
|
|
root.favoriteFolders = settings.favoriteFolders
|
|
}
|
|
|
|
Component.onDestruction: {
|
|
settings.favoriteFolders = root.favoriteFolders
|
|
}
|
|
|
|
property Settings settings: Settings {
|
|
category: "QQControlsFileDialog"
|
|
property alias width: root.width
|
|
property alias height: root.height
|
|
property variant favoriteFolders: []
|
|
}
|
|
|
|
property bool showFocusHighlight: false
|
|
property SystemPalette palette: SystemPalette { }
|
|
property var favoriteFolders: []
|
|
|
|
function dirDown(path) {
|
|
view.selection.clear()
|
|
root.folder = "file://" + path
|
|
}
|
|
function dirUp() {
|
|
view.selection.clear()
|
|
if (view.model.parentFolder != "")
|
|
root.folder = view.model.parentFolder
|
|
}
|
|
function acceptSelection() {
|
|
// transfer the view's selections to QQuickFileDialog
|
|
clearSelection()
|
|
if (selectFolder && view.selection.count === 0)
|
|
addSelection(folder)
|
|
else {
|
|
view.selection.forEach(function(idx) {
|
|
if (view.model.isFolder(idx)) {
|
|
if (selectFolder)
|
|
addSelection(view.model.get(idx, "fileURL"))
|
|
} else {
|
|
if (!selectFolder)
|
|
addSelection(view.model.get(idx, "fileURL"))
|
|
}
|
|
})
|
|
}
|
|
accept()
|
|
}
|
|
|
|
property Action dirUpAction: Action {
|
|
text: "\ue810"
|
|
shortcut: "Ctrl+U"
|
|
onTriggered: dirUp()
|
|
tooltip: qsTr("Go up to the folder containing this one")
|
|
}
|
|
|
|
Rectangle {
|
|
id: window
|
|
implicitWidth: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 100, view.implicitWidth))
|
|
implicitHeight: Math.min(root.__maximumDimension, Screen.pixelDensity * 80)
|
|
color: root.palette.window
|
|
|
|
Binding {
|
|
target: view.model
|
|
property: "folder"
|
|
value: root.folder
|
|
}
|
|
Binding {
|
|
target: currentPathField
|
|
property: "text"
|
|
value: fileIo.urlToPath(root.folder)
|
|
}
|
|
Keys.onPressed: {
|
|
event.accepted = true
|
|
switch (event.key) {
|
|
case Qt.Key_Back:
|
|
case Qt.Key_Escape:
|
|
reject()
|
|
break
|
|
default:
|
|
event.accepted = false
|
|
break
|
|
}
|
|
}
|
|
Keys.forwardTo: [view.flickableItem]
|
|
|
|
|
|
TableView {
|
|
id: view
|
|
sortIndicatorVisible: true
|
|
width: parent.width
|
|
anchors.top: titleBar.bottom
|
|
anchors.bottom: bottomBar.top
|
|
|
|
property bool needsWidthAdjustment: true
|
|
selectionMode: root.selectMultiple ?
|
|
(ControlsPrivate.Settings.hasTouchScreen ? SelectionMode.MultiSelection : SelectionMode.ExtendedSelection) :
|
|
SelectionMode.SingleSelection
|
|
onRowCountChanged: if (needsWidthAdjustment && rowCount > 0) {
|
|
resizeColumnsToContents()
|
|
needsWidthAdjustment = false
|
|
}
|
|
model: FolderListModel {
|
|
showFiles: !root.selectFolder
|
|
nameFilters: root.selectedNameFilterExtensions
|
|
sortField: (view.sortIndicatorColumn === 0 ? FolderListModel.Name :
|
|
(view.sortIndicatorColumn === 1 ? FolderListModel.Type :
|
|
(view.sortIndicatorColumn === 2 ? FolderListModel.Size : FolderListModel.LastModified)))
|
|
sortReversed: view.sortIndicatorOrder === Qt.DescendingOrder
|
|
}
|
|
|
|
onActivated: if (view.focus) {
|
|
if (view.selection.count > 0 && view.model.isFolder(row)) {
|
|
dirDown(view.model.get(row, "filePath"))
|
|
} else {
|
|
root.acceptSelection()
|
|
}
|
|
}
|
|
onClicked: currentPathField.text = view.model.get(row, "filePath")
|
|
|
|
|
|
TableViewColumn {
|
|
id: fileNameColumn
|
|
role: "fileName"
|
|
title: qsTr("Filename")
|
|
delegate: Item {
|
|
implicitWidth: pathText.implicitWidth + pathText.anchors.leftMargin + pathText.anchors.rightMargin
|
|
|
|
Text {
|
|
id: fileIcon
|
|
width: height
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.family: iconFont.name
|
|
property alias unicode: fileIcon.text
|
|
FontLoader { id: iconFont; source: "qrc:/QtQuick/Dialogs/qml/icons.ttf"; onNameChanged: console.log("custom font" + name) }
|
|
x: 4
|
|
height: parent.height - 2
|
|
unicode: view.model.isFolder(styleData.row) ? "\ue804" : "\ue802"
|
|
}
|
|
Text {
|
|
id: pathText
|
|
text: styleData.value
|
|
anchors {
|
|
left: parent.left
|
|
right: parent.right
|
|
leftMargin: 36 + 6
|
|
rightMargin: 4
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
color: styleData.textColor
|
|
elide: Text.ElideRight
|
|
renderType: ControlsPrivate.Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
|
}
|
|
}
|
|
}
|
|
TableViewColumn {
|
|
role: "fileSuffix"
|
|
title: qsTr("Type", "file type (extension)")
|
|
// TODO should not need to create a whole new component just to customize the text value
|
|
// something like textFormat: function(text) { return view.model.get(styleData.row, "fileIsDir") ? "folder" : text }
|
|
delegate: Item {
|
|
implicitWidth: sizeText.implicitWidth + sizeText.anchors.leftMargin + sizeText.anchors.rightMargin
|
|
Text {
|
|
id: sizeText
|
|
text: view.model.get(styleData.row, "fileIsDir") ? "folder" : styleData.value
|
|
anchors {
|
|
left: parent.left
|
|
right: parent.right
|
|
leftMargin: 4
|
|
rightMargin: 4
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
color: styleData.textColor
|
|
elide: Text.ElideRight
|
|
renderType: ControlsPrivate.Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
|
}
|
|
}
|
|
}
|
|
TableViewColumn {
|
|
role: "fileSize"
|
|
title: qsTr("Size", "file size")
|
|
horizontalAlignment: Text.AlignRight
|
|
}
|
|
TableViewColumn { id: modifiedColumn; role: "fileModified" ; title: qsTr("Modified", "last-modified time") }
|
|
TableViewColumn { id: accessedColumn; role: "fileAccessed" ; title: qsTr("Accessed", "last-accessed time") }
|
|
}
|
|
|
|
ToolBar {
|
|
id: titleBar
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
ToolButton {
|
|
action: dirUpAction
|
|
//style: IconButtonStyle { }
|
|
Layout.maximumWidth: height * 1.5
|
|
}
|
|
TextField {
|
|
id: currentPathField
|
|
Layout.fillWidth: true
|
|
function doAccept() {
|
|
root.clearSelection()
|
|
if (root.addSelection(fileIo.pathToUrl(text)))
|
|
root.accept()
|
|
else
|
|
root.folder = fileIo.pathFolder(text)
|
|
}
|
|
onAccepted: doAccept()
|
|
}
|
|
}
|
|
}
|
|
Item {
|
|
id: bottomBar
|
|
width: parent.width
|
|
height: buttonRow.height + buttonRow.spacing * 2
|
|
anchors.bottom: parent.bottom
|
|
|
|
Row {
|
|
id: buttonRow
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: spacing
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 4
|
|
ComboBox {
|
|
id: filterField
|
|
model: root.nameFilters
|
|
visible: !selectFolder
|
|
width: bottomBar.width - cancelButton.width - okButton.width - parent.spacing * 6
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
onCurrentTextChanged: {
|
|
root.selectNameFilter(currentText)
|
|
view.model.nameFilters = root.selectedNameFilterExtensions
|
|
}
|
|
}
|
|
Button {
|
|
id: cancelButton
|
|
text: qsTr("Cancel")
|
|
onClicked: root.reject()
|
|
}
|
|
Button {
|
|
id: okButton
|
|
text: root.selectFolder ? qsTr("Choose") : (selectExisting ? qsTr("Open") : qsTr("Save"))
|
|
onClicked: {
|
|
if (view.model.isFolder(view.currentIndex) && !selectFolder)
|
|
dirDown(view.model.get(view.currentIndex, "filePath"))
|
|
else if (!(root.selectExisting))
|
|
currentPathField.doAccept()
|
|
else
|
|
root.acceptSelection()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|