diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-03-31 13:16:02 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-03-31 14:23:55 +0900 |
commit | efeb50a46ad824aa258472f6ac8da74810f05a55 (patch) | |
tree | a89c6f35d56986c60e73f870530c9d6ee0527e6d /avatar.cpp | |
parent | 29093379b707bfe620234c2968b37aa86666542a (diff) | |
download | libquotient-efeb50a46ad824aa258472f6ac8da74810f05a55.tar.gz libquotient-efeb50a46ad824aa258472f6ac8da74810f05a55.zip |
Move source files to a separate folder
It's been long overdue to separate them from the rest of the stuff (docs etc.). Also, this allows installing to a directory within the checked out git tree (say, ./install/, similar to ./build/).
Diffstat (limited to 'avatar.cpp')
-rw-r--r-- | avatar.cpp | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/avatar.cpp b/avatar.cpp deleted file mode 100644 index 1ff2aae1..00000000 --- a/avatar.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avatar.h" - -#include "jobs/mediathumbnailjob.h" -#include "events/eventcontent.h" -#include "connection.h" - -#include <QtGui/QPainter> -#include <QtCore/QPointer> - -using namespace QMatrixClient; - -class Avatar::Private -{ - public: - explicit Private(QIcon di, QUrl url = {}) - : _defaultIcon(di), _url(url) - { } - QImage get(Connection* connection, QSize size, - get_callback_t callback) const; - bool upload(UploadContentJob* job, upload_callback_t callback); - - bool checkUrl(QUrl url) const; - - const QIcon _defaultIcon; - QUrl _url; - - // The below are related to image caching, hence mutable - mutable QImage _originalImage; - mutable std::vector<QPair<QSize, QImage>> _scaledImages; - mutable QSize _requestedSize; - mutable bool _bannedUrl = false; - mutable bool _fetched = false; - mutable QPointer<MediaThumbnailJob> _thumbnailRequest = nullptr; - mutable QPointer<BaseJob> _uploadRequest = nullptr; - mutable std::vector<get_callback_t> callbacks; - mutable get_callback_t uploadCallback; -}; - -Avatar::Avatar(QIcon defaultIcon) - : d(std::make_unique<Private>(std::move(defaultIcon))) -{ } - -Avatar::Avatar(QUrl url, QIcon defaultIcon) - : d(std::make_unique<Private>(std::move(defaultIcon), std::move(url))) -{ } - -Avatar::Avatar(Avatar&&) = default; - -Avatar::~Avatar() = default; - -Avatar& Avatar::operator=(Avatar&&) = default; - -QImage Avatar::get(Connection* connection, int dimension, - get_callback_t callback) const -{ - return d->get(connection, {dimension, dimension}, callback); -} - -QImage Avatar::get(Connection* connection, int width, int height, - get_callback_t callback) const -{ - return d->get(connection, {width, height}, callback); -} - -bool Avatar::upload(Connection* connection, const QString& fileName, - upload_callback_t callback) const -{ - if (isJobRunning(d->_uploadRequest)) - return false; - return d->upload(connection->uploadFile(fileName), callback); -} - -bool Avatar::upload(Connection* connection, QIODevice* source, - upload_callback_t callback) const -{ - if (isJobRunning(d->_uploadRequest) || !source->isReadable()) - return false; - return d->upload(connection->uploadContent(source), callback); -} - -QString Avatar::mediaId() const -{ - return d->_url.authority() + d->_url.path(); -} - -QImage Avatar::Private::get(Connection* connection, QSize size, - get_callback_t callback) const -{ - // FIXME: Alternating between longer-width and longer-height requests - // is a sure way to trick the below code into constantly getting another - // image from the server because the existing one is alleged unsatisfactory. - // This is plain abuse by the client, though; so not critical for now. - if( ( !(_fetched || _thumbnailRequest) - || size.width() > _requestedSize.width() - || size.height() > _requestedSize.height() ) && checkUrl(_url) ) - { - qCDebug(MAIN) << "Getting avatar from" << _url.toString(); - _requestedSize = size; - if (isJobRunning(_thumbnailRequest)) - _thumbnailRequest->abandon(); - callbacks.emplace_back(std::move(callback)); - _thumbnailRequest = connection->getThumbnail(_url, size); - QObject::connect( _thumbnailRequest, &MediaThumbnailJob::success, [this] - { - _fetched = true; - _originalImage = _thumbnailRequest->scaledThumbnail(_requestedSize); - _scaledImages.clear(); - for (auto n: callbacks) - n(); - }); - } - - if( _originalImage.isNull() ) - { - if (_defaultIcon.isNull()) - return _originalImage; - - QPainter p { &_originalImage }; - _defaultIcon.paint(&p, { QPoint(), _defaultIcon.actualSize(size) }); - } - - for (auto p: _scaledImages) - if (p.first == size) - return p.second; - auto result = _originalImage.scaled(size, - Qt::KeepAspectRatio, Qt::SmoothTransformation); - _scaledImages.emplace_back(size, result); - return result; -} - -bool Avatar::Private::upload(UploadContentJob* job, upload_callback_t callback) -{ - _uploadRequest = job; - if (!isJobRunning(_uploadRequest)) - return false; - _uploadRequest->connect(_uploadRequest, &BaseJob::success, - [job,callback] { callback(job->contentUri()); }); - return true; -} - -bool Avatar::Private::checkUrl(QUrl url) const -{ - if (_bannedUrl || url.isEmpty()) - return false; - - // FIXME: Make "mxc" a library-wide constant and maybe even make - // the URL checker a Connection(?) method. - _bannedUrl = !(url.isValid() && - url.scheme() == "mxc" && url.path().count('/') == 1); - if (_bannedUrl) - qCWarning(MAIN) << "Avatar URL is invalid or not mxc-based:" - << url.toDisplayString(); - return !_bannedUrl; -} - -QUrl Avatar::url() const { return d->_url; } - -bool Avatar::updateUrl(const QUrl& newUrl) -{ - if (newUrl == d->_url) - return false; - - d->_url = newUrl; - d->_fetched = false; - if (isJobRunning(d->_thumbnailRequest)) - d->_thumbnailRequest->abandon(); - return true; -} - |