Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F140150
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/contents/ui/MediaFileMenu.qml b/src/contents/ui/MediaFileMenu.qml
index 63e02f6..8f30e9d 100644
--- a/src/contents/ui/MediaFileMenu.qml
+++ b/src/contents/ui/MediaFileMenu.qml
@@ -1,50 +1,50 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import Qt.labs.platform 1.1 as Platform
import org.kde.kirigami 2.13 as Kirigami
import '.' as Types
TapHandler {
property var kazvIO
property var progressBar
property var url
acceptedButtons: Qt.LeftButton | Qt.RightButton
onSingleTapped: {
if (eventPoint.event.button === Qt.RightButton) {
optionMenu.popup(parent)
console.log("clicked")
}
if (eventPoint.event.button === Qt.LeftButton) {
// TODO: Open with default program
}
}
onLongPressed: {
optionMenu.popup(parent)
}
property var optionMenu: Menu {
Kirigami.Action {
text: l10n.get('menu-option-view')
// shortcut: StandardKey.Open
// TODO: open with default program
}
Kirigami.Action {
text: l10n.get('menu-option-save-as')
// Can't think of a suitable shortcut key
// shortcut: StandardKey.Save
onTriggered: {
fileDialog.open()
}
}
}
property var fileDialog: Platform.FileDialog {
acceptLabel: l10n.get('menu-option-save-as')
fileMode: Platform.FileDialog.SaveFile
onAccepted: {
- kazvIO.download(url, file)
+ kazvIO.download(file)
progressBar.visible = true
}
}
}
diff --git a/src/contents/ui/event-types/Image.qml b/src/contents/ui/event-types/Image.qml
index 89f4f6e..77bc20a 100644
--- a/src/contents/ui/event-types/Image.qml
+++ b/src/contents/ui/event-types/Image.qml
@@ -1,66 +1,67 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2020-2021 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import moe.kazv.mxc.kazv 0.0 as MK
import org.kde.kirigami 2.13 as Kirigami
import '..' as Kazv
Simple {
id: upper
property var gender: 'neutral'
property var body: event.content.body
property var mxcUri: event.content.url
property var imageUri: matrixSdk.mxcUriToHttp(mxcUri)
property var imageInfo: event.content.info || {}
property var imageWidth: image.implicitWidth || imageInfo.w || 1 // lest we divide by 0
property var imageHeight: image.implicitHeight || imageInfo.h || 1
property var innerContentWidth: upper.contentMaxWidth - bubble.bubbleSpacing
property var kazvIO: MK.KazvIO {
+ url: imageUri
onResult: {
progressBar.visible = false
}
}
Kazv.Bubble {
id: bubble
ColumnLayout {
id: layout
Label {
Layout.fillWidth: false
Layout.maximumWidth: innerContentWidth
wrapMode: Text.Wrap
text: l10n.get('event-message-image-sent', { gender, body })
}
Image {
id: image
source: imageUri
Layout.maximumWidth: innerContentWidth
Layout.preferredWidth: imageWidth
Layout.preferredHeight: imageHeight / imageWidth * width
fillMode: Image.PreserveAspectFit
Kazv.MediaFileMenu {
kazvIO: upper.kazvIO
progressBar: progressBar
url: imageUri
}
}
Kazv.ProgressBar {
id: progressBar
kazvIO: upper.kazvIO
}
}
}
}
diff --git a/src/kazv-io.cpp b/src/kazv-io.cpp
index 5898036..1edcf27 100644
--- a/src/kazv-io.cpp
+++ b/src/kazv-io.cpp
@@ -1,129 +1,143 @@
#include <QUrl>
#include <KIO/TransferJob>
#include <QObject>
#include <QString>
#include <QSaveFile>
#include <QIODevice>
#include <QFileDialog>
#include <QDebug>
#include <KIO/TransferJob>
#include <algorithm>
#include <execution>
#include "kazv-io.hpp"
struct KazvIOJob {
QPointer<KIO::TransferJob> job;
float progress = 0;
+ // The url is used for KazvIO objects to index its own job
QUrl url;
QPointer<QSaveFile> file;
};
struct KazvIOPrivate {
QUrl url;
};
QVector<KazvIOJob> KazvIO::jobs = QVector<KazvIOJob>(MAX_JOB_NUM);
KazvIO::KazvIO(QObject *parent)
: QObject(parent)
, m_d(new KazvIOPrivate)
{
}
KazvIO::~KazvIO() = default;
-void KazvIO::download(const QUrl url, QUrl localFileUrl)
+void KazvIO::download(QUrl localFileUrl)
{
auto job = std::find_if(std::execution::seq,
jobs.begin(),
jobs.end(),
[](auto it) {return it.job.isNull();});
if (job == jobs.constEnd()) {
qDebug() << "KazvIO busy";
return;
}
- qDebug() << url;
- job->job = KIO::get(url);
- job->url = url;
- m_d->url = url;
+ qDebug() << m_d->url;
+ job->job = KIO::get(m_d->url);
+ job->url = m_d->url;
job->file = new QSaveFile(localFileUrl.path());
job->file->open(QIODevice::WriteOnly);
connect(job->job, &KIO::TransferJob::data, this, &KazvIO::write);
connect(job->job, &KJob::percentChanged, this, &KazvIO::updatePercent);
connect(job->job, &KJob::result, this, &KazvIO::emitResult);
job->job->start();
}
void KazvIO::suspend()
{
auto job = std::find_if(std::execution::seq,
jobs.constBegin(),
jobs.constEnd(),
[this](auto it) {return it.url == m_d->url;});
if (!job->job->suspend()) {
qDebug() << "Suspend job failed";
}
}
void KazvIO::resume()
{
auto job = std::find_if(std::execution::seq,
jobs.constBegin(),
jobs.constEnd(),
[this](auto it) {return it.url == m_d->url;});
if (!job->job->resume()) {
qDebug() << "Resume job failed";
}
}
void KazvIO::cancel()
{
auto job = std::find_if(std::execution::seq,
jobs.constBegin(),
jobs.constEnd(),
[this](auto it) {return it.url == m_d->url;});
if (!job->job->kill()) {
qDebug() << "Cancel job failed";
}
+ job->file->cancelWriting();
+ job->file->commit();
+ Q_EMIT result();
}
float KazvIO::progress()
{
auto job = std::find_if(std::execution::seq,
jobs.constBegin(),
jobs.constEnd(),
[this](auto it) {return it.url == m_d->url;});
return job->progress;
}
+QUrl KazvIO::url()
+{
+ return m_d->url;
+}
+
+void KazvIO::setUrl(QUrl url)
+{
+ m_d->url = url;
+ Q_EMIT urlChanged();
+}
+
void KazvIO::updatePercent(KJob* job, unsigned long percent)
{
auto currentJob = std::find_if(std::execution::seq,
jobs.begin(),
jobs.end(),
[this](auto it) {return it.url == m_d->url;});
currentJob->progress = 1.0 * percent / 100;
Q_EMIT progressChanged();
}
void KazvIO::write(KJob* job, const QByteArray& data)
{
auto currentJob = std::find_if(std::execution::seq,
jobs.begin(),
jobs.end(),
[this](auto it) {return it.url == m_d->url;});
currentJob->file->write(data);
}
void KazvIO::emitResult(KJob * job) {
auto currentJob = std::find_if(std::execution::seq,
jobs.begin(),
jobs.end(),
[this](auto it) {return it.url == m_d->url;});
if (currentJob->job->error())
qDebug() << currentJob->job->errorString();
currentJob->file->commit();
Q_EMIT result();
}
diff --git a/src/kazv-io.hpp b/src/kazv-io.hpp
index 19d4217..51181b0 100644
--- a/src/kazv-io.hpp
+++ b/src/kazv-io.hpp
@@ -1,65 +1,73 @@
#pragma once
#include <QObject>
#include <QUrl>
#include <KIO/Job>
#include <QtQml>
#include <KIO/TransferJob>
#include <QPointer>
#include <QSaveFile>
#include <QByteArray>
#include <QScopedPointer>
#include <QVector>
#define MAX_JOB_NUM 10
struct KazvIOJob;
struct KazvIOPrivate;
class KazvIO : public QObject {
Q_OBJECT
QML_ELEMENT
/*
* Progress in decimal form, from 0 to 1
*/
Q_PROPERTY(float progress READ progress NOTIFY progressChanged)
- // Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
+ /*
+ * url of the file to download or upload.
+ */
+ Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
private:
+ /*
+ * hold all job.
+ */
static QVector<KazvIOJob> jobs;
QScopedPointer<KazvIOPrivate> m_d;
public:
explicit KazvIO(QObject *parent = 0);
~KazvIO() override;
+
/**
* QML should call this function to initiate a download.
* url is the file to download.
* localFileUrl is the file to store.
*/
- Q_INVOKABLE void download(QUrl url, QUrl localFileUrl);
- /** Pause the download.
+ Q_INVOKABLE void download(QUrl localFileUrl);
+ /**
+ * Pause the download.
*/
Q_INVOKABLE void suspend();
/**
* Resume the download.
*/
Q_INVOKABLE void resume();
/**
* Cancel the download.
*/
Q_INVOKABLE void cancel();
float progress();
- // QUrl url();
- // void setUrl(QUrl url);
+ QUrl url();
+ void setUrl(QUrl url);
Q_SIGNALS:
void progressChanged();
- // void urlChanged();
+ void urlChanged();
void result();
private Q_SLOTS:
void updatePercent(KJob* job, unsigned long percent);
void write(KJob* job, const QByteArray& data);
void emitResult(KJob* job);
};
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jan 19, 1:55 PM (22 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55212
Default Alt Text
(9 KB)
Attached To
Mode
rK kazv
Attached
Detach File
Event Timeline
Log In to Comment