linphone-desktop/linphone-app/ui/modules/Linphone/File/FileView.qml

265 lines
No EOL
8.7 KiB
QML

import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import LinphoneEnums 1.0
import Linphone.Styles 1.0
import Utils 1.0
import UtilsCpp 1.0
import Units 1.0
import ColorsList 1.0
// =============================================================================
Item {
id: mainItem
property ContentModel contentModel
property string thumbnail: contentModel && contentModel.thumbnail
property string name: contentModel && contentModel.name
property string filePath: contentModel && contentModel.filePath
property int fileHeight: FileViewStyle.height
property bool active: true
property real animationScale : FileViewStyle.animation.to
property alias imageScale: thumbnailProvider.scale
property int fitHeight: mainItem.isAnimatedImage ? FileViewStyle.heightbetter : FileViewStyle.height
property int fitWidth: fitHeight*4/3
property bool isAnimatedImage : contentModel && contentModel.wasDownloaded && UtilsCpp.isAnimatedImage(filePath)
property bool haveThumbnail: contentModel && UtilsCpp.canHaveThumbnail(filePath)
property int borderWidth : 0
property color backgroundColor: FileViewStyle.extension.background.colorModel.color
property int backgroundRadius: FileViewStyle.extension.radius
property bool isTransferring
property bool isHovering: thumbnailProvider.state == 'hovered'
signal clickOnFile()
MouseArea {
function handleMouseMove (mouse) {
thumbnailProvider.state = Utils.pointIsInItem(this, thumbnailProvider, mouse)
? 'hovered'
: ''
}
anchors.fill: parent
visible: true
onClicked: {
if(mainItem.isTransferring)
mainItem.contentModel.cancelDownloadFile()
else if( !mainItem.contentModel.wasDownloaded) {
thumbnailProvider.state = ''
mainItem.contentModel.downloadFile()
}else if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) {
if(SettingsModel.isVfsEncrypted){
window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
contentModel: mainItem.contentModel,
}, function (status) {
})
}else
mainItem.contentModel.openFile()
} else if (mainItem.contentModel ) {
thumbnailProvider.state = ''
mainItem.contentModel.openFile(true)// Show directory
} else {
thumbnailProvider.state = ''
mainItem.contentModel.downloadFile()
}
mainItem.clickOnFile()
}
onExited: thumbnailProvider.state = ''
onMouseXChanged: handleMouseMove.call(this, mouse)
onMouseYChanged: handleMouseMove.call(this, mouse)
}
// ---------------------------------------------------------------------
// Thumbnail
// ---------------------------------------------------------------------
Component {
id: thumbnailImage
Image {
id: thumbnailImageSource
property real scaleAnimatorTo : FileViewStyle.animation.thumbnailTo
property bool isVideo: UtilsCpp.isVideo(mainItem.filePath)
mipmap: SettingsModel.mipmapEnabled
source: mainItem.thumbnail
autoTransform: true
fillMode: Image.PreserveAspectFit
anchors.fill: parent
Loader{
anchors.fill: parent
sourceComponent: Image{// Better quality on zoom
mipmap: SettingsModel.mipmapEnabled
source: !thumbnailImageSource.isVideo ? 'image://external/'+mainItem.filePath : ''
autoTransform: true
fillMode: Image.PreserveAspectFit
visible: status == Image.Ready
}
asynchronous: true
active: !thumbnailImageSource.isVideo && thumbnailProvider.state == 'hovered'
}
ActionButton{
id: thumbnailVideoButton
anchors.centerIn: parent
visible: thumbnailImageSource.isVideo
isCustom: true
backgroundRadius: width
colorSet: FileViewStyle.thumbnailVideoIcon
onClicked:{
window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
contentModel: mainItem.contentModel,
}, function (status) {
})
}
}
}
}
Component {
id: animatedImage
AnimatedImage {
id: animatedImageSource
property real scaleAnimatorTo : FileViewStyle.animation.to
mipmap: SettingsModel.mipmapEnabled
source: 'file:/'+mainItem.filePath
autoTransform: true
fillMode: Image.PreserveAspectFit
anchors.fill: parent
}
}
// ---------------------------------------------------------------------
// Extension
// ---------------------------------------------------------------------
Component {
id: extension
Rectangle {
property real scaleAnimatorTo : FileViewStyle.animation.to
anchors.fill: parent
color: mainItem.backgroundColor
radius: mainItem.backgroundRadius
border.width: mainItem.borderWidth
border.color: FileViewStyle.extension.background.borderColorModel.color
ColumnLayout{
anchors.fill: parent
anchors.topMargin: FileViewStyle.margins
anchors.bottomMargin: FileViewStyle.margins
spacing: FileViewStyle.spacing
Icon{
id: fileIcon
property bool isImage: UtilsCpp.isImage(mainItem.name)
Layout.alignment: Qt.AlignCenter
icon: fileIcon.isImage ? FileViewStyle.extension.imageIcon : FileViewStyle.extension.icon
iconSize: FileViewStyle.extension.iconSize
Layout.fillHeight: true
Layout.fillWidth: true
Layout.preferredHeight: iconSize
Layout.preferredWidth: iconSize
Text {
id: extensionText
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: FileViewStyle.spacing
width: FileViewStyle.extension.internalSize
onWidthChanged: extensionMetrics.font.pointSize = FileViewStyle.extension.text.pointSize // reset metrics
color: FileViewStyle.extension.text.colorModel.color
font.bold: true
font.pointSize: extensionMetrics.font.pointSize
clip: true
text: (!fileIcon.isImage && mainItem.contentModel?Utils.getExtension(mainItem.name).toUpperCase():'')
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
TextMetrics{
id: extensionMetrics
text: extensionText.text
font.pointSize: FileViewStyle.extension.text.pointSize
onWidthChanged: if(width > extensionText.width) --font.pointSize
Component.onCompleted: if(width > extensionText.width) --font.pointSize
}
}
RoundProgressBar {
id: progressBar
anchors.centerIn: parent
property int fileSize: mainItem.contentModel ? mainItem.contentModel.fileSize : 0
to: 100
value: mainItem.contentModel ? (fileSize>0 ? Math.floor(100 * mainItem.contentModel.fileOffset / fileSize) : 0) : to
visible: mainItem.isTransferring && value != 0
/* Change format? Current is %
text: if(mainRow.contentModel){
var fileSize = Utils.formatSize(mainRow.contentModel.fileSize)
return progressBar.visible
? Utils.formatSize(mainRow.contentModel.fileOffset) + '/' + fileSize
: fileSize
}else
return ''
*/
}
}
Text {
id: fileName
Layout.fillWidth: true
Layout.fillHeight: true
visible: mainItem.contentModel && !mainItem.isAnimatedImage
color: FileViewStyle.extension.text.colorModel.color
font.pointSize: FileViewStyle.name.pointSize
wrapMode: Text.WrapAnywhere
horizontalAlignment: Text.AlignHCenter
maximumLineCount: 2
text: mainItem.name
}
Text{
id: downloadText
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredHeight: visible ? contentHeight : 0
//: 'Cancel' : Message link to cancel a transfer (upload/download)
text: mainItem.contentModel ? mainItem.isTransferring ? qsTr('fileTransferCancel')
//: 'Download' : Message link to download a file
: qsTr('fileTransferDownload') +' ('+Utils.formatSize(mainItem.contentModel.fileSize)+')'
: ''
font.underline: true
font.pointSize: FileViewStyle.download.pointSize
color:FileViewStyle.extension.text.colorModel.color
visible: (mainItem.contentModel? (!mainItem.isOutgoing && !mainItem.contentModel.wasDownloaded) || mainItem.isTransferring : false)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
Loader {
id: thumbnailProvider
anchors.fill: parent
sourceComponent: (mainItem.contentModel ?
(mainItem.isAnimatedImage ? animatedImage
: (mainItem.haveThumbnail ? thumbnailImage : extension )
) : undefined)
states: State {
name: 'hovered'
}
}
Loader {
id: waitingProvider
anchors.fill: parent
sourceComponent: thumbnailProvider.sourceComponent == thumbnailImage && (thumbnailProvider.item.status != Image.Ready || thumbnailProvider.item.sourceSize.height == 0)
? extension
: undefined
states: State {
name: 'hovered'
}
}
}