From a57a15a2e07da8cc07bc12e828b7c636efe36cbc Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 6 Aug 2021 01:45:47 +0200 Subject: Basic sticker pack editor --- src/SingleImagePackModel.h | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'src/SingleImagePackModel.h') diff --git a/src/SingleImagePackModel.h b/src/SingleImagePackModel.h index e0c791ba..44f413c6 100644 --- a/src/SingleImagePackModel.h +++ b/src/SingleImagePackModel.h @@ -15,14 +15,18 @@ class SingleImagePackModel : public QAbstractListModel Q_OBJECT Q_PROPERTY(QString roomid READ roomid CONSTANT) - Q_PROPERTY(QString statekey READ statekey CONSTANT) - Q_PROPERTY(QString attribution READ statekey CONSTANT) - Q_PROPERTY(QString packname READ packname CONSTANT) - Q_PROPERTY(QString avatarUrl READ avatarUrl CONSTANT) - Q_PROPERTY(bool isStickerPack READ isStickerPack CONSTANT) - Q_PROPERTY(bool isEmotePack READ isEmotePack CONSTANT) + Q_PROPERTY(QString statekey READ statekey WRITE setStatekey NOTIFY statekeyChanged) + Q_PROPERTY( + QString attribution READ attribution WRITE setAttribution NOTIFY attributionChanged) + Q_PROPERTY(QString packname READ packname WRITE setPackname NOTIFY packnameChanged) + Q_PROPERTY(QString avatarUrl READ avatarUrl WRITE setAvatarUrl NOTIFY avatarUrlChanged) + Q_PROPERTY( + bool isStickerPack READ isStickerPack WRITE setIsStickerPack NOTIFY isStickerPackChanged) + Q_PROPERTY(bool isEmotePack READ isEmotePack WRITE setIsEmotePack NOTIFY isEmotePackChanged) Q_PROPERTY(bool isGloballyEnabled READ isGloballyEnabled WRITE setGloballyEnabled NOTIFY globallyEnabledChanged) + Q_PROPERTY(bool canEdit READ canEdit CONSTANT) + public: enum Roles { @@ -32,11 +36,15 @@ public: IsEmote, IsSticker, }; + Q_ENUM(Roles); SingleImagePackModel(ImagePackInfo pack_, QObject *parent = nullptr); QHash roleNames() const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, + const QVariant &value, + int role = Qt::EditRole) override; QString roomid() const { return QString::fromStdString(roomid_); } QString statekey() const { return QString::fromStdString(statekey_); } @@ -47,14 +55,30 @@ public: bool isEmotePack() const { return pack.pack->is_emoji(); } bool isGloballyEnabled() const; + bool canEdit() const; void setGloballyEnabled(bool enabled); + void setPackname(QString val); + void setAttribution(QString val); + void setAvatarUrl(QString val); + void setStatekey(QString val); + void setIsStickerPack(bool val); + void setIsEmotePack(bool val); + + Q_INVOKABLE void save(); + signals: void globallyEnabledChanged(); + void statekeyChanged(); + void attributionChanged(); + void packnameChanged(); + void avatarUrlChanged(); + void isEmotePackChanged(); + void isStickerPackChanged(); private: std::string roomid_; - std::string statekey_; + std::string statekey_, old_statekey_; mtx::events::msc2545::ImagePack pack; std::vector shortcodes; -- cgit 1.5.1 From 16d0190f4e1ee79025ec47f3dcfa1fb701a63ff1 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 6 Aug 2021 03:28:56 +0200 Subject: Allow uploading additional stickers --- resources/qml/ScrollHelper.qml | 7 ++- resources/qml/dialogs/ImagePackEditorDialog.qml | 18 +++++++ src/SingleImagePackModel.cpp | 69 ++++++++++++++++++++++++- src/SingleImagePackModel.h | 8 +++ 4 files changed, 97 insertions(+), 5 deletions(-) (limited to 'src/SingleImagePackModel.h') diff --git a/resources/qml/ScrollHelper.qml b/resources/qml/ScrollHelper.qml index e584ae3d..e84e67fd 100644 --- a/resources/qml/ScrollHelper.qml +++ b/resources/qml/ScrollHelper.qml @@ -23,6 +23,9 @@ MouseArea { // console.warn("Delta: ", wheel.pixelDelta.y); // console.warn("Old position: ", flickable.contentY); // console.warn("New position: ", newPos); + // breaks ListView's with headers... + //if (typeof (flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) + // minYExtent += flickableItem.headerItem.height; id: root @@ -30,10 +33,6 @@ MouseArea { property alias enabled: root.enabled function calculateNewPosition(flickableItem, wheel) { - // breaks ListView's with headers... - //if (typeof (flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) - // minYExtent += flickableItem.headerItem.height; - //Nothing to scroll if (flickableItem.contentHeight < flickableItem.height) return flickableItem.contentY; diff --git a/resources/qml/dialogs/ImagePackEditorDialog.qml b/resources/qml/dialogs/ImagePackEditorDialog.qml index 0049d3b4..89301215 100644 --- a/resources/qml/dialogs/ImagePackEditorDialog.qml +++ b/resources/qml/dialogs/ImagePackEditorDialog.qml @@ -4,6 +4,7 @@ import ".." import "../components" +import Qt.labs.platform 1.1 import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 @@ -78,6 +79,23 @@ ApplicationWindow { } + footer: Button { + palette: Nheko.colors + onClicked: addFilesDialog.open() + width: ListView.view.width + text: qsTr("Add images") + + FileDialog { + id: addFilesDialog + + folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation) + fileMode: FileDialog.OpenFiles + nameFilters: [qsTr("Stickers (*.png *.webp)")] + onAccepted: imagePack.addStickers(files) + } + + } + delegate: AvatarListTile { id: packItem diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp index d3cc8014..ddecf1ad 100644 --- a/src/SingleImagePackModel.cpp +++ b/src/SingleImagePackModel.cpp @@ -4,13 +4,18 @@ #include "SingleImagePackModel.h" +#include +#include + #include "Cache_p.h" #include "ChatPage.h" +#include "Logging.h" #include "MatrixClient.h" +#include "Utils.h" #include "timeline/Permissions.h" #include "timeline/TimelineModel.h" -#include "Logging.h" +Q_DECLARE_METATYPE(mtx::common::ImageInfo); SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent) : QAbstractListModel(parent) @@ -19,11 +24,15 @@ SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent) , old_statekey_(statekey_) , pack(std::move(pack_.pack)) { + [[maybe_unused]] static auto imageInfoType = qRegisterMetaType(); + if (!pack.pack) pack.pack = mtx::events::msc2545::ImagePack::PackDescription{}; for (const auto &e : pack.images) shortcodes.push_back(e.first); + + connect(this, &SingleImagePackModel::addImage, this, &SingleImagePackModel::addImageCb); } int @@ -279,3 +288,61 @@ SingleImagePackModel::save() }); } } + +void +SingleImagePackModel::addStickers(QList files) +{ + for (const auto &f : files) { + auto file = QFile(f.toLocalFile()); + if (!file.open(QFile::ReadOnly)) { + ChatPage::instance()->showNotification( + tr("Failed to open image: {}").arg(f.toLocalFile())); + return; + } + + auto bytes = file.readAll(); + auto img = utils::readImage(bytes); + + mtx::common::ImageInfo info{}; + + auto sz = img.size() / 2; + if (sz.width() > 512 || sz.height() > 512) { + sz.scale(512, 512, Qt::AspectRatioMode::KeepAspectRatio); + } + + info.h = sz.height(); + info.w = sz.width(); + info.size = bytes.size(); + + auto filename = f.fileName().toStdString(); + http::client()->upload( + bytes.toStdString(), + QMimeDatabase().mimeTypeForFile(f.toLocalFile()).name().toStdString(), + filename, + [this, filename, info](const mtx::responses::ContentURI &uri, + mtx::http::RequestErr e) { + if (e) { + ChatPage::instance()->showNotification( + tr("Failed to upload image: {}") + .arg(QString::fromStdString(e->matrix_error.error))); + return; + } + + emit addImage(uri.content_uri, filename, info); + }); + } +} +void +SingleImagePackModel::addImageCb(std::string uri, std::string filename, mtx::common::ImageInfo info) +{ + mtx::events::msc2545::PackImage img{}; + img.url = uri; + img.info = info; + beginInsertRows( + QModelIndex(), static_cast(shortcodes.size()), static_cast(shortcodes.size())); + + pack.images[filename] = img; + shortcodes.push_back(filename); + + endInsertRows(); +} diff --git a/src/SingleImagePackModel.h b/src/SingleImagePackModel.h index 44f413c6..cd38b3b6 100644 --- a/src/SingleImagePackModel.h +++ b/src/SingleImagePackModel.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include #include @@ -66,6 +68,7 @@ public: void setIsEmotePack(bool val); Q_INVOKABLE void save(); + Q_INVOKABLE void addStickers(QList files); signals: void globallyEnabledChanged(); @@ -76,6 +79,11 @@ signals: void isEmotePackChanged(); void isStickerPackChanged(); + void addImage(std::string uri, std::string filename, mtx::common::ImageInfo info); + +private slots: + void addImageCb(std::string uri, std::string filename, mtx::common::ImageInfo info); + private: std::string roomid_; std::string statekey_, old_statekey_; -- cgit 1.5.1