Improve the file delegate

- cleaner code
- supports stopping downloads
- utilises the mimetype in order to display an icon
- better size formatting
- tooltips
This commit is contained in:
Jan Blackquill
2021-08-19 13:23:52 -04:00
parent d7ce0b7468
commit 4955b1f7a0
4 changed files with 85 additions and 30 deletions

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15 import QtGraphicalEffects 1.15
import Qt.labs.platform 1.1 import Qt.labs.platform 1.1
@@ -23,29 +23,82 @@ RowLayout {
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing
onDownloadedChanged: if (downloaded && openOnFinished) { states: [
openSavedFile(); State {
} name: "downloaded"
when: progressInfo.completed
ToolButton { PropertyChanges {
icon.name: progressInfo.completed ? "document-open" : "document-save" target: downloadButton
onClicked: progressInfo.completed ? openSavedFile() : saveFileAs()
}
icon.name: "document-open"
QQC2.ToolTip.text: i18nc("tooltip for a button on a message; offers ability to open its downloaded file with an appropriate application", "Open File")
onClicked: openSavedFile()
}
},
State {
name: "downloading"
when: progressInfo.active
PropertyChanges {
target: sizeLabel
text: i18nc("file download progress", "%1 / %2", Controller.formatByteSize(progressInfo.progress), Controller.formatByteSize(progressInfo.total))
}
PropertyChanges {
target: downloadButton
icon.name: "media-playback-stop"
QQC2.ToolTip.text: i18nc("tooltip for a button on a message; stops downloading the message's file", "Stop Download")
onClicked: currentRoom.cancelFileTransfer(eventId)
}
},
State {
name: "raw"
when: true
PropertyChanges {
target: downloadButton
onClicked: root.saveFileAs()
}
}
]
Kirigami.Icon {
id: ikon
source: model.fileMimetypeIcon
fallback: "unknown"
}
ColumnLayout { ColumnLayout {
Kirigami.Heading { Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true Layout.fillWidth: true
level: 4
text: model.display spacing: 0
wrapMode: Label.Wrap
} QQC2.Label {
text: model.display
wrapMode: Text.Wrap
Label {
Layout.fillWidth: true Layout.fillWidth: true
text: !progressInfo.completed && progressInfo.active ? (Controller.formatByteSize(progressInfo.progress) + "/" + Controller.formatByteSize(progressInfo.total)) : Controller.formatByteSize(content.info ? content.info.size : 0)
color: Kirigami.Theme.disabledTextColor
wrapMode: Label.Wrap
} }
QQC2.Label {
id: sizeLabel
text: Controller.formatByteSize(content.info ? content.info.size : 0)
opacity: 0.7
Layout.fillWidth: true
}
}
QQC2.Button {
id: downloadButton
icon.name: "download"
QQC2.ToolTip.text: i18nc("tooltip for a button on a message; offers ability to download its file", "Download")
QQC2.ToolTip.visible: hovered
} }
Component { Component {
@@ -61,21 +114,11 @@ RowLayout {
} }
function saveFileAs() { function saveFileAs() {
var dialog = fileDialog.createObject(ApplicationWindow.overlay) var dialog = fileDialog.createObject(QQC2.ApplicationWindow.overlay)
dialog.open() dialog.open()
dialog.currentFile = dialog.folder + "/" + currentRoom.fileNameToDownload(eventId) dialog.currentFile = dialog.folder + "/" + currentRoom.fileNameToDownload(eventId)
} }
function downloadAndOpen() {
if (downloaded) {
openSavedFile();
} else {
openOnFinished = true;
currentRoom.downloadFile(eventId, StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/"
+ eventId.replace(":", "_").replace("/", "_").replace("+", "_") + currentRoom.fileNameToDownload(eventId));
}
}
function openSavedFile() { function openSavedFile() {
if (Qt.openUrlExternally(progressInfo.localPath)) return; if (Qt.openUrlExternally(progressInfo.localPath)) return;
if (Qt.openUrlExternally(progressInfo.localDir)) return; if (Qt.openUrlExternally(progressInfo.localDir)) return;

View File

@@ -610,7 +610,7 @@ void Controller::openOrCreateDirectChat(NeoChatUser *user)
QString Controller::formatByteSize(double size, int precision) const QString Controller::formatByteSize(double size, int precision) const
{ {
return KFormat().formatByteSize(size, precision); return QLocale().formattedDataSize(size, precision);
} }
QString Controller::formatDuration(quint64 msecs, KFormat::DurationFormatOptions options) const QString Controller::formatDuration(quint64 msecs, KFormat::DurationFormatOptions options) const

View File

@@ -37,6 +37,7 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
roles[HighlightRole] = "isHighlighted"; roles[HighlightRole] = "isHighlighted";
roles[SpecialMarksRole] = "marks"; roles[SpecialMarksRole] = "marks";
roles[LongOperationRole] = "progressInfo"; roles[LongOperationRole] = "progressInfo";
roles[FileMimetypeIcon] = "fileMimetypeIcon";
roles[AnnotationRole] = "annotation"; roles[AnnotationRole] = "annotation";
roles[EventResolvedTypeRole] = "eventResolvedType"; roles[EventResolvedTypeRole] = "eventResolvedType";
roles[ReplyRole] = "reply"; roles[ReplyRole] = "reply";
@@ -536,6 +537,15 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return m_currentRoom->isEventHighlighted(&evt); return m_currentRoom->isEventHighlighted(&evt);
} }
if (role == FileMimetypeIcon) {
auto e = eventCast<const RoomMessageEvent>(&evt);
if (!e || !e->hasFileContent()) {
return QVariant();
}
return e->content()->fileInfo()->mimeType.iconName();
}
if (role == SpecialMarksRole) { if (role == SpecialMarksRole) {
if (isPending) { if (isPending) {
return pendingIt->deliveryStatus(); return pendingIt->deliveryStatus();

View File

@@ -30,6 +30,8 @@ public:
UserMarkerRole, UserMarkerRole,
FormattedBodyRole, FormattedBodyRole,
FileMimetypeIcon,
ReplyRole, ReplyRole,
ShowAuthorRole, ShowAuthorRole,