summary refs log tree commit diff
path: root/src/timeline/widgets
diff options
context:
space:
mode:
authorJoseph Donofry <joedonofry@gmail.com>2019-12-07 21:39:47 -0500
committerJoseph Donofry <joedonofry@gmail.com>2019-12-07 21:39:47 -0500
commite79ae4ea0996f175ea607e22627a447a4de2a1dc (patch)
treea49d9a6936c22619d619f02e5a654c80f283f5c1 /src/timeline/widgets
parentMerge branch '0.7.0-dev' of ssh://github.com/Nheko-Reborn/nheko into 0.7.0-dev (diff)
parentSimplify scroll logic (diff)
downloadnheko-e79ae4ea0996f175ea607e22627a447a4de2a1dc.tar.xz
Merge branch '0.7.0-dev' of ssh://github.com/Nheko-Reborn/nheko into 0.7.0-dev
Diffstat (limited to 'src/timeline/widgets')
-rw-r--r--src/timeline/widgets/AudioItem.cpp236
-rw-r--r--src/timeline/widgets/AudioItem.h104
-rw-r--r--src/timeline/widgets/FileItem.cpp221
-rw-r--r--src/timeline/widgets/FileItem.h79
-rw-r--r--src/timeline/widgets/ImageItem.cpp267
-rw-r--r--src/timeline/widgets/ImageItem.h104
-rw-r--r--src/timeline/widgets/VideoItem.cpp65
-rw-r--r--src/timeline/widgets/VideoItem.h51
8 files changed, 0 insertions, 1127 deletions
diff --git a/src/timeline/widgets/AudioItem.cpp b/src/timeline/widgets/AudioItem.cpp
deleted file mode 100644

index 5d6431ee..00000000 --- a/src/timeline/widgets/AudioItem.cpp +++ /dev/null
@@ -1,236 +0,0 @@ -/* - * 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 <QBrush> -#include <QDesktopServices> -#include <QFile> -#include <QFileDialog> -#include <QPainter> -#include <QPixmap> -#include <QtGlobal> - -#include "Logging.h" -#include "MatrixClient.h" -#include "Utils.h" - -#include "timeline/widgets/AudioItem.h" - -constexpr int MaxWidth = 400; -constexpr int Height = 70; -constexpr int IconRadius = 22; -constexpr int IconDiameter = IconRadius * 2; -constexpr int HorizontalPadding = 12; -constexpr int TextPadding = 15; -constexpr int ActionIconRadius = IconRadius - 4; - -constexpr double VerticalPadding = Height - 2 * IconRadius; -constexpr double IconYCenter = Height / 2; -constexpr double IconXCenter = HorizontalPadding + IconRadius; - -void -AudioItem::init() -{ - setMouseTracking(true); - setCursor(Qt::PointingHandCursor); - setAttribute(Qt::WA_Hover, true); - - playIcon_.addFile(":/icons/icons/ui/play-sign.png"); - pauseIcon_.addFile(":/icons/icons/ui/pause-symbol.png"); - - player_ = new QMediaPlayer; - player_->setMedia(QUrl(url_)); - player_->setVolume(100); - player_->setNotifyInterval(1000); - - connect(player_, &QMediaPlayer::stateChanged, this, [this](QMediaPlayer::State state) { - if (state == QMediaPlayer::StoppedState) { - state_ = AudioState::Play; - player_->setMedia(QUrl(url_)); - update(); - } - }); - - setFixedHeight(Height); -} - -AudioItem::AudioItem(const mtx::events::RoomEvent<mtx::events::msg::Audio> &event, QWidget *parent) - : QWidget(parent) - , url_{QUrl(QString::fromStdString(event.content.url))} - , text_{QString::fromStdString(event.content.body)} - , event_{event} -{ - readableFileSize_ = utils::humanReadableFileSize(event.content.info.size); - - init(); -} - -AudioItem::AudioItem(const QString &url, const QString &filename, uint64_t size, QWidget *parent) - : QWidget(parent) - , url_{url} - , text_{filename} -{ - readableFileSize_ = utils::humanReadableFileSize(size); - - init(); -} - -QSize -AudioItem::sizeHint() const -{ - return QSize(MaxWidth, Height); -} - -void -AudioItem::mousePressEvent(QMouseEvent *event) -{ - if (event->button() != Qt::LeftButton) - return; - - auto point = event->pos(); - - // Click on the download icon. - if (QRect(HorizontalPadding, VerticalPadding / 2, IconDiameter, IconDiameter) - .contains(point)) { - if (state_ == AudioState::Play) { - state_ = AudioState::Pause; - player_->play(); - } else { - state_ = AudioState::Play; - player_->pause(); - } - - update(); - } else { - filenameToSave_ = QFileDialog::getSaveFileName(this, tr("Save File"), text_); - - if (filenameToSave_.isEmpty()) - return; - - auto proxy = std::make_shared<MediaProxy>(); - connect(proxy.get(), &MediaProxy::fileDownloaded, this, &AudioItem::fileDownloaded); - - http::client()->download( - url_.toString().toStdString(), - [proxy = std::move(proxy), url = url_](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->info("failed to retrieve m.audio content: {}", - url.toString().toStdString()); - return; - } - - emit proxy->fileDownloaded(QByteArray(data.data(), data.size())); - }); - } -} - -void -AudioItem::fileDownloaded(const QByteArray &data) -{ - try { - QFile file(filenameToSave_); - - if (!file.open(QIODevice::WriteOnly)) - return; - - file.write(data); - file.close(); - } catch (const std::exception &e) { - nhlog::ui()->warn("error while saving file: {}", e.what()); - } -} - -void -AudioItem::resizeEvent(QResizeEvent *event) -{ - QFont font; - font.setWeight(QFont::Medium); - - QFontMetrics fm(font); -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - const int computedWidth = std::min( - fm.width(text_) + 2 * IconRadius + VerticalPadding * 2 + TextPadding, (double)MaxWidth); -#else - const int computedWidth = - std::min(fm.horizontalAdvance(text_) + 2 * IconRadius + VerticalPadding * 2 + TextPadding, - (double)MaxWidth); -#endif - resize(computedWidth, Height); - - event->accept(); -} - -void -AudioItem::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - - QFont font; - font.setWeight(QFont::Medium); - - QFontMetrics fm(font); - - QPainterPath path; - path.addRoundedRect(QRectF(0, 0, width(), height()), 10, 10); - - painter.setPen(Qt::NoPen); - painter.fillPath(path, backgroundColor_); - painter.drawPath(path); - - QPainterPath circle; - circle.addEllipse(QPoint(IconXCenter, IconYCenter), IconRadius, IconRadius); - - painter.setPen(Qt::NoPen); - painter.fillPath(circle, iconColor_); - painter.drawPath(circle); - - QIcon icon_; - if (state_ == AudioState::Play) - icon_ = playIcon_; - else - icon_ = pauseIcon_; - - icon_.paint(&painter, - QRect(IconXCenter - ActionIconRadius / 2, - IconYCenter - ActionIconRadius / 2, - ActionIconRadius, - ActionIconRadius), - Qt::AlignCenter, - QIcon::Normal); - - const int textStartX = HorizontalPadding + 2 * IconRadius + TextPadding; - const int textStartY = VerticalPadding + fm.ascent() / 2; - - // Draw the filename. - QString elidedText = fm.elidedText( - text_, Qt::ElideRight, width() - HorizontalPadding * 2 - TextPadding - 2 * IconRadius); - - painter.setFont(font); - painter.setPen(QPen(textColor_)); - painter.drawText(QPoint(textStartX, textStartY), elidedText); - - // Draw the filesize. - font.setWeight(QFont::Normal); - painter.setFont(font); - painter.setPen(QPen(textColor_)); - painter.drawText(QPoint(textStartX, textStartY + 1.5 * fm.ascent()), readableFileSize_); -} diff --git a/src/timeline/widgets/AudioItem.h b/src/timeline/widgets/AudioItem.h deleted file mode 100644
index c32b7731..00000000 --- a/src/timeline/widgets/AudioItem.h +++ /dev/null
@@ -1,104 +0,0 @@ -/* - * 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 <QEvent> -#include <QIcon> -#include <QMediaPlayer> -#include <QMouseEvent> -#include <QSharedPointer> -#include <QWidget> - -#include <mtx.hpp> - -class AudioItem : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) - Q_PROPERTY(QColor iconColor WRITE setIconColor READ iconColor) - Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) - - Q_PROPERTY(QColor durationBackgroundColor WRITE setDurationBackgroundColor READ - durationBackgroundColor) - Q_PROPERTY(QColor durationForegroundColor WRITE setDurationForegroundColor READ - durationForegroundColor) - -public: - AudioItem(const mtx::events::RoomEvent<mtx::events::msg::Audio> &event, - QWidget *parent = nullptr); - - AudioItem(const QString &url, - const QString &filename, - uint64_t size, - QWidget *parent = nullptr); - - QSize sizeHint() const override; - - void setTextColor(const QColor &color) { textColor_ = color; } - void setIconColor(const QColor &color) { iconColor_ = color; } - void setBackgroundColor(const QColor &color) { backgroundColor_ = color; } - - void setDurationBackgroundColor(const QColor &color) { durationBgColor_ = color; } - void setDurationForegroundColor(const QColor &color) { durationFgColor_ = color; } - - QColor textColor() const { return textColor_; } - QColor iconColor() const { return iconColor_; } - QColor backgroundColor() const { return backgroundColor_; } - - QColor durationBackgroundColor() const { return durationBgColor_; } - QColor durationForegroundColor() const { return durationFgColor_; } - -protected: - void paintEvent(QPaintEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - -private slots: - void fileDownloaded(const QByteArray &data); - -private: - void init(); - - enum class AudioState - { - Play, - Pause, - }; - - AudioState state_ = AudioState::Play; - - QUrl url_; - QString text_; - QString readableFileSize_; - QString filenameToSave_; - - mtx::events::RoomEvent<mtx::events::msg::Audio> event_; - - QMediaPlayer *player_; - - QIcon playIcon_; - QIcon pauseIcon_; - - QColor textColor_ = QColor("white"); - QColor iconColor_ = QColor("#38A3D8"); - QColor backgroundColor_ = QColor("#333"); - - QColor durationBgColor_ = QColor("black"); - QColor durationFgColor_ = QColor("blue"); -}; diff --git a/src/timeline/widgets/FileItem.cpp b/src/timeline/widgets/FileItem.cpp deleted file mode 100644
index 1a555d1c..00000000 --- a/src/timeline/widgets/FileItem.cpp +++ /dev/null
@@ -1,221 +0,0 @@ -/* - * 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 <QBrush> -#include <QDesktopServices> -#include <QFile> -#include <QFileDialog> -#include <QPainter> -#include <QPixmap> -#include <QtGlobal> - -#include "Logging.h" -#include "MatrixClient.h" -#include "Utils.h" - -#include "timeline/widgets/FileItem.h" - -constexpr int MaxWidth = 400; -constexpr int Height = 70; -constexpr int IconRadius = 22; -constexpr int IconDiameter = IconRadius * 2; -constexpr int HorizontalPadding = 12; -constexpr int TextPadding = 15; -constexpr int DownloadIconRadius = IconRadius - 4; - -constexpr double VerticalPadding = Height - 2 * IconRadius; -constexpr double IconYCenter = Height / 2; -constexpr double IconXCenter = HorizontalPadding + IconRadius; - -void -FileItem::init() -{ - setMouseTracking(true); - setCursor(Qt::PointingHandCursor); - setAttribute(Qt::WA_Hover, true); - - icon_.addFile(":/icons/icons/ui/arrow-pointing-down.png"); - - setFixedHeight(Height); -} - -FileItem::FileItem(const mtx::events::RoomEvent<mtx::events::msg::File> &event, QWidget *parent) - : QWidget(parent) - , url_{QString::fromStdString(event.content.url)} - , text_{QString::fromStdString(event.content.body)} - , event_{event} -{ - readableFileSize_ = utils::humanReadableFileSize(event.content.info.size); - - init(); -} - -FileItem::FileItem(const QString &url, const QString &filename, uint64_t size, QWidget *parent) - : QWidget(parent) - , url_{url} - , text_{filename} -{ - readableFileSize_ = utils::humanReadableFileSize(size); - - init(); -} - -void -FileItem::openUrl() -{ - if (url_.toString().isEmpty()) - return; - - auto urlToOpen = utils::mxcToHttp( - url_, QString::fromStdString(http::client()->server()), http::client()->port()); - - if (!QDesktopServices::openUrl(urlToOpen)) - nhlog::ui()->warn("Could not open url: {}", urlToOpen.toStdString()); -} - -QSize -FileItem::sizeHint() const -{ - return QSize(MaxWidth, Height); -} - -void -FileItem::mousePressEvent(QMouseEvent *event) -{ - if (event->button() != Qt::LeftButton) - return; - - auto point = event->pos(); - - // Click on the download icon. - if (QRect(HorizontalPadding, VerticalPadding / 2, IconDiameter, IconDiameter) - .contains(point)) { - filenameToSave_ = QFileDialog::getSaveFileName(this, tr("Save File"), text_); - - if (filenameToSave_.isEmpty()) - return; - - auto proxy = std::make_shared<MediaProxy>(); - connect(proxy.get(), &MediaProxy::fileDownloaded, this, &FileItem::fileDownloaded); - - http::client()->download( - url_.toString().toStdString(), - [proxy = std::move(proxy), url = url_](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::ui()->warn("failed to retrieve m.file content: {}", - url.toString().toStdString()); - return; - } - - emit proxy->fileDownloaded(QByteArray(data.data(), data.size())); - }); - } else { - openUrl(); - } -} - -void -FileItem::fileDownloaded(const QByteArray &data) -{ - try { - QFile file(filenameToSave_); - - if (!file.open(QIODevice::WriteOnly)) - return; - - file.write(data); - file.close(); - } catch (const std::exception &e) { - nhlog::ui()->warn("Error while saving file to: {}", e.what()); - } -} - -void -FileItem::resizeEvent(QResizeEvent *event) -{ - QFont font; - font.setWeight(QFont::Medium); - - QFontMetrics fm(font); -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - const int computedWidth = std::min( - fm.width(text_) + 2 * IconRadius + VerticalPadding * 2 + TextPadding, (double)MaxWidth); -#else - const int computedWidth = - std::min(fm.horizontalAdvance(text_) + 2 * IconRadius + VerticalPadding * 2 + TextPadding, - (double)MaxWidth); -#endif - resize(computedWidth, Height); - - event->accept(); -} - -void -FileItem::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - - QFont font; - font.setWeight(QFont::Medium); - - QFontMetrics fm(font); - - QPainterPath path; - path.addRoundedRect(QRectF(0, 0, width(), height()), 10, 10); - - painter.setPen(Qt::NoPen); - painter.fillPath(path, backgroundColor_); - painter.drawPath(path); - - QPainterPath circle; - circle.addEllipse(QPoint(IconXCenter, IconYCenter), IconRadius, IconRadius); - - painter.setPen(Qt::NoPen); - painter.fillPath(circle, iconColor_); - painter.drawPath(circle); - - icon_.paint(&painter, - QRect(IconXCenter - DownloadIconRadius / 2, - IconYCenter - DownloadIconRadius / 2, - DownloadIconRadius, - DownloadIconRadius), - Qt::AlignCenter, - QIcon::Normal); - - const int textStartX = HorizontalPadding + 2 * IconRadius + TextPadding; - const int textStartY = VerticalPadding + fm.ascent() / 2; - - // Draw the filename. - QString elidedText = fm.elidedText( - text_, Qt::ElideRight, width() - HorizontalPadding * 2 - TextPadding - 2 * IconRadius); - - painter.setFont(font); - painter.setPen(QPen(textColor_)); - painter.drawText(QPoint(textStartX, textStartY), elidedText); - - // Draw the filesize. - font.setWeight(QFont::Normal); - painter.setFont(font); - painter.setPen(QPen(textColor_)); - painter.drawText(QPoint(textStartX, textStartY + 1.5 * fm.ascent()), readableFileSize_); -} diff --git a/src/timeline/widgets/FileItem.h b/src/timeline/widgets/FileItem.h deleted file mode 100644
index d63cce88..00000000 --- a/src/timeline/widgets/FileItem.h +++ /dev/null
@@ -1,79 +0,0 @@ -/* - * 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 <QEvent> -#include <QIcon> -#include <QMouseEvent> -#include <QSharedPointer> -#include <QWidget> - -#include <mtx.hpp> - -class FileItem : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) - Q_PROPERTY(QColor iconColor WRITE setIconColor READ iconColor) - Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) - -public: - FileItem(const mtx::events::RoomEvent<mtx::events::msg::File> &event, - QWidget *parent = nullptr); - - FileItem(const QString &url, - const QString &filename, - uint64_t size, - QWidget *parent = nullptr); - - QSize sizeHint() const override; - - void setTextColor(const QColor &color) { textColor_ = color; } - void setIconColor(const QColor &color) { iconColor_ = color; } - void setBackgroundColor(const QColor &color) { backgroundColor_ = color; } - - QColor textColor() const { return textColor_; } - QColor iconColor() const { return iconColor_; } - QColor backgroundColor() const { return backgroundColor_; } - -protected: - void paintEvent(QPaintEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - -private slots: - void fileDownloaded(const QByteArray &data); - -private: - void openUrl(); - void init(); - - QUrl url_; - QString text_; - QString readableFileSize_; - QString filenameToSave_; - - mtx::events::RoomEvent<mtx::events::msg::File> event_; - - QIcon icon_; - - QColor textColor_ = QColor("white"); - QColor iconColor_ = QColor("#38A3D8"); - QColor backgroundColor_ = QColor("#333"); -}; diff --git a/src/timeline/widgets/ImageItem.cpp b/src/timeline/widgets/ImageItem.cpp deleted file mode 100644
index 26c569d7..00000000 --- a/src/timeline/widgets/ImageItem.cpp +++ /dev/null
@@ -1,267 +0,0 @@ -/* - * 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 <QBrush> -#include <QDesktopServices> -#include <QFileDialog> -#include <QFileInfo> -#include <QPainter> -#include <QPixmap> -#include <QUuid> -#include <QtGlobal> - -#include "Config.h" -#include "ImageItem.h" -#include "Logging.h" -#include "MatrixClient.h" -#include "Utils.h" -#include "dialogs/ImageOverlay.h" - -void -ImageItem::downloadMedia(const QUrl &url) -{ - auto proxy = std::make_shared<MediaProxy>(); - connect(proxy.get(), &MediaProxy::imageDownloaded, this, &ImageItem::setImage); - - http::client()->download(url.toString().toStdString(), - [proxy = std::move(proxy), url](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn( - "failed to retrieve image {}: {} {}", - url.toString().toStdString(), - err->matrix_error.error, - static_cast<int>(err->status_code)); - return; - } - - QPixmap img; - img.loadFromData(QByteArray(data.data(), data.size())); - - emit proxy->imageDownloaded(img); - }); -} - -void -ImageItem::saveImage(const QString &filename, const QByteArray &data) -{ - try { - QFile file(filename); - - if (!file.open(QIODevice::WriteOnly)) - return; - - file.write(data); - file.close(); - } catch (const std::exception &e) { - nhlog::ui()->warn("Error while saving file to: {}", e.what()); - } -} - -void -ImageItem::init() -{ - setMouseTracking(true); - setCursor(Qt::PointingHandCursor); - setAttribute(Qt::WA_Hover, true); - - downloadMedia(url_); -} - -ImageItem::ImageItem(const mtx::events::RoomEvent<mtx::events::msg::Image> &event, QWidget *parent) - : QWidget(parent) - , event_{event} -{ - url_ = QString::fromStdString(event.content.url); - text_ = QString::fromStdString(event.content.body); - - init(); -} - -ImageItem::ImageItem(const QString &url, const QString &filename, uint64_t size, QWidget *parent) - : QWidget(parent) - , url_{url} - , text_{filename} -{ - Q_UNUSED(size); - init(); -} - -void -ImageItem::openUrl() -{ - if (url_.toString().isEmpty()) - return; - - auto urlToOpen = utils::mxcToHttp( - url_, QString::fromStdString(http::client()->server()), http::client()->port()); - - if (!QDesktopServices::openUrl(urlToOpen)) - nhlog::ui()->warn("could not open url: {}", urlToOpen.toStdString()); -} - -QSize -ImageItem::sizeHint() const -{ - if (image_.isNull()) - return QSize(max_width_, bottom_height_); - - return QSize(width_, height_); -} - -void -ImageItem::setImage(const QPixmap &image) -{ - image_ = image; - scaled_image_ = utils::scaleDown(max_width_, max_height_, image_); - - width_ = scaled_image_.width(); - height_ = scaled_image_.height(); - - setFixedSize(width_, height_); - update(); -} - -void -ImageItem::mousePressEvent(QMouseEvent *event) -{ - if (!isInteractive_) { - event->accept(); - return; - } - - if (event->button() != Qt::LeftButton) - return; - - if (image_.isNull()) { - openUrl(); - return; - } - - if (textRegion_.contains(event->pos())) { - openUrl(); - } else { - auto imgDialog = new dialogs::ImageOverlay(image_); - imgDialog->show(); - connect(imgDialog, &dialogs::ImageOverlay::saving, this, &ImageItem::saveAs); - } -} - -void -ImageItem::resizeEvent(QResizeEvent *event) -{ - if (!image_) - return QWidget::resizeEvent(event); - - scaled_image_ = utils::scaleDown(max_width_, max_height_, image_); - - width_ = scaled_image_.width(); - height_ = scaled_image_.height(); - - setFixedSize(width_, height_); -} - -void -ImageItem::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - - QFont font; - - QFontMetrics metrics(font); - const int fontHeight = metrics.height() + metrics.ascent(); - - if (image_.isNull()) { - QString elidedText = metrics.elidedText(text_, Qt::ElideRight, max_width_ - 10); -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - setFixedSize(metrics.width(elidedText), fontHeight); -#else - setFixedSize(metrics.horizontalAdvance(elidedText), fontHeight); -#endif - painter.setFont(font); - painter.setPen(QPen(QColor(66, 133, 244))); - painter.drawText(QPoint(0, fontHeight / 2), elidedText); - - return; - } - - imageRegion_ = QRectF(0, 0, width_, height_); - - QPainterPath path; - path.addRoundedRect(imageRegion_, 5, 5); - - painter.setPen(Qt::NoPen); - painter.fillPath(path, scaled_image_); - painter.drawPath(path); - - // Bottom text section - if (isInteractive_ && underMouse()) { - const int textBoxHeight = fontHeight / 2 + 6; - - textRegion_ = QRectF(0, height_ - textBoxHeight, width_, textBoxHeight); - - QPainterPath textPath; - textPath.addRoundedRect(textRegion_, 0, 0); - - painter.fillPath(textPath, QColor(40, 40, 40, 140)); - - QString elidedText = metrics.elidedText(text_, Qt::ElideRight, width_ - 10); - - font.setWeight(QFont::Medium); - painter.setFont(font); - painter.setPen(QPen(QColor(Qt::white))); - - textRegion_.adjust(5, 0, 5, 0); - painter.drawText(textRegion_, Qt::AlignVCenter, elidedText); - } -} - -void -ImageItem::saveAs() -{ - auto filename = QFileDialog::getSaveFileName(this, tr("Save image"), text_); - - if (filename.isEmpty()) - return; - - const auto url = url_.toString().toStdString(); - - auto proxy = std::make_shared<MediaProxy>(); - connect(proxy.get(), &MediaProxy::imageSaved, this, &ImageItem::saveImage); - - http::client()->download( - url, - [proxy = std::move(proxy), filename, url](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to retrieve image {}: {} {}", - url, - err->matrix_error.error, - static_cast<int>(err->status_code)); - return; - } - - emit proxy->imageSaved(filename, QByteArray(data.data(), data.size())); - }); -} diff --git a/src/timeline/widgets/ImageItem.h b/src/timeline/widgets/ImageItem.h deleted file mode 100644
index 65bd962d..00000000 --- a/src/timeline/widgets/ImageItem.h +++ /dev/null
@@ -1,104 +0,0 @@ -/* - * 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 <QEvent> -#include <QMouseEvent> -#include <QSharedPointer> -#include <QWidget> - -#include <mtx.hpp> - -namespace dialogs { -class ImageOverlay; -} - -class ImageItem : public QWidget -{ - Q_OBJECT -public: - ImageItem(const mtx::events::RoomEvent<mtx::events::msg::Image> &event, - QWidget *parent = nullptr); - - ImageItem(const QString &url, - const QString &filename, - uint64_t size, - QWidget *parent = nullptr); - - QSize sizeHint() const override; - -public slots: - //! Show a save as dialog for the image. - void saveAs(); - void setImage(const QPixmap &image); - void saveImage(const QString &filename, const QByteArray &data); - -protected: - void paintEvent(QPaintEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - - //! Whether the user can interact with the displayed image. - bool isInteractive_ = true; - -private: - void init(); - void openUrl(); - void downloadMedia(const QUrl &url); - - int max_width_ = 500; - int max_height_ = 300; - - int width_; - int height_; - - QPixmap scaled_image_; - QPixmap image_; - - QUrl url_; - QString text_; - - int bottom_height_ = 30; - - QRectF textRegion_; - QRectF imageRegion_; - - mtx::events::RoomEvent<mtx::events::msg::Image> event_; -}; - -class StickerItem : public ImageItem -{ - Q_OBJECT - -public: - StickerItem(const mtx::events::Sticker &event, QWidget *parent = nullptr) - : ImageItem{QString::fromStdString(event.content.url), - QString::fromStdString(event.content.body), - event.content.info.size, - parent} - , event_{event} - { - isInteractive_ = false; - setCursor(Qt::ArrowCursor); - setMouseTracking(false); - setAttribute(Qt::WA_Hover, false); - } - -private: - mtx::events::Sticker event_; -}; diff --git a/src/timeline/widgets/VideoItem.cpp b/src/timeline/widgets/VideoItem.cpp deleted file mode 100644
index 4b5dc022..00000000 --- a/src/timeline/widgets/VideoItem.cpp +++ /dev/null
@@ -1,65 +0,0 @@ -/* - * 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 <QLabel> -#include <QVBoxLayout> - -#include "Config.h" -#include "MatrixClient.h" -#include "Utils.h" -#include "timeline/widgets/VideoItem.h" - -void -VideoItem::init() -{ - url_ = utils::mxcToHttp( - url_, QString::fromStdString(http::client()->server()), http::client()->port()); -} - -VideoItem::VideoItem(const mtx::events::RoomEvent<mtx::events::msg::Video> &event, QWidget *parent) - : QWidget(parent) - , url_{QString::fromStdString(event.content.url)} - , text_{QString::fromStdString(event.content.body)} - , event_{event} -{ - readableFileSize_ = utils::humanReadableFileSize(event.content.info.size); - - init(); - - auto layout = new QVBoxLayout(this); - layout->setMargin(0); - layout->setSpacing(0); - - QString link = QString("<a href=%1>%2</a>").arg(url_.toString()).arg(text_); - - label_ = new QLabel(link, this); - label_->setMargin(0); - label_->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextBrowserInteraction); - label_->setOpenExternalLinks(true); - - layout->addWidget(label_); -} - -VideoItem::VideoItem(const QString &url, const QString &filename, uint64_t size, QWidget *parent) - : QWidget(parent) - , url_{url} - , text_{filename} -{ - readableFileSize_ = utils::humanReadableFileSize(size); - - init(); -} diff --git a/src/timeline/widgets/VideoItem.h b/src/timeline/widgets/VideoItem.h deleted file mode 100644
index 26fa1c35..00000000 --- a/src/timeline/widgets/VideoItem.h +++ /dev/null
@@ -1,51 +0,0 @@ -/* - * 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 <QEvent> -#include <QLabel> -#include <QSharedPointer> -#include <QUrl> -#include <QWidget> - -#include <mtx.hpp> - -class VideoItem : public QWidget -{ - Q_OBJECT - -public: - VideoItem(const mtx::events::RoomEvent<mtx::events::msg::Video> &event, - QWidget *parent = nullptr); - - VideoItem(const QString &url, - const QString &filename, - uint64_t size, - QWidget *parent = nullptr); - -private: - void init(); - - QUrl url_; - QString text_; - QString readableFileSize_; - - QLabel *label_; - - mtx::events::RoomEvent<mtx::events::msg::Video> event_; -};