mirror of https://github.com/Nheko-Reborn/nheko
commit
15ff5dace5
After Width: | Height: | Size: 704 B |
After Width: | Height: | Size: 458 B |
After Width: | Height: | Size: 645 B |
After Width: | Height: | Size: 931 B |
@ -0,0 +1,89 @@ |
|||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors |
||||||
|
// |
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later |
||||||
|
|
||||||
|
import "./components" |
||||||
|
import "./ui" |
||||||
|
|
||||||
|
import QtQuick 2.9 |
||||||
|
import QtQuick.Controls 2.5 |
||||||
|
import QtQuick.Layouts 1.3 |
||||||
|
import im.nheko 1.0 |
||||||
|
|
||||||
|
Page { |
||||||
|
id: uploadPopup |
||||||
|
visible: room && room.input.uploads.length > 0 |
||||||
|
Layout.preferredHeight: 200 |
||||||
|
clip: true |
||||||
|
|
||||||
|
Layout.fillWidth: true |
||||||
|
|
||||||
|
padding: Nheko.paddingMedium |
||||||
|
|
||||||
|
contentItem: ListView { |
||||||
|
id: uploadsList |
||||||
|
anchors.horizontalCenter: parent.horizontalCenter |
||||||
|
boundsBehavior: Flickable.StopAtBounds |
||||||
|
|
||||||
|
ScrollBar.horizontal: ScrollBar { |
||||||
|
id: scr |
||||||
|
} |
||||||
|
|
||||||
|
orientation: ListView.Horizontal |
||||||
|
width: Math.min(contentWidth, parent.availableWidth) |
||||||
|
model: room ? room.input.uploads : undefined |
||||||
|
spacing: Nheko.paddingMedium |
||||||
|
|
||||||
|
delegate: Pane { |
||||||
|
padding: Nheko.paddingSmall |
||||||
|
height: uploadPopup.availableHeight - buttons.height - (scr.visible? scr.height : 0) |
||||||
|
width: uploadPopup.availableHeight - buttons.height |
||||||
|
|
||||||
|
background: Rectangle { |
||||||
|
color: Nheko.colors.window |
||||||
|
radius: Nheko.paddingMedium |
||||||
|
} |
||||||
|
contentItem: ColumnLayout { |
||||||
|
Image { |
||||||
|
Layout.fillHeight: true |
||||||
|
Layout.fillWidth: true |
||||||
|
|
||||||
|
sourceSize.height: height |
||||||
|
sourceSize.width: width |
||||||
|
fillMode: Image.PreserveAspectFit |
||||||
|
smooth: true |
||||||
|
mipmap: true |
||||||
|
|
||||||
|
property string typeStr: switch(modelData.mediaType) { |
||||||
|
case MediaUpload.Video: return "video-file"; |
||||||
|
case MediaUpload.Audio: return "music"; |
||||||
|
case MediaUpload.Image: return "image"; |
||||||
|
default: return "zip"; |
||||||
|
} |
||||||
|
source: (modelData.thumbnail != "") ? modelData.thumbnail : ("image://colorimage/:/icons/icons/ui/"+typeStr+".svg?" + Nheko.colors.buttonText) |
||||||
|
} |
||||||
|
MatrixTextField { |
||||||
|
Layout.fillWidth: true |
||||||
|
text: modelData.filename |
||||||
|
onTextEdited: modelData.filename = text |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
footer: DialogButtonBox { |
||||||
|
id: buttons |
||||||
|
|
||||||
|
standardButtons: DialogButtonBox.Cancel |
||||||
|
Button { |
||||||
|
text: qsTr("Upload %n file(s)", "", (room ? room.input.uploads.length : 0)) |
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole |
||||||
|
} |
||||||
|
onAccepted: room.input.acceptUploads() |
||||||
|
onRejected: room.input.declineUploads() |
||||||
|
} |
||||||
|
|
||||||
|
background: Rectangle { |
||||||
|
color: Nheko.colors.base |
||||||
|
} |
||||||
|
} |
@ -1,223 +0,0 @@ |
|||||||
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
|
|
||||||
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
|
||||||
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#include <QBuffer> |
|
||||||
#include <QFile> |
|
||||||
#include <QFileInfo> |
|
||||||
#include <QHBoxLayout> |
|
||||||
#include <QMimeDatabase> |
|
||||||
#include <QVBoxLayout> |
|
||||||
|
|
||||||
#include "dialogs/PreviewUploadOverlay.h" |
|
||||||
|
|
||||||
#include "Config.h" |
|
||||||
#include "Logging.h" |
|
||||||
#include "MainWindow.h" |
|
||||||
#include "Utils.h" |
|
||||||
|
|
||||||
using namespace dialogs; |
|
||||||
|
|
||||||
constexpr const char *DEFAULT = "Upload %1?"; |
|
||||||
constexpr const char *ERR_MSG = "Failed to load image type '%1'. Continue upload?"; |
|
||||||
|
|
||||||
PreviewUploadOverlay::PreviewUploadOverlay(QWidget *parent) |
|
||||||
: QWidget{parent} |
|
||||||
, titleLabel_{this} |
|
||||||
, fileName_{this} |
|
||||||
, upload_{tr("Upload"), this} |
|
||||||
, cancel_{tr("Cancel"), this} |
|
||||||
{ |
|
||||||
auto hlayout = new QHBoxLayout; |
|
||||||
hlayout->setContentsMargins(0, 0, 0, 0); |
|
||||||
hlayout->addStretch(1); |
|
||||||
hlayout->addWidget(&cancel_); |
|
||||||
hlayout->addWidget(&upload_); |
|
||||||
|
|
||||||
auto vlayout = new QVBoxLayout{this}; |
|
||||||
vlayout->addWidget(&titleLabel_); |
|
||||||
vlayout->addWidget(&infoLabel_); |
|
||||||
vlayout->addWidget(&fileName_); |
|
||||||
vlayout->addLayout(hlayout); |
|
||||||
vlayout->setSpacing(conf::modals::WIDGET_SPACING); |
|
||||||
vlayout->setContentsMargins(conf::modals::WIDGET_MARGIN, |
|
||||||
conf::modals::WIDGET_MARGIN, |
|
||||||
conf::modals::WIDGET_MARGIN, |
|
||||||
conf::modals::WIDGET_MARGIN); |
|
||||||
|
|
||||||
upload_.setDefault(true); |
|
||||||
connect(&upload_, &QPushButton::clicked, this, [this]() { |
|
||||||
emit confirmUpload(data_, mediaType_, fileName_.text()); |
|
||||||
close(); |
|
||||||
}); |
|
||||||
|
|
||||||
connect(&fileName_, &QLineEdit::returnPressed, this, [this]() { |
|
||||||
emit confirmUpload(data_, mediaType_, fileName_.text()); |
|
||||||
close(); |
|
||||||
}); |
|
||||||
|
|
||||||
connect(&cancel_, &QPushButton::clicked, this, [this]() { |
|
||||||
emit aborted(); |
|
||||||
close(); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
PreviewUploadOverlay::init() |
|
||||||
{ |
|
||||||
QSize winsize; |
|
||||||
QPoint center; |
|
||||||
|
|
||||||
auto window = MainWindow::instance(); |
|
||||||
if (window) { |
|
||||||
winsize = window->frameGeometry().size(); |
|
||||||
center = window->frameGeometry().center(); |
|
||||||
} else { |
|
||||||
nhlog::ui()->warn("unable to retrieve MainWindow's size"); |
|
||||||
} |
|
||||||
|
|
||||||
fileName_.setText(QFileInfo{filePath_}.fileName()); |
|
||||||
|
|
||||||
setAutoFillBackground(true); |
|
||||||
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); |
|
||||||
setWindowModality(Qt::WindowModal); |
|
||||||
|
|
||||||
QFont font; |
|
||||||
font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO); |
|
||||||
|
|
||||||
titleLabel_.setFont(font); |
|
||||||
titleLabel_.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
||||||
titleLabel_.setAlignment(Qt::AlignCenter); |
|
||||||
infoLabel_.setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); |
|
||||||
fileName_.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); |
|
||||||
fileName_.setAlignment(Qt::AlignCenter); |
|
||||||
upload_.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); |
|
||||||
cancel_.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); |
|
||||||
|
|
||||||
if (isImage_) { |
|
||||||
infoLabel_.setAlignment(Qt::AlignCenter); |
|
||||||
|
|
||||||
const auto maxWidth = winsize.width() * 0.8; |
|
||||||
const auto maxHeight = winsize.height() * 0.8; |
|
||||||
|
|
||||||
// Scale image preview to fit into the application window.
|
|
||||||
infoLabel_.setPixmap(utils::scaleDown(maxWidth, maxHeight, image_)); |
|
||||||
move(center.x() - (width() * 0.5), center.y() - (height() * 0.5)); |
|
||||||
} else { |
|
||||||
infoLabel_.setAlignment(Qt::AlignLeft); |
|
||||||
} |
|
||||||
infoLabel_.setScaledContents(false); |
|
||||||
|
|
||||||
show(); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
PreviewUploadOverlay::setLabels(const QString &type, const QString &mime, uint64_t upload_size) |
|
||||||
{ |
|
||||||
if (mediaType_.split('/')[0] == QLatin1String("image")) { |
|
||||||
if (!image_.loadFromData(data_)) { |
|
||||||
titleLabel_.setText(QString{tr(ERR_MSG)}.arg(type)); |
|
||||||
} else { |
|
||||||
titleLabel_.setText(QString{tr(DEFAULT)}.arg(mediaType_)); |
|
||||||
} |
|
||||||
isImage_ = true; |
|
||||||
} else { |
|
||||||
auto const info = QString{tr("Media type: %1\n" |
|
||||||
"Media size: %2\n")} |
|
||||||
.arg(mime, utils::humanReadableFileSize(upload_size)); |
|
||||||
|
|
||||||
titleLabel_.setText(QString{tr(DEFAULT)}.arg(QStringLiteral("file"))); |
|
||||||
infoLabel_.setText(info); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
PreviewUploadOverlay::setPreview(const QImage &src, const QString &mime) |
|
||||||
{ |
|
||||||
nhlog::ui()->info( |
|
||||||
"Pasting image with size: {}x{}, format: {}", src.height(), src.width(), mime.toStdString()); |
|
||||||
|
|
||||||
auto const &split = mime.split('/'); |
|
||||||
auto const &type = split[1]; |
|
||||||
|
|
||||||
QBuffer buffer(&data_); |
|
||||||
buffer.open(QIODevice::WriteOnly); |
|
||||||
if (src.save(&buffer, type.toStdString().c_str())) |
|
||||||
titleLabel_.setText(QString{tr(DEFAULT)}.arg(QStringLiteral("image"))); |
|
||||||
else |
|
||||||
titleLabel_.setText(QString{tr(ERR_MSG)}.arg(type)); |
|
||||||
|
|
||||||
mediaType_ = mime; |
|
||||||
filePath_ = "clipboard." + type; |
|
||||||
image_.convertFromImage(src); |
|
||||||
isImage_ = true; |
|
||||||
|
|
||||||
titleLabel_.setText(QString{tr(DEFAULT)}.arg(QStringLiteral("image"))); |
|
||||||
init(); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
PreviewUploadOverlay::setPreview(const QByteArray data, const QString &mime) |
|
||||||
{ |
|
||||||
nhlog::ui()->info("Pasting {} bytes of data, mimetype {}", data.size(), mime.toStdString()); |
|
||||||
|
|
||||||
auto const &split = mime.split('/'); |
|
||||||
auto const &type = split[1]; |
|
||||||
|
|
||||||
data_ = data; |
|
||||||
mediaType_ = mime; |
|
||||||
filePath_ = "clipboard." + type; |
|
||||||
isImage_ = false; |
|
||||||
|
|
||||||
if (mime == QLatin1String("image/svg+xml")) { |
|
||||||
isImage_ = true; |
|
||||||
image_.loadFromData(data_, mediaType_.toStdString().c_str()); |
|
||||||
} |
|
||||||
|
|
||||||
setLabels(type, mime, data_.size()); |
|
||||||
init(); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
PreviewUploadOverlay::setPreview(const QString &path) |
|
||||||
{ |
|
||||||
QFile file{path}; |
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadOnly)) { |
|
||||||
nhlog::ui()->warn( |
|
||||||
"Failed to open file ({}): {}", path.toStdString(), file.errorString().toStdString()); |
|
||||||
close(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
QMimeDatabase db; |
|
||||||
auto mime = db.mimeTypeForFileNameAndData(path, &file); |
|
||||||
|
|
||||||
if ((data_ = file.readAll()).isEmpty()) { |
|
||||||
nhlog::ui()->warn("Failed to read media: {}", file.errorString().toStdString()); |
|
||||||
close(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
auto const &split = mime.name().split('/'); |
|
||||||
|
|
||||||
mediaType_ = mime.name(); |
|
||||||
filePath_ = file.fileName(); |
|
||||||
isImage_ = false; |
|
||||||
|
|
||||||
setLabels(split[1], mime.name(), data_.size()); |
|
||||||
init(); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
PreviewUploadOverlay::keyPressEvent(QKeyEvent *event) |
|
||||||
{ |
|
||||||
if (event->matches(QKeySequence::Cancel)) { |
|
||||||
emit aborted(); |
|
||||||
close(); |
|
||||||
} else { |
|
||||||
QWidget::keyPressEvent(event); |
|
||||||
} |
|
||||||
} |
|
@ -1,53 +0,0 @@ |
|||||||
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
|
|
||||||
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
|
||||||
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <QImage> |
|
||||||
#include <QLabel> |
|
||||||
#include <QLineEdit> |
|
||||||
#include <QPixmap> |
|
||||||
#include <QPushButton> |
|
||||||
#include <QWidget> |
|
||||||
|
|
||||||
class QMimeData; |
|
||||||
|
|
||||||
namespace dialogs { |
|
||||||
|
|
||||||
class PreviewUploadOverlay : public QWidget |
|
||||||
{ |
|
||||||
Q_OBJECT |
|
||||||
public: |
|
||||||
PreviewUploadOverlay(QWidget *parent = nullptr); |
|
||||||
|
|
||||||
void setPreview(const QImage &src, const QString &mime); |
|
||||||
void setPreview(const QByteArray data, const QString &mime); |
|
||||||
void setPreview(const QString &path); |
|
||||||
void keyPressEvent(QKeyEvent *event); |
|
||||||
|
|
||||||
signals: |
|
||||||
void confirmUpload(const QByteArray data, const QString &media, const QString &filename); |
|
||||||
void aborted(); |
|
||||||
|
|
||||||
private: |
|
||||||
void init(); |
|
||||||
void setLabels(const QString &type, const QString &mime, uint64_t upload_size); |
|
||||||
|
|
||||||
bool isImage_; |
|
||||||
QPixmap image_; |
|
||||||
|
|
||||||
QByteArray data_; |
|
||||||
QString filePath_; |
|
||||||
QString mediaType_; |
|
||||||
|
|
||||||
QLabel titleLabel_; |
|
||||||
QLabel infoLabel_; |
|
||||||
QLineEdit fileName_; |
|
||||||
|
|
||||||
QPushButton upload_; |
|
||||||
QPushButton cancel_; |
|
||||||
}; |
|
||||||
} // dialogs
|
|
Loading…
Reference in new issue