Files
tactileipc3d/qml/content/OpenFileDialog.qml

292 lines
10 KiB
QML

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import Qt.labs.folderlistmodel 2.15
import QtCore 6.2
import QtQuick.Dialogs
import TactileIPC 1.0
Window {
id: root
width: 980
height: 640
minimumWidth: 880
minimumHeight: 560
visible: false
modality: Qt.ApplicationModal
flags: Qt.Dialog | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
title: root.tr("导入数据")
color: windowBg
readonly property bool isDark: !Backend.lightMode
readonly property color windowBg: isDark ? "#1B1F1B" : "#F7F8F9"
Material.accent: root.accent
Material.primary: root.accent
Material.theme: root.isDark ? Material.Dark : Material.Light
readonly property color accent: "#21A453"
readonly property color accentSoft: root.isDark ? "#1F3A2A" : "#E6F6EC"
readonly property color panel: root.isDark ? "#242924" : "#FFFFFF"
readonly property color border: root.isDark ? "#343A35" : "#E1E5EA"
readonly property color text: root.isDark ? "#E6ECE7" : "#1E2A32"
readonly property color subText: root.isDark ? "#9AA5A0" : "#6E7A86"
readonly property color fieldBg: root.isDark ? "#1E221E" : "#FFFFFF"
readonly property color surfaceAlt: root.isDark ? "#202520" : "#F9FAFB"
readonly property color hoverBg: root.isDark ? "#2C322D" : "#F3F6F8"
readonly property color iconBg: root.isDark ? "#25362B" : "#E8F3EA"
readonly property color iconBgAlt: root.isDark ? "#2A302A" : "#EFF2F5"
readonly property color disabledBg: root.isDark ? "#4B544E" : "#C9D2D8"
readonly property string uiFont: "Microsoft YaHei UI"
property url currentFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + "/"
property string chosenFilename: ""
property string importFormat: ""
property string importMethod: ""
signal importIn(url filename, string format, string method)
function open() {
}
function accept() {
visible = false
}
function reject() {
visible = false
}
function centerOnScreen_() {
x = Math.round((Screen.width - width) / 2)
y = Math.round((Screen.height - height) / 2)
}
function normalizeFolder_(path) {
if (!path)
return path
if (path.endsWith("/"))
return path
return path + "/"
}
function tr(text) {
I18n.retranslateToken
return qsTr(text)
}
onVisibleChanged: if (visible) centerOnScreen_()
ColumnLayout {
anchors.fill: parent
anchors.margins: 16
spacing: 12
Rectangle {
Layout.fillWidth: true
height: 54
radius: 6
color: root.panel
border.color: root.border
RowLayout {
anchors.fill: parent
anchors.margins: 8
spacing: 8
ToolButton {
id: backBtn
text: "<"
font.family: root.uiFont
onClicked: {
}
background: Rectangle {
radius: 4
color: backBtn.hovered ? root.accentSoft : "transparent"
border.color: backBtn.hovered ? root.accent : root.border
}
}
ToolButton {
id: forwardBtn
text: ">"
font.family: root.uiFont
onClicked: {
}
background: Rectangle {
radius: 4
color: backBtn.hovered ? root.accentSoft : "transparent"
border.color: backBtn.hovered ? root.accent : root.border
}
}
ToolButton {
id: upBtn
text: "^"
font.family: root.uiFont
onClicked: {
}
background: Rectangle {
radius: 4
color: backBtn.hovered ? root.accentSoft : "transparent"
border.color: backBtn.hovered ? root.accent : root.border
}
}
TextField {
id: breadcrumb
Layout.fillWidth: true
readOnly: true
font.family: root.uiFont
color: root.text
text: root.currentFolder.toString()
background: Rectangle {
radius: 4
color: root.surfaceAlt
border.color: root.border
}
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 12
Rectangle {
Layout.preferredWidth: 220
Layout.fillHeight: true
radius: 6
color: root.panel
border.color: root.border
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
spacing: 8
Label {
text: root.tr("位置")
font.bold: true
font.family: root.uiFont
color: root.text
}
ListView {
id: places
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
model: [
{ name: root.tr("此电脑"), url: "file:///", icon: root.isDark ? "qrc:/images/computer_dark.png" : "qrc:/images/computer_light.png" },
{ name: root.tr("桌面"), url: StandardPaths.writableLocation(StandardPaths.DesktopLocation) + "/", icon: root.isDark ? "qrc:/images/desktop_dark.png" : "qrc:/images/desktop_light.png" },
{ name: root.tr("文档"), url: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + "/", icon: root.isDark ? "qrc:/images/docs_dark.png" : "qrc:/images/docs_light.png" },
{ name: root.tr("下载"), url: StandardPaths.writableLocation(StandardPaths.DownloadLocation) + "/", icon: root.isDark ? "qrc:/images/download_dark.png" : "qrc:/images/download_light.png" }
]
delegate: ItemDelegate {
width: ListView.view.width
onClicked: {
places.currentIndex = index
root.currentFolder = normalizeFolder_(modeData.url)
}
background: Rectangle {
radius: 4
color: places.currentIndex === index ? root.accentSoft : "transparent"
border.color: places.currentIndex === index ? root.accent : "transparent"
}
contentItem: RowLayout {
spacing: 8
Image {
width: 16
height: 16
source: modelData.icon
fillMode: Image.PreserveAspectFit
smooth: true
}
Label {
text: modelData.name
font.family: root.uiFont
color: root.text
}
}
}
}
}
}
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
radius: 6
color: root.panel
border.color: root.border
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
spacing: 6
RowLayout {
Layout.fillWidth: true
Lable {
// TODO table title
}
}
Rectangle {
Layout.fillWidth: true
height: 1
color: root.border
}
FolderListModel {
id: fileModel
folder: root.currentFolder
showDotAndDotDot: false
showDirs: true
showFiles: true
sortField: FolderListModel.Name
}
ListView {
id: fileList
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
model: fileModel
delegate: ItemDelegate {
id: fileRow
width: ListView.view.width
onDoubleClicked: {
const isDir = fileModel.get(index, "fileIsDir")
if (isDir) {
root.currentFolder = normalizeFolder_(fileModel.get(index, "filePath"))
}
else {
// TODO import file
}
}
onClicked: {
fileList.currentIndex = index
}
background: Rectangle {
radius: 4
color: fileRow.hovered ? root.hoverBg : "transparent"
}
contentItem: RowLayout {
spacing: 8
Rectangle {
width+:
}
}
}
}
}
}
}
}
}