Page MenuHomePhorge

No OneTemporary

Size
10 KB
Referenced Files
None
Subscribers
None
diff --git a/src/contents/ui/MediaFileMenu.qml b/src/contents/ui/MediaFileMenu.qml
index 3fdf08e..63e02f6 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()
+ 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.fileUrl = file
- kazvIO.download(imageUri)
+ kazvIO.download(url, file)
progressBar.visible = true
}
}
}
diff --git a/src/contents/ui/event-types/Image.qml b/src/contents/ui/event-types/Image.qml
index fe60557..89f4f6e 100644
--- a/src/contents/ui/event-types/Image.qml
+++ b/src/contents/ui/event-types/Image.qml
@@ -1,65 +1,66 @@
/*
* 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 {
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 453dbc4..5898036 100644
--- a/src/kazv-io.cpp
+++ b/src/kazv-io.cpp
@@ -1,95 +1,129 @@
#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 KazvIOPrivate {
+struct KazvIOJob {
QPointer<KIO::TransferJob> job;
float progress = 0;
- QUrl fileUrl;
- QSaveFile file;
+ 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(QUrl url)
+void KazvIO::download(const QUrl url, QUrl localFileUrl)
{
- if (m_d->job) {
- return;
+ 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;
}
- m_d->job = KIO::get(url);
- m_d->file.setFileName(m_d->fileUrl.path());
- m_d->file.open(QIODevice::WriteOnly);
- connect(m_d->job, &KIO::TransferJob::data, this, &KazvIO::write);
- connect(m_d->job, &KJob::percentChanged, this, &KazvIO::updatePercent);
- connect(m_d->job, &KJob::result, this, &KazvIO::emitResult);
- m_d->job->start();
+ qDebug() << url;
+ job->job = KIO::get(url);
+ job->url = url;
+ m_d->url = 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()
{
- if (!m_d->job->suspend()) {
- qDebug() << "Suspend job failed";
+ 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()
{
- if (!m_d->job->resume()) {
- qDebug() << "Resume job failed";
+ 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()
{
- if (!m_d->job->kill()) {
- qDebug() << "Cancel job failed";
+ 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";
}
}
float KazvIO::progress()
{
- return m_d->progress;
-}
-
-QUrl KazvIO::fileUrl()
-{
- return m_d->fileUrl;
-}
-
-void KazvIO::setFileUrl(QUrl fileUrl)
-{
- m_d->fileUrl = fileUrl;
- Q_EMIT fileUrlChanged();
+ auto job = std::find_if(std::execution::seq,
+ jobs.constBegin(),
+ jobs.constEnd(),
+ [this](auto it) {return it.url == m_d->url;});
+ return job->progress;
}
void KazvIO::updatePercent(KJob* job, unsigned long percent)
{
- m_d->progress = 1.0 * percent / 100;
+ 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)
{
- m_d->file.write(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) {
- if (m_d->job->error())
- qDebug() << job->errorString();
- m_d->file.commit();
+ 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 b82ad67..19d4217 100644
--- a/src/kazv-io.hpp
+++ b/src/kazv-io.hpp
@@ -1,60 +1,65 @@
#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
+ /*
+ * Progress in decimal form, from 0 to 1
+ */
Q_PROPERTY(float progress READ progress NOTIFY progressChanged)
- Q_PROPERTY(QUrl fileUrl READ fileUrl WRITE setFileUrl NOTIFY fileUrlChanged)
+ // Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
private:
+ 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.
- * return job id, QML should restore it to call suspend, cancel, etc.
+ * localFileUrl is the file to store.
*/
- Q_INVOKABLE void download(QUrl url);
+ Q_INVOKABLE void download(QUrl url, QUrl localFileUrl);
/** Pause the download.
- * id is the return value of the download function.
*/
Q_INVOKABLE void suspend();
/**
* Resume the download.
- * id is the return value of the download function.
*/
Q_INVOKABLE void resume();
/**
* Cancel the download.
- * id is the return value of the download function.
*/
Q_INVOKABLE void cancel();
float progress();
- QUrl fileUrl();
- void setFileUrl(QUrl fileUrl);
+ // QUrl url();
+ // void setUrl(QUrl url);
Q_SIGNALS:
void progressChanged();
- void fileUrlChanged();
+ // void urlChanged();
void result();
-public Q_SLOTS:
+private Q_SLOTS:
void updatePercent(KJob* job, unsigned long percent);
void write(KJob* job, const QByteArray& data);
void emitResult(KJob* job);
};

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 7:25 PM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55414
Default Alt Text
(10 KB)

Event Timeline