From cc54c6393a88c32f53fa3da6f75bb6c31cea6a32 Mon Sep 17 00:00:00 2001 From: blue Date: Wed, 18 Sep 2019 01:05:32 +0300 Subject: [PATCH] aspectRation handling for images, other then images types of downloads, progress fix, labels, context menu to open files --- core/networkaccess.cpp | 6 +- ui/CMakeLists.txt | 2 + ui/utils/image.cpp | 52 +++++++++++++ ui/utils/image.h | 61 +++++++++++++++ ui/utils/resizer.cpp | 34 +++++++++ ui/utils/resizer.h | 41 ++++++++++ ui/widgets/conversation.cpp | 15 ---- ui/widgets/conversation.h | 13 +--- ui/widgets/message.cpp | 147 ++++++++++++++++++++++++------------ ui/widgets/message.h | 16 +++- 10 files changed, 307 insertions(+), 80 deletions(-) create mode 100644 ui/utils/image.cpp create mode 100644 ui/utils/image.h create mode 100644 ui/utils/resizer.cpp create mode 100644 ui/utils/resizer.h diff --git a/core/networkaccess.cpp b/core/networkaccess.cpp index 518c7b1..7fd3b06 100644 --- a/core/networkaccess.cpp +++ b/core/networkaccess.cpp @@ -115,8 +115,12 @@ void Core::NetworkAccess::onDownloadProgress(qint64 bytesReceived, qint64 bytesT qDebug() << "an error downloading" << url << ": the request had some progress but seems like noone is waiting for it, skipping"; } else { Download* dwn = itr->second; + qreal received = bytesReceived; + qreal total = bytesTotal; + qreal progress = received/total; + dwn->progress = progress; for (std::set::const_iterator mItr = dwn->messages.begin(), end = dwn->messages.end(); mItr != end; ++mItr) { - emit downloadFileProgress(*mItr, bytesReceived/bytesTotal); + emit downloadFileProgress(*mItr, progress); } } } diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 2887403..d9ede46 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -31,6 +31,8 @@ set(squawkUI_SRC widgets/account.cpp widgets/joinconference.cpp widgets/message.cpp + utils/resizer.cpp + utils/image.cpp ) # Tell CMake to create the helloworld executable diff --git a/ui/utils/image.cpp b/ui/utils/image.cpp new file mode 100644 index 0000000..0abccf1 --- /dev/null +++ b/ui/utils/image.cpp @@ -0,0 +1,52 @@ +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * 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 . + */ + +#include +#include "image.h" + +Image::Image(const QString& path, QWidget* parent): + QLabel(parent), + pixmap(path), + aspectRatio(0) +{ + + qreal height = pixmap.height(); + qreal width = pixmap.width(); + aspectRatio = width / height; + setPixmap(pixmap); + setScaledContents(true); + setMinimumHeight(50 / aspectRatio); + setMinimumWidth(50); +} + +Image::~Image() +{ + +} + +int Image::heightForWidth(int width) const +{ + int height = width / aspectRatio; + //qDebug() << height << width << aspectRatio; + return height; +} + +bool Image::hasHeightForWidth() const +{ + return true; +} diff --git a/ui/utils/image.h b/ui/utils/image.h new file mode 100644 index 0000000..7d61202 --- /dev/null +++ b/ui/utils/image.h @@ -0,0 +1,61 @@ +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * 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 . + */ + +#ifndef IMAGE_H +#define IMAGE_H + +#include +#include + +/** + * @todo write docs + */ +class Image : public QLabel +{ +public: + /** + * Default constructor + */ + Image(const QString& path, QWidget* parent = nullptr); + + /** + * Destructor + */ + ~Image(); + + /** + * @todo write docs + * + * @param TODO + * @return TODO + */ + int heightForWidth(int width) const override; + + /** + * @todo write docs + * + * @return TODO + */ + virtual bool hasHeightForWidth() const; + +private: + QPixmap pixmap; + qreal aspectRatio; +}; + +#endif // IMAGE_H diff --git a/ui/utils/resizer.cpp b/ui/utils/resizer.cpp new file mode 100644 index 0000000..45a21e8 --- /dev/null +++ b/ui/utils/resizer.cpp @@ -0,0 +1,34 @@ +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * 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 . + */ + +#include "resizer.h" + +Resizer::Resizer(QWidget* parent): +QObject(parent) +{ + +} + +bool Resizer::eventFilter(QObject* obj, QEvent* event) +{ + if (event->type() == QEvent::Resize) { + emit resized(); + } + + return false; +} diff --git a/ui/utils/resizer.h b/ui/utils/resizer.h new file mode 100644 index 0000000..85fc97e --- /dev/null +++ b/ui/utils/resizer.h @@ -0,0 +1,41 @@ +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * 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 . + */ + +#ifndef RESIZER_H +#define RESIZER_H + +#include +#include +#include + +/** + * @todo write docs + */ +class Resizer : public QObject { + Q_OBJECT +public: + Resizer(QWidget* parent = nullptr); + +protected: + bool eventFilter(QObject* obj, QEvent* event) override; + +signals: + void resized(); +}; + +#endif // RESIZER_H diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp index 47a8f25..73fc851 100644 --- a/ui/widgets/conversation.cpp +++ b/ui/widgets/conversation.cpp @@ -295,21 +295,6 @@ void Conversation::responseLocalFile(const QString& messageId, const QString& pa line->responseLocalFile(messageId, path); } -Resizer::Resizer(QWidget* parent): - QObject(parent) -{ - -} - -bool Resizer::eventFilter(QObject* obj, QEvent* event) -{ - if (event->type() == QEvent::Resize) { - emit resized(); - } - - return false; -} - bool VisibilityCatcher::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::Show) { diff --git a/ui/widgets/conversation.h b/ui/widgets/conversation.h index 2c0ce9d..3d1529c 100644 --- a/ui/widgets/conversation.h +++ b/ui/widgets/conversation.h @@ -23,6 +23,7 @@ #include #include "../../global.h" #include "messageline.h" +#include "../utils/resizer.h" namespace Ui { @@ -42,18 +43,6 @@ signals: void enterPressed(); }; -class Resizer : public QObject { - Q_OBJECT -public: - Resizer(QWidget* parent = nullptr); - -protected: - bool eventFilter(QObject* obj, QEvent* event) override; - -signals: - void resized(); -}; - class VisibilityCatcher : public QObject { Q_OBJECT public: diff --git a/ui/widgets/message.cpp b/ui/widgets/message.cpp index 70d7e82..54cbcfc 100644 --- a/ui/widgets/message.cpp +++ b/ui/widgets/message.cpp @@ -17,6 +17,9 @@ */ #include +#include +#include +#include #include "message.h" const QRegExp urlReg("^(?!setBackgroundRole(QPalette::AlternateBase); body->setAutoFillBackground(true); @@ -86,6 +90,9 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_ Message::~Message() { + if (!commentAdded) { + delete fileComment; + } } QString Message::getId() const @@ -100,27 +107,23 @@ void Message::setSender(const QString& p_sender) void Message::addDownloadDialog() { - if (hasFile) { - file->deleteLater(); - file = 0; - hasFile = false; - } - if (hasProgress) { - progress->deleteLater(); - progress = 0; - hasProgress = false;; - } + hideFile(); + hideProgress(); if (!hasDownloadButton) { + hideComment(); if (msg.getBody() == msg.getOutOfBandUrl()) { text->setText(""); text->hide(); } downloadButton = new QPushButton(QIcon::fromTheme("download"), "Download"); - fileComment = new QLabel(sender->text() + " is offering you to download a file"); + downloadButton->setToolTip("" + msg.getOutOfBandUrl() + ""); + fileComment->setText(sender->text() + " is offering you to download a file"); + fileComment->show(); connect(downloadButton, SIGNAL(clicked()), this, SLOT(onDownload())); bodyLayout->insertWidget(2, fileComment); bodyLayout->insertWidget(3, downloadButton); hasDownloadButton = true; + commentAdded = true; } } @@ -130,54 +133,98 @@ void Message::onDownload() } void Message::setProgress(qreal value) +{ + hideFile(); + hideDownload(); + if (!hasProgress) { + hideComment(); + if (msg.getBody() == msg.getOutOfBandUrl()) { + text->setText(""); + text->hide(); + } + progress = new QProgressBar(); + progress->setRange(0, 100); + fileComment->setText("Downloading..."); + fileComment->show(); + bodyLayout->insertWidget(2, progress); + bodyLayout->insertWidget(3, fileComment); + hasProgress = true; + commentAdded = true; + } + progress->setValue(value * 100); +} + +void Message::showFile(const QString& path) +{ + hideDownload(); + hideProgress(); + if (!hasFile) { + hideComment(); + if (msg.getBody() == msg.getOutOfBandUrl()) { + text->setText(""); + text->hide(); + } + QMimeDatabase db; + QMimeType type = db.mimeTypeForFile(path); + QStringList parts = type.name().split("/"); + QString big = parts.front(); + QFileInfo info(path); + fileComment = new QLabel(); + if (big == "image") { + file = new Image(path); + } else { + file = new QLabel(); + file->setPixmap(QIcon::fromTheme(type.iconName()).pixmap(50)); + file->setAlignment(Qt::AlignCenter); + fileComment->setText(info.fileName()); + fileComment->setWordWrap(true); + fileComment->show(); + } + file->setContextMenuPolicy(Qt::ActionsContextMenu); + QAction* openAction = new QAction(QIcon::fromTheme("document-new-from-template"), "Open", file); + connect(openAction, &QAction::triggered, [path]() { //TODO need to get rid of this shame + QDesktopServices::openUrl(QUrl::fromLocalFile(path)); + }); + file->addAction(openAction); + bodyLayout->insertWidget(2, file); + bodyLayout->insertWidget(3, fileComment); + hasFile = true; + commentAdded = true; + } +} + +void Message::hideComment() +{ + if (commentAdded) { + bodyLayout->removeWidget(fileComment); + fileComment->hide(); + fileComment->setWordWrap(false); + } +} + +void Message::hideDownload() +{ + if (hasDownloadButton) { + downloadButton->deleteLater(); + downloadButton = 0; + hasDownloadButton = false; + } +} + +void Message::hideFile() { if (hasFile) { file->deleteLater(); file = 0; hasFile = false; } - if (hasDownloadButton) { - downloadButton->deleteLater(); - fileComment->deleteLater(); - downloadButton = 0; - fileComment = 0; - hasDownloadButton = false; - } - if (!hasProgress) { - if (msg.getBody() == msg.getOutOfBandUrl()) { - text->setText(""); - text->hide(); - } - progress = new QLabel(std::to_string(value).c_str()); - bodyLayout->insertWidget(2, progress); - hasProgress = true; - } } -void Message::showFile(const QString& path) +void Message::hideProgress() { - if (hasDownloadButton) { - downloadButton->deleteLater(); - fileComment->deleteLater(); - downloadButton = 0; - fileComment = 0; - hasDownloadButton = false; - } if (hasProgress) { progress->deleteLater(); progress = 0; - hasProgress = false; - } - if (!hasFile) { - if (msg.getBody() == msg.getOutOfBandUrl()) { - text->setText(""); - text->hide(); - } - //file = new QLabel(""); - file = new QLabel(); - file->setPixmap(QPixmap(path)); - //file->setScaledContents(true); - bodyLayout->insertWidget(2, file); - hasFile = true; + hasProgress = false;; } } diff --git a/ui/widgets/message.h b/ui/widgets/message.h index e59a372..362feaf 100644 --- a/ui/widgets/message.h +++ b/ui/widgets/message.h @@ -25,8 +25,14 @@ #include #include #include +#include +#include +#include +#include #include "../../global.h" +#include "../utils/resizer.h" +#include "../utils/image.h" /** * @todo write docs @@ -58,15 +64,21 @@ private: QGraphicsDropShadowEffect* shadow; QPushButton* downloadButton; QLabel* file; - QLabel* progress; + QProgressBar* progress; QLabel* fileComment; bool hasDownloadButton; bool hasProgress; bool hasFile; + bool commentAdded; private slots: void onDownload(); - + +private: + void hideDownload(); + void hideProgress(); + void hideFile(); + void hideComment(); }; #endif // MESSAGE_H