mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 04:28:49 +03:00
parent
53f670096c
commit
ddfce136ed
22 changed files with 388 additions and 73 deletions
|
@ -144,6 +144,7 @@ set(SRC_FILES
|
||||||
# Dialogs
|
# Dialogs
|
||||||
src/dialogs/CreateRoom.cc
|
src/dialogs/CreateRoom.cc
|
||||||
src/dialogs/ImageOverlay.cc
|
src/dialogs/ImageOverlay.cc
|
||||||
|
src/dialogs/PreviewImageOverlay.cc
|
||||||
src/dialogs/InviteUsers.cc
|
src/dialogs/InviteUsers.cc
|
||||||
src/dialogs/JoinRoom.cc
|
src/dialogs/JoinRoom.cc
|
||||||
src/dialogs/LeaveRoom.cc
|
src/dialogs/LeaveRoom.cc
|
||||||
|
@ -229,6 +230,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
||||||
# Dialogs
|
# Dialogs
|
||||||
include/dialogs/CreateRoom.h
|
include/dialogs/CreateRoom.h
|
||||||
include/dialogs/ImageOverlay.h
|
include/dialogs/ImageOverlay.h
|
||||||
|
include/dialogs/PreviewImageOverlay.h
|
||||||
include/dialogs/InviteUsers.h
|
include/dialogs/InviteUsers.h
|
||||||
include/dialogs/JoinRoom.h
|
include/dialogs/JoinRoom.h
|
||||||
include/dialogs/LeaveRoom.h
|
include/dialogs/LeaveRoom.h
|
||||||
|
|
|
@ -55,9 +55,15 @@ public:
|
||||||
void downloadImage(const QString &event_id, const QUrl &url);
|
void downloadImage(const QString &event_id, const QUrl &url);
|
||||||
void downloadFile(const QString &event_id, const QUrl &url);
|
void downloadFile(const QString &event_id, const QUrl &url);
|
||||||
void messages(const QString &room_id, const QString &from_token, int limit = 30) noexcept;
|
void messages(const QString &room_id, const QString &from_token, int limit = 30) noexcept;
|
||||||
void uploadImage(const QString &roomid, const QString &filename);
|
void uploadImage(const QString &roomid,
|
||||||
void uploadFile(const QString &roomid, const QString &filename);
|
const QSharedPointer<QIODevice> data,
|
||||||
void uploadAudio(const QString &roomid, const QString &filename);
|
const QString &filename);
|
||||||
|
void uploadFile(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename);
|
||||||
|
void uploadAudio(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename);
|
||||||
void joinRoom(const QString &roomIdOrAlias);
|
void joinRoom(const QString &roomIdOrAlias);
|
||||||
void leaveRoom(const QString &roomId);
|
void leaveRoom(const QString &roomId);
|
||||||
void sendTypingNotification(const QString &roomid, int timeoutInMillis = 20000);
|
void sendTypingNotification(const QString &roomid, int timeoutInMillis = 20000);
|
||||||
|
@ -98,7 +104,10 @@ signals:
|
||||||
const QString &homeserver,
|
const QString &homeserver,
|
||||||
const QString &token);
|
const QString &token);
|
||||||
void versionSuccess();
|
void versionSuccess();
|
||||||
void imageUploaded(const QString &roomid, const QString &filename, const QString &url);
|
void imageUploaded(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename,
|
||||||
|
const QString &url);
|
||||||
void fileUploaded(const QString &roomid, const QString &filename, const QString &url);
|
void fileUploaded(const QString &roomid, const QString &filename, const QString &url);
|
||||||
void audioUploaded(const QString &roomid, const QString &filename, const QString &url);
|
void audioUploaded(const QString &roomid, const QString &filename, const QString &url);
|
||||||
|
|
||||||
|
@ -131,7 +140,7 @@ signals:
|
||||||
void roomCreationFailed(const QString &msg);
|
void roomCreationFailed(const QString &msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QNetworkReply *makeUploadRequest(const QString &filename);
|
QNetworkReply *makeUploadRequest(QSharedPointer<QIODevice> iodev);
|
||||||
|
|
||||||
// Client API prefix.
|
// Client API prefix.
|
||||||
QString clientApiUrl_;
|
QString clientApiUrl_;
|
||||||
|
|
|
@ -27,8 +27,14 @@
|
||||||
#include "FlatButton.h"
|
#include "FlatButton.h"
|
||||||
#include "LoadingIndicator.h"
|
#include "LoadingIndicator.h"
|
||||||
|
|
||||||
|
#include "dialogs/PreviewImageOverlay.h"
|
||||||
|
|
||||||
#include "emoji/PickButton.h"
|
#include "emoji/PickButton.h"
|
||||||
|
|
||||||
|
namespace dialogs {
|
||||||
|
class PreviewImageOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
class FilteredTextEdit : public QTextEdit
|
class FilteredTextEdit : public QTextEdit
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -48,16 +54,22 @@ signals:
|
||||||
void stoppedTyping();
|
void stoppedTyping();
|
||||||
void message(QString);
|
void message(QString);
|
||||||
void command(QString name, QString args);
|
void command(QString name, QString args);
|
||||||
|
void image(const QSharedPointer<QIODevice> iodev, const QString &img_name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
|
bool canInsertFromMimeData(const QMimeData *source) const override;
|
||||||
|
void insertFromMimeData(const QMimeData *source) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<QString> true_history_, working_history_;
|
std::deque<QString> true_history_, working_history_;
|
||||||
size_t history_index_;
|
size_t history_index_;
|
||||||
QTimer *typingTimer_;
|
QTimer *typingTimer_;
|
||||||
|
|
||||||
|
dialogs::PreviewImageOverlay previewDialog_;
|
||||||
|
|
||||||
void textChanged();
|
void textChanged();
|
||||||
|
void receiveImage(const QByteArray img, const QString &img_name);
|
||||||
void afterCompletion(int);
|
void afterCompletion(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,9 +95,9 @@ signals:
|
||||||
void sendTextMessage(QString msg);
|
void sendTextMessage(QString msg);
|
||||||
void sendEmoteMessage(QString msg);
|
void sendEmoteMessage(QString msg);
|
||||||
|
|
||||||
void uploadImage(QString filename);
|
void uploadImage(QSharedPointer<QIODevice> data, const QString &filename);
|
||||||
void uploadFile(QString filename);
|
void uploadFile(QSharedPointer<QIODevice> data, const QString &filename);
|
||||||
void uploadAudio(QString filename);
|
void uploadAudio(QSharedPointer<QIODevice> data, const QString &filename);
|
||||||
|
|
||||||
void sendJoinRoomRequest(const QString &room);
|
void sendJoinRoomRequest(const QString &room);
|
||||||
|
|
||||||
|
|
57
include/dialogs/PreviewImageOverlay.h
Normal file
57
include/dialogs/PreviewImageOverlay.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "FlatButton.h"
|
||||||
|
|
||||||
|
class QMimeData;
|
||||||
|
|
||||||
|
namespace dialogs {
|
||||||
|
|
||||||
|
class PreviewImageOverlay : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
PreviewImageOverlay(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void setImageAndCreate(const QByteArray data, const QString &type);
|
||||||
|
void setImageAndCreate(const QString &path);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void confirmImageUpload(const QByteArray data, const QString &img_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
QPixmap image_;
|
||||||
|
QByteArray imageData_;
|
||||||
|
QString imagePath_;
|
||||||
|
|
||||||
|
QLabel titleLabel_;
|
||||||
|
QLabel imageLabel_;
|
||||||
|
QLineEdit imageName_;
|
||||||
|
|
||||||
|
FlatButton upload_;
|
||||||
|
FlatButton cancel_;
|
||||||
|
};
|
||||||
|
} // dialogs
|
|
@ -87,7 +87,9 @@ public:
|
||||||
void addUserMessage(mtx::events::MessageType ty, const QString &msg);
|
void addUserMessage(mtx::events::MessageType ty, const QString &msg);
|
||||||
|
|
||||||
template<class Widget, mtx::events::MessageType MsgType>
|
template<class Widget, mtx::events::MessageType MsgType>
|
||||||
void addUserMessage(const QString &url, const QString &filename);
|
void addUserMessage(const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename);
|
||||||
void updatePendingMessage(int txn_id, QString event_id);
|
void updatePendingMessage(int txn_id, QString event_id);
|
||||||
void scrollDown();
|
void scrollDown();
|
||||||
void addDateSeparator(QDateTime datetime, int position);
|
void addDateSeparator(QDateTime datetime, int position);
|
||||||
|
@ -216,11 +218,13 @@ private:
|
||||||
|
|
||||||
template<class Widget, mtx::events::MessageType MsgType>
|
template<class Widget, mtx::events::MessageType MsgType>
|
||||||
void
|
void
|
||||||
TimelineView::addUserMessage(const QString &url, const QString &filename)
|
TimelineView::addUserMessage(const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename)
|
||||||
{
|
{
|
||||||
auto with_sender = lastSender_ != local_user_;
|
auto with_sender = lastSender_ != local_user_;
|
||||||
|
|
||||||
auto widget = new Widget(client_, url, filename, this);
|
auto widget = new Widget(client_, url, data, filename, this);
|
||||||
|
|
||||||
TimelineItem *view_item =
|
TimelineItem *view_item =
|
||||||
new TimelineItem(widget, local_user_, with_sender, scroll_widget_);
|
new TimelineItem(widget, local_user_, with_sender, scroll_widget_);
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include <mtx.hpp>
|
#include <mtx.hpp>
|
||||||
|
|
||||||
|
class QFile;
|
||||||
|
|
||||||
class MatrixClient;
|
class MatrixClient;
|
||||||
class RoomInfoListItem;
|
class RoomInfoListItem;
|
||||||
class TimelineView;
|
class TimelineView;
|
||||||
|
@ -64,7 +66,10 @@ public slots:
|
||||||
void setHistoryView(const QString &room_id);
|
void setHistoryView(const QString &room_id);
|
||||||
void queueTextMessage(const QString &msg);
|
void queueTextMessage(const QString &msg);
|
||||||
void queueEmoteMessage(const QString &msg);
|
void queueEmoteMessage(const QString &msg);
|
||||||
void queueImageMessage(const QString &roomid, const QString &filename, const QString &url);
|
void queueImageMessage(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename,
|
||||||
|
const QString &url);
|
||||||
void queueFileMessage(const QString &roomid, const QString &filename, const QString &url);
|
void queueFileMessage(const QString &roomid, const QString &filename, const QString &url);
|
||||||
void queueAudioMessage(const QString &roomid, const QString &filename, const QString &url);
|
void queueAudioMessage(const QString &roomid, const QString &filename, const QString &url);
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
|
|
||||||
AudioItem(QSharedPointer<MatrixClient> client,
|
AudioItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
|
|
||||||
FileItem(QSharedPointer<MatrixClient> client,
|
FileItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ public:
|
||||||
|
|
||||||
ImageItem(QSharedPointer<MatrixClient> client,
|
ImageItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
|
|
||||||
VideoItem(QSharedPointer<MatrixClient> client,
|
VideoItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -95,16 +95,13 @@ dialogs--LeaveRoom,
|
||||||
dialogs--CreateRoom,
|
dialogs--CreateRoom,
|
||||||
dialogs--InviteUsers,
|
dialogs--InviteUsers,
|
||||||
dialogs--ReadReceipts,
|
dialogs--ReadReceipts,
|
||||||
dialogs--JoinRoom {
|
dialogs--JoinRoom,
|
||||||
background-color: #383c4a;
|
dialogs--PreviewImageOverlay {
|
||||||
color: #caccd1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QListWidget {
|
|
||||||
background-color: #383c4a;
|
background-color: #383c4a;
|
||||||
color: #caccd1;
|
color: #caccd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QListWidget,
|
||||||
WelcomePage,
|
WelcomePage,
|
||||||
LoginPage,
|
LoginPage,
|
||||||
RegisterPage {
|
RegisterPage {
|
||||||
|
|
|
@ -98,11 +98,8 @@ dialogs--LeaveRoom,
|
||||||
dialogs--CreateRoom,
|
dialogs--CreateRoom,
|
||||||
dialogs--InviteUsers,
|
dialogs--InviteUsers,
|
||||||
dialogs--ReadReceipts,
|
dialogs--ReadReceipts,
|
||||||
dialogs--JoinRoom {
|
dialogs--JoinRoom,
|
||||||
background-color: white;
|
dialogs--PreviewImageOverlay,
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
QListWidget {
|
QListWidget {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
|
|
@ -228,17 +228,26 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client,
|
||||||
client_.data(),
|
client_.data(),
|
||||||
&MatrixClient::joinRoom);
|
&MatrixClient::joinRoom);
|
||||||
|
|
||||||
connect(text_input_, &TextInputWidget::uploadImage, this, [=](QString filename) {
|
connect(text_input_,
|
||||||
client_->uploadImage(current_room_, filename);
|
&TextInputWidget::uploadImage,
|
||||||
});
|
this,
|
||||||
|
[=](QSharedPointer<QIODevice> data, const QString &fn) {
|
||||||
|
client_->uploadImage(current_room_, data, fn);
|
||||||
|
});
|
||||||
|
|
||||||
connect(text_input_, &TextInputWidget::uploadFile, this, [=](QString filename) {
|
connect(text_input_,
|
||||||
client_->uploadFile(current_room_, filename);
|
&TextInputWidget::uploadFile,
|
||||||
});
|
this,
|
||||||
|
[=](QSharedPointer<QIODevice> data, const QString &fn) {
|
||||||
|
client_->uploadFile(current_room_, data, fn);
|
||||||
|
});
|
||||||
|
|
||||||
connect(text_input_, &TextInputWidget::uploadAudio, this, [=](QString filename) {
|
connect(text_input_,
|
||||||
client_->uploadAudio(current_room_, filename);
|
&TextInputWidget::uploadAudio,
|
||||||
});
|
this,
|
||||||
|
[=](QSharedPointer<QIODevice> data, const QString &fn) {
|
||||||
|
client_->uploadAudio(current_room_, data, fn);
|
||||||
|
});
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
client_.data(), &MatrixClient::roomCreationFailed, this, &ChatPage::showNotification);
|
client_.data(), &MatrixClient::roomCreationFailed, this, &ChatPage::showNotification);
|
||||||
|
@ -246,9 +255,9 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client,
|
||||||
connect(client_.data(),
|
connect(client_.data(),
|
||||||
&MatrixClient::imageUploaded,
|
&MatrixClient::imageUploaded,
|
||||||
this,
|
this,
|
||||||
[=](QString roomid, QString filename, QString url) {
|
[=](QString roomid, QSharedPointer<QIODevice> data, QString filename, QString url) {
|
||||||
text_input_->hideUploadSpinner();
|
text_input_->hideUploadSpinner();
|
||||||
view_manager_->queueImageMessage(roomid, filename, url);
|
view_manager_->queueImageMessage(roomid, data, filename, url);
|
||||||
});
|
});
|
||||||
connect(client_.data(),
|
connect(client_.data(),
|
||||||
&MatrixClient::fileUploaded,
|
&MatrixClient::fileUploaded,
|
||||||
|
|
|
@ -821,14 +821,16 @@ MatrixClient::messages(const QString &roomid, const QString &from_token, int lim
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MatrixClient::uploadImage(const QString &roomid, const QString &filename)
|
MatrixClient::uploadImage(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename)
|
||||||
{
|
{
|
||||||
auto reply = makeUploadRequest(filename);
|
auto reply = makeUploadRequest(data);
|
||||||
|
|
||||||
if (reply == nullptr)
|
if (reply == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
connect(reply, &QNetworkReply::finished, this, [this, reply, roomid, filename]() {
|
connect(reply, &QNetworkReply::finished, this, [this, reply, roomid, data, filename]() {
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
@ -838,12 +840,12 @@ MatrixClient::uploadImage(const QString &roomid, const QString &filename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = reply->readAll();
|
auto res_data = reply->readAll();
|
||||||
|
|
||||||
if (data.isEmpty())
|
if (res_data.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto json = QJsonDocument::fromJson(data);
|
auto json = QJsonDocument::fromJson(res_data);
|
||||||
|
|
||||||
if (!json.isObject()) {
|
if (!json.isObject()) {
|
||||||
qDebug() << "Media upload: Response is not a json object.";
|
qDebug() << "Media upload: Response is not a json object.";
|
||||||
|
@ -857,16 +859,18 @@ MatrixClient::uploadImage(const QString &roomid, const QString &filename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit imageUploaded(roomid, filename, object.value("content_uri").toString());
|
emit imageUploaded(roomid, data, filename, object.value("content_uri").toString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MatrixClient::uploadFile(const QString &roomid, const QString &filename)
|
MatrixClient::uploadFile(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename)
|
||||||
{
|
{
|
||||||
auto reply = makeUploadRequest(filename);
|
auto reply = makeUploadRequest(data);
|
||||||
|
|
||||||
connect(reply, &QNetworkReply::finished, this, [this, reply, roomid, filename]() {
|
connect(reply, &QNetworkReply::finished, this, [this, reply, roomid, data, filename]() {
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
@ -900,11 +904,13 @@ MatrixClient::uploadFile(const QString &roomid, const QString &filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MatrixClient::uploadAudio(const QString &roomid, const QString &filename)
|
MatrixClient::uploadAudio(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
|
const QString &filename)
|
||||||
{
|
{
|
||||||
auto reply = makeUploadRequest(filename);
|
auto reply = makeUploadRequest(data);
|
||||||
|
|
||||||
connect(reply, &QNetworkReply::finished, this, [this, reply, roomid, filename]() {
|
connect(reply, &QNetworkReply::finished, this, [this, reply, roomid, data, filename]() {
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
@ -1158,7 +1164,7 @@ MatrixClient::readEvent(const QString &room_id, const QString &event_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply *
|
QNetworkReply *
|
||||||
MatrixClient::makeUploadRequest(const QString &filename)
|
MatrixClient::makeUploadRequest(QSharedPointer<QIODevice> iodev)
|
||||||
{
|
{
|
||||||
QUrlQuery query;
|
QUrlQuery query;
|
||||||
query.addQueryItem("access_token", token_);
|
query.addQueryItem("access_token", token_);
|
||||||
|
@ -1167,20 +1173,18 @@ MatrixClient::makeUploadRequest(const QString &filename)
|
||||||
endpoint.setPath(mediaApiUrl_ + "/upload");
|
endpoint.setPath(mediaApiUrl_ + "/upload");
|
||||||
endpoint.setQuery(query);
|
endpoint.setQuery(query);
|
||||||
|
|
||||||
QFile file(filename);
|
if (!iodev->open(QIODevice::ReadOnly)) {
|
||||||
if (!file.open(QIODevice::ReadWrite)) {
|
qWarning() << "Error while reading device:" << iodev->errorString();
|
||||||
qDebug() << "Error while reading" << filename;
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMimeDatabase db;
|
QMimeDatabase db;
|
||||||
QMimeType mime = db.mimeTypeForFile(filename, QMimeDatabase::MatchContent);
|
QMimeType mime = db.mimeTypeForData(iodev.data());
|
||||||
|
|
||||||
QNetworkRequest request(QString(endpoint.toEncoded()));
|
QNetworkRequest request(QString(endpoint.toEncoded()));
|
||||||
request.setHeader(QNetworkRequest::ContentLengthHeader, file.size());
|
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, mime.name());
|
request.setHeader(QNetworkRequest::ContentTypeHeader, mime.name());
|
||||||
|
|
||||||
auto reply = post(request, file.readAll());
|
auto reply = post(request, iodev.data());
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
#include <QMimeData>
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
#include <QMimeType>
|
#include <QMimeType>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
@ -33,6 +36,7 @@ static constexpr size_t INPUT_HISTORY_SIZE = 127;
|
||||||
FilteredTextEdit::FilteredTextEdit(QWidget *parent)
|
FilteredTextEdit::FilteredTextEdit(QWidget *parent)
|
||||||
: QTextEdit{parent}
|
: QTextEdit{parent}
|
||||||
, history_index_{0}
|
, history_index_{0}
|
||||||
|
, previewDialog_{parent}
|
||||||
{
|
{
|
||||||
connect(document()->documentLayout(),
|
connect(document()->documentLayout(),
|
||||||
&QAbstractTextDocumentLayout::documentSizeChanged,
|
&QAbstractTextDocumentLayout::documentSizeChanged,
|
||||||
|
@ -50,6 +54,12 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent)
|
||||||
typingTimer_->setSingleShot(true);
|
typingTimer_->setSingleShot(true);
|
||||||
|
|
||||||
connect(typingTimer_, &QTimer::timeout, this, &FilteredTextEdit::stopTyping);
|
connect(typingTimer_, &QTimer::timeout, this, &FilteredTextEdit::stopTyping);
|
||||||
|
connect(&previewDialog_,
|
||||||
|
&dialogs::PreviewImageOverlay::confirmImageUpload,
|
||||||
|
this,
|
||||||
|
&FilteredTextEdit::receiveImage);
|
||||||
|
|
||||||
|
previewDialog_.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -101,6 +111,42 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FilteredTextEdit::canInsertFromMimeData(const QMimeData *source) const
|
||||||
|
{
|
||||||
|
return (source->hasImage() || QTextEdit::canInsertFromMimeData(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilteredTextEdit::insertFromMimeData(const QMimeData *source)
|
||||||
|
{
|
||||||
|
if (source->hasImage()) {
|
||||||
|
const auto formats = source->formats();
|
||||||
|
const auto idx = formats.indexOf(
|
||||||
|
QRegularExpression{"image/.+", QRegularExpression::CaseInsensitiveOption});
|
||||||
|
|
||||||
|
// Note: in the future we may want to look into what the best choice is from the
|
||||||
|
// formats list. For now we will default to PNG format.
|
||||||
|
QString type = "png";
|
||||||
|
if (idx != -1) {
|
||||||
|
type = formats.at(idx).split('/')[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode raw pixel data of image.
|
||||||
|
QByteArray data = source->data("image/" + type);
|
||||||
|
previewDialog_.setImageAndCreate(data, type);
|
||||||
|
previewDialog_.show();
|
||||||
|
} else if (source->hasFormat("x-special/gnome-copied-files") &&
|
||||||
|
QImageReader{source->text()}.canRead()) {
|
||||||
|
// Special case for X11 users. See "Notes for X11 Users" in source.
|
||||||
|
// Source: http://doc.qt.io/qt-5/qclipboard.html
|
||||||
|
previewDialog_.setImageAndCreate(source->text());
|
||||||
|
previewDialog_.show();
|
||||||
|
} else {
|
||||||
|
QTextEdit::insertFromMimeData(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FilteredTextEdit::stopTyping()
|
FilteredTextEdit::stopTyping()
|
||||||
{
|
{
|
||||||
|
@ -146,6 +192,7 @@ FilteredTextEdit::submit()
|
||||||
history_index_ = 0;
|
history_index_ = 0;
|
||||||
|
|
||||||
QString text = toPlainText();
|
QString text = toPlainText();
|
||||||
|
|
||||||
if (text.startsWith('/')) {
|
if (text.startsWith('/')) {
|
||||||
int command_end = text.indexOf(' ');
|
int command_end = text.indexOf(' ');
|
||||||
if (command_end == -1)
|
if (command_end == -1)
|
||||||
|
@ -170,6 +217,14 @@ FilteredTextEdit::textChanged()
|
||||||
working_history_[history_index_] = toPlainText();
|
working_history_[history_index_] = toPlainText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilteredTextEdit::receiveImage(const QByteArray img, const QString &img_name)
|
||||||
|
{
|
||||||
|
QSharedPointer<QBuffer> buffer{new QBuffer{this}};
|
||||||
|
buffer->setData(img);
|
||||||
|
emit image(buffer, img_name);
|
||||||
|
}
|
||||||
|
|
||||||
TextInputWidget::TextInputWidget(QWidget *parent)
|
TextInputWidget::TextInputWidget(QWidget *parent)
|
||||||
: QFrame(parent)
|
: QFrame(parent)
|
||||||
{
|
{
|
||||||
|
@ -231,6 +286,7 @@ TextInputWidget::TextInputWidget(QWidget *parent)
|
||||||
connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
|
connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
|
||||||
connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage);
|
connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage);
|
||||||
connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command);
|
connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command);
|
||||||
|
connect(input_, &FilteredTextEdit::image, this, &TextInputWidget::uploadImage);
|
||||||
connect(emojiBtn_,
|
connect(emojiBtn_,
|
||||||
SIGNAL(emojiSelected(const QString &)),
|
SIGNAL(emojiSelected(const QString &)),
|
||||||
this,
|
this,
|
||||||
|
@ -289,12 +345,13 @@ TextInputWidget::openFileSelection()
|
||||||
|
|
||||||
const auto format = mime.name().split("/")[0];
|
const auto format = mime.name().split("/")[0];
|
||||||
|
|
||||||
|
QSharedPointer<QFile> file{new QFile{fileName, this}};
|
||||||
if (format == "image")
|
if (format == "image")
|
||||||
emit uploadImage(fileName);
|
emit uploadImage(file, fileName);
|
||||||
else if (format == "audio")
|
else if (format == "audio")
|
||||||
emit uploadAudio(fileName);
|
emit uploadAudio(file, fileName);
|
||||||
else
|
else
|
||||||
emit uploadFile(fileName);
|
emit uploadFile(file, fileName);
|
||||||
|
|
||||||
showUploadSpinner();
|
showUploadSpinner();
|
||||||
}
|
}
|
||||||
|
|
142
src/dialogs/PreviewImageOverlay.cc
Normal file
142
src/dialogs/PreviewImageOverlay.cc
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
#include "dialogs/PreviewImageOverlay.h"
|
||||||
|
|
||||||
|
using namespace dialogs;
|
||||||
|
|
||||||
|
static constexpr const char *DEFAULT = "Upload image?";
|
||||||
|
static constexpr const char *ERROR = "Failed to load image type '%1'. Continue upload?";
|
||||||
|
|
||||||
|
PreviewImageOverlay::PreviewImageOverlay(QWidget *parent)
|
||||||
|
: QWidget{parent}
|
||||||
|
, titleLabel_{tr(DEFAULT), this}
|
||||||
|
, imageLabel_{this}
|
||||||
|
, imageName_{tr("clipboard"), this}
|
||||||
|
, upload_{tr("Upload"), this}
|
||||||
|
, cancel_{tr("Cancel"), this}
|
||||||
|
{
|
||||||
|
auto hlayout = new QHBoxLayout;
|
||||||
|
hlayout->addWidget(&upload_);
|
||||||
|
hlayout->addWidget(&cancel_);
|
||||||
|
|
||||||
|
auto vlayout = new QVBoxLayout{this};
|
||||||
|
vlayout->addWidget(&titleLabel_);
|
||||||
|
vlayout->addWidget(&imageLabel_);
|
||||||
|
vlayout->addWidget(&imageName_);
|
||||||
|
vlayout->addLayout(hlayout);
|
||||||
|
|
||||||
|
connect(&upload_, &QPushButton::clicked, [&]() {
|
||||||
|
emit confirmImageUpload(imageData_, imageName_.text());
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
connect(&cancel_, &QPushButton::clicked, [&]() { close(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PreviewImageOverlay::init()
|
||||||
|
{
|
||||||
|
auto window = QApplication::activeWindow();
|
||||||
|
auto winsize = window->frameGeometry().size();
|
||||||
|
auto center = window->frameGeometry().center();
|
||||||
|
auto img_size = image_.size();
|
||||||
|
|
||||||
|
imageName_.setText(QFileInfo{imagePath_}.fileName());
|
||||||
|
|
||||||
|
setAutoFillBackground(true);
|
||||||
|
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
|
||||||
|
setWindowModality(Qt::WindowModal);
|
||||||
|
|
||||||
|
titleLabel_.setStyleSheet(
|
||||||
|
QString{"font-weight: bold; font-size: %1px;"}.arg(conf::headerFontSize));
|
||||||
|
titleLabel_.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
titleLabel_.setAlignment(Qt::AlignCenter);
|
||||||
|
imageLabel_.setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||||
|
imageLabel_.setAlignment(Qt::AlignCenter);
|
||||||
|
imageName_.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
imageName_.setAlignment(Qt::AlignCenter);
|
||||||
|
upload_.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
cancel_.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
upload_.setFontSize(conf::btn::fontSize);
|
||||||
|
cancel_.setFontSize(conf::btn::fontSize);
|
||||||
|
|
||||||
|
// Scale image preview to the size of the current window if it is larger.
|
||||||
|
if ((img_size.height() * img_size.width()) > (winsize.height() * winsize.width())) {
|
||||||
|
imageLabel_.setPixmap(image_.scaled(winsize, Qt::KeepAspectRatio));
|
||||||
|
} else {
|
||||||
|
imageLabel_.setPixmap(image_);
|
||||||
|
move(center.x() - (width() * 0.5), center.y() - (height() * 0.5));
|
||||||
|
}
|
||||||
|
imageLabel_.setScaledContents(false);
|
||||||
|
|
||||||
|
raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PreviewImageOverlay::setImageAndCreate(const QByteArray data, const QString &type)
|
||||||
|
{
|
||||||
|
imageData_ = data;
|
||||||
|
imagePath_ = "clipboard." + type;
|
||||||
|
auto loaded = image_.loadFromData(imageData_);
|
||||||
|
if (!loaded) {
|
||||||
|
titleLabel_.setText(QString{tr(ERROR)}.arg(type));
|
||||||
|
} else {
|
||||||
|
titleLabel_.setText(tr(DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PreviewImageOverlay::setImageAndCreate(const QString &path)
|
||||||
|
{
|
||||||
|
QFile file{path};
|
||||||
|
imagePath_ = path;
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
qWarning() << "Failed to open image from:" << path;
|
||||||
|
qWarning() << "Reason:" << file.errorString();
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((imageData_ = file.readAll()).isEmpty()) {
|
||||||
|
qWarning() << "Failed to read image:" << file.errorString();
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto loaded = image_.loadFromData(imageData_);
|
||||||
|
if (!loaded) {
|
||||||
|
auto t = QFileInfo{path}.suffix();
|
||||||
|
titleLabel_.setText(QString{tr(ERROR)}.arg(t));
|
||||||
|
} else {
|
||||||
|
titleLabel_.setText(tr(DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
|
@ -510,12 +510,8 @@ TimelineView::sendNextPendingMessage()
|
||||||
case mtx::events::MessageType::Image:
|
case mtx::events::MessageType::Image:
|
||||||
case mtx::events::MessageType::File:
|
case mtx::events::MessageType::File:
|
||||||
// FIXME: Improve the API
|
// FIXME: Improve the API
|
||||||
client_->sendRoomMessage(m.ty,
|
client_->sendRoomMessage(
|
||||||
m.txn_id,
|
m.ty, m.txn_id, room_id_, m.filename, QFileInfo(m.filename), m.body);
|
||||||
room_id_,
|
|
||||||
QFileInfo(m.filename).fileName(),
|
|
||||||
QFileInfo(m.filename),
|
|
||||||
m.body);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
client_->sendRoomMessage(m.ty, m.txn_id, room_id_, m.body, QFileInfo());
|
client_->sendRoomMessage(m.ty, m.txn_id, room_id_, m.body, QFileInfo());
|
||||||
|
|
|
@ -85,6 +85,7 @@ TimelineViewManager::queueEmoteMessage(const QString &msg)
|
||||||
|
|
||||||
void
|
void
|
||||||
TimelineViewManager::queueImageMessage(const QString &roomid,
|
TimelineViewManager::queueImageMessage(const QString &roomid,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
const QString &url)
|
const QString &url)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +96,7 @@ TimelineViewManager::queueImageMessage(const QString &roomid,
|
||||||
|
|
||||||
auto view = views_[roomid];
|
auto view = views_[roomid];
|
||||||
|
|
||||||
view->addUserMessage<ImageItem, mtx::events::MessageType::Image>(url, filename);
|
view->addUserMessage<ImageItem, mtx::events::MessageType::Image>(url, data, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -110,7 +111,7 @@ TimelineViewManager::queueFileMessage(const QString &roomid,
|
||||||
|
|
||||||
auto view = views_[roomid];
|
auto view = views_[roomid];
|
||||||
|
|
||||||
view->addUserMessage<FileItem, mtx::events::MessageType::File>(url, filename);
|
view->addUserMessage<FileItem, mtx::events::MessageType::File>(url, nullptr, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -125,7 +126,7 @@ TimelineViewManager::queueAudioMessage(const QString &roomid,
|
||||||
|
|
||||||
auto view = views_[roomid];
|
auto view = views_[roomid];
|
||||||
|
|
||||||
view->addUserMessage<AudioItem, mtx::events::MessageType::Audio>(url, filename);
|
view->addUserMessage<AudioItem, mtx::events::MessageType::Audio>(url, nullptr, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -89,14 +89,16 @@ AudioItem::AudioItem(QSharedPointer<MatrixClient> client,
|
||||||
|
|
||||||
AudioItem::AudioItem(QSharedPointer<MatrixClient> client,
|
AudioItem::AudioItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, url_{url}
|
, url_{url}
|
||||||
, text_{QFileInfo(filename).fileName()}
|
, text_{QFileInfo{filename}.fileName()}
|
||||||
, client_{client}
|
, client_{client}
|
||||||
{
|
{
|
||||||
readableFileSize_ = calculateFileSize(QFileInfo(filename).size());
|
Q_UNUSED(data);
|
||||||
|
readableFileSize_ = calculateFileSize(QFileInfo{filename}.size());
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,14 +76,16 @@ FileItem::FileItem(QSharedPointer<MatrixClient> client,
|
||||||
|
|
||||||
FileItem::FileItem(QSharedPointer<MatrixClient> client,
|
FileItem::FileItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, url_{url}
|
, url_{url}
|
||||||
, text_{QFileInfo(filename).fileName()}
|
, text_{QFileInfo{filename}.fileName()}
|
||||||
, client_{client}
|
, client_{client}
|
||||||
{
|
{
|
||||||
readableFileSize_ = calculateFileSize(QFileInfo(filename).size());
|
Q_UNUSED(data);
|
||||||
|
readableFileSize_ = calculateFileSize(QFileInfo{filename}.size());
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,11 +61,12 @@ ImageItem::ImageItem(QSharedPointer<MatrixClient> client,
|
||||||
|
|
||||||
ImageItem::ImageItem(QSharedPointer<MatrixClient> client,
|
ImageItem::ImageItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, url_{url}
|
, url_{url}
|
||||||
, text_{QFileInfo(filename).fileName()}
|
, text_{filename}
|
||||||
, client_{client}
|
, client_{client}
|
||||||
{
|
{
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
@ -83,7 +84,19 @@ ImageItem::ImageItem(QSharedPointer<MatrixClient> client,
|
||||||
url_ = QString("%1/_matrix/media/r0/download/%2")
|
url_ = QString("%1/_matrix/media/r0/download/%2")
|
||||||
.arg(client_.data()->getHomeServer().toString(), media_params);
|
.arg(client_.data()->getHomeServer().toString(), media_params);
|
||||||
|
|
||||||
setImage(QPixmap(filename));
|
if (data.isNull()) {
|
||||||
|
qWarning() << "No image data to display";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->reset()) {
|
||||||
|
QPixmap p;
|
||||||
|
p.loadFromData(data->readAll());
|
||||||
|
setImage(p);
|
||||||
|
} else {
|
||||||
|
qWarning() << "Failed to seek to beginning of device:" << data->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -66,6 +66,7 @@ VideoItem::VideoItem(QSharedPointer<MatrixClient> client,
|
||||||
|
|
||||||
VideoItem::VideoItem(QSharedPointer<MatrixClient> client,
|
VideoItem::VideoItem(QSharedPointer<MatrixClient> client,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
const QSharedPointer<QIODevice> data,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
@ -73,6 +74,7 @@ VideoItem::VideoItem(QSharedPointer<MatrixClient> client,
|
||||||
, text_{QFileInfo(filename).fileName()}
|
, text_{QFileInfo(filename).fileName()}
|
||||||
, client_{client}
|
, client_{client}
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(data);
|
||||||
readableFileSize_ = calculateFileSize(QFileInfo(filename).size());
|
readableFileSize_ = calculateFileSize(QFileInfo(filename).size());
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
Loading…
Reference in a new issue