AvatarJob improvements

* Drop AvatarJob2
* Allow AvatarJob to retrieve different sizes and users
* Make creating a circular avatar into a function
  (maybe all avatars should be made into that shape in the first place)
This commit is contained in:
Christian Kamm 2017-11-21 10:18:15 +01:00 committed by ckamm
parent 6b9b5252de
commit e9907bc8ae
9 changed files with 46 additions and 183 deletions

View File

@ -47,7 +47,6 @@ set(client_SRCS
accountmanager.cpp
accountsettings.cpp
application.cpp
avatarjob.cpp
folder.cpp
folderman.cpp
folderstatusmodel.cpp

View File

@ -1,52 +0,0 @@
/*
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
*
* 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; version 2 of the License.
*
* 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.
*/
#include "avatarjob.h"
#include "networkjobs.h"
#include "account.h"
#include <QLatin1String>
namespace OCC {
AvatarJob2::AvatarJob2(const QString &userId, int size, AccountPtr account, QObject* parent)
: AbstractNetworkJob(account, QLatin1String("remote.php/dav/avatars/"), parent)
{
setIgnoreCredentialFailure(true);
//Append <userid>/<size> to the path
setPath(path() + userId + QString("/%1").arg(size));
}
void AvatarJob2::start()
{
sendRequest("GET", Utility::concatUrlPath(account()->url(), path()));
AbstractNetworkJob::start();
}
bool AvatarJob2::finished()
{
int statusCode = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (statusCode != 200) {
emit avatarNotAvailable(statusCode);
} else {
QByteArray data = reply()->readAll();
QString mimeType = reply()->header(QNetworkRequest::ContentTypeHeader).toString();
emit avatarReady(data, mimeType);
}
return true;
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
*
* 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; version 2 of the License.
*
* 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.
*/
#ifndef AVATARJOB_H
#define AVATARJOB_H
#include "networkjobs.h"
#include "accountfwd.h"
namespace OCC {
/**
* @brief Job to fetch an avatar for a user
* @ingroup gui
*/
class AvatarJob2 : public AbstractNetworkJob {
Q_OBJECT
public:
/**
* @param userId The user for which to obtain the avatar
* @param size The size of the avatar (square so size*size)
* @param account For which account to obtain the avatar
* @param parent Parent of the object
*/
explicit AvatarJob2(const QString& userId, int size, AccountPtr account, QObject* parent = 0);
public slots:
/* Start the job */
void start() Q_DECL_OVERRIDE;
signals:
/**
* Signal that the job is done and returned an avatar
*
* @param reply the content of the reply
* @param the mimetype (set by the server)
*/
void avatarReady(QByteArray reply, QString mimeType);
/**
* Signal that the job is done but the server did not return
* an avatar
*
* @param statusCode The status code returned by the server
*/
void avatarNotAvailable(int statusCode);
private slots:
virtual bool finished() Q_DECL_OVERRIDE;
};
}
#endif // AVATAR_H

View File

@ -57,23 +57,6 @@ namespace OCC {
#include "settingsdialogcommon.cpp"
static QIcon circleMask(const QImage &avatar)
{
int dim = avatar.width();
QPixmap fixedImage(dim, dim);
fixedImage.fill(Qt::transparent);
QPainter imgPainter(&fixedImage);
QPainterPath clip;
clip.addEllipse(0, 0, dim, dim);
imgPainter.setClipPath(clip);
imgPainter.drawImage(0, 0, avatar);
imgPainter.end();
return QIcon(fixedImage);
}
//
// Whenever you change something here check both settingsdialog.cpp and settingsdialogmac.cpp !
//
@ -232,7 +215,7 @@ void SettingsDialog::accountAdded(AccountState *s)
accountAction = createColorAwareAction(QLatin1String(":/client/resources/account.png"),
actionText);
} else {
QIcon icon = circleMask(avatar);
QIcon icon(QPixmap::fromImage(AvatarJob::makeCircularAvatar(avatar)));
accountAction = createActionWithIcon(icon, actionText);
}
@ -265,7 +248,7 @@ void SettingsDialog::slotAccountAvatarChanged()
if (action) {
QImage pix = account->avatar();
if (!pix.isNull()) {
action->setIcon(circleMask(pix));
action->setIcon(QPixmap::fromImage(AvatarJob::makeCircularAvatar(pix)));
}
}
}

View File

@ -26,7 +26,6 @@
#include "thumbnailjob.h"
#include "sharee.h"
#include "sharemanager.h"
#include "avatarjob.h"
#include "QProgressIndicator.h"
#include <QBuffer>
@ -470,53 +469,23 @@ void ShareUserLine::loadAvatar()
// We can only fetch avatars for local users currently
if (_share->getShareWith()->type() == Sharee::User) {
AvatarJob2 *job = new AvatarJob2(_share->getShareWith()->shareWith(), 48, _share->account(), this);
connect(job, SIGNAL(avatarReady(QByteArray, QString)), SLOT(slotAvatarLoaded(QByteArray, QString)));
AvatarJob *job = new AvatarJob(_share->account(), _share->getShareWith()->shareWith(), 48, this);
connect(job, &AvatarJob::avatarPixmap, this, &ShareUserLine::slotAvatarLoaded);
job->start();
}
}
void ShareUserLine::slotAvatarLoaded(const QByteArray &data, const QString &mimeType)
void ShareUserLine::slotAvatarLoaded(QImage avatar)
{
QPixmap p;
bool valid = false;
if (mimeType == "image/png") {
valid = p.loadFromData(data, "PNG");
} else if (mimeType == "image/jpeg") {
valid = p.loadFromData(data, "JPG");
} else {
// Guess the filetype
valid = p.loadFromData(data);
}
if (avatar.isNull())
return;
// If the image was loaded succesfully set it!
if (valid) {
avatar = AvatarJob::makeCircularAvatar(avatar);
/*
* We want round avatars so create a new pixmap to draw
* the round avatar on and set a transparent background
*/
QPixmap avatar(p.width(), p.height());
avatar.fill(QColor(0,0,0,0));
_ui->avatar->setPixmap(QPixmap::fromImage(avatar));
// Initialise our painer
QPainter painter(&avatar);
painter.setRenderHint(QPainter::Antialiasing);
// Set to draw only a cricle
QPainterPath path;
path.addEllipse(0,0,p.width(),p.height());
painter.setClipPath(path);
// Draw the round avatar
painter.drawPixmap(0,0,p.width(),p.width(),p);
// Set the avatar
_ui->avatar->setPixmap(avatar);
// Remove the stylesheet
_ui->avatar->setStyleSheet("");
}
// Remove the stylesheet for the fallback avatar
_ui->avatar->setStyleSheet("");
}
void ShareUserLine::on_deleteShareButton_clicked()

View File

@ -131,7 +131,7 @@ private slots:
void slotShareDeleted();
void slotPermissionsSet();
void slotAvatarLoaded(const QByteArray &data, const QString &mimeType);
void slotAvatarLoaded(QImage avatar);
private:
void displayPermissions();

View File

@ -334,7 +334,7 @@ void ConnectionValidator::slotUserFetched(const QJsonDocument &json)
if (!user.isEmpty()) {
_account->setDavUser(user);
AvatarJob *job = new AvatarJob(_account, this);
AvatarJob *job = new AvatarJob(_account, _account->davUser(), 128, this);
job->setTimeout(20 * 1000);
QObject::connect(job, &AvatarJob::avatarPixmap, this, &ConnectionValidator::slotAvatarImage);

View File

@ -30,6 +30,7 @@
#include <QPixmap>
#include <QJsonDocument>
#include <QJsonObject>
#include <QPainter>
#include "networkjobs.h"
#include "account.h"
@ -626,10 +627,10 @@ bool PropfindJob::finished()
/*********************************************************************************************/
AvatarJob::AvatarJob(AccountPtr account, QObject *parent)
AvatarJob::AvatarJob(AccountPtr account, const QString &userId, int size, QObject *parent)
: AbstractNetworkJob(account, QString(), parent)
{
_avatarUrl = Utility::concatUrlPath(account->url(), QString("remote.php/dav/avatars/%1/128.png").arg(account->davUser()));
_avatarUrl = Utility::concatUrlPath(account->url(), QString("remote.php/dav/avatars/%1/%2.png").arg(userId, QString::number(size)));
}
void AvatarJob::start()
@ -639,6 +640,26 @@ void AvatarJob::start()
AbstractNetworkJob::start();
}
QImage AvatarJob::makeCircularAvatar(const QImage &baseAvatar)
{
int dim = baseAvatar.width();
QImage avatar(dim, dim, baseAvatar.format());
avatar.fill(Qt::transparent);
QPainter painter(&avatar);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addEllipse(0, 0, dim, dim);
painter.setClipPath(path);
painter.drawImage(0, 0, baseAvatar);
painter.end();
return avatar;
}
bool AvatarJob::finished()
{
int http_result_code = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

View File

@ -137,9 +137,7 @@ private:
/**
* @brief The AvatarJob class
*
* Retrieves the account users avatar from the server using a GET request.
* @brief Retrieves the account users avatar from the server using a GET request.
*
* If the server does not have the avatar, the result Pixmap is empty.
*
@ -149,9 +147,17 @@ class OWNCLOUDSYNC_EXPORT AvatarJob : public AbstractNetworkJob
{
Q_OBJECT
public:
explicit AvatarJob(AccountPtr account, QObject *parent = 0);
/**
* @param userId The user for which to obtain the avatar
* @param size The size of the avatar (square so size*size)
*/
explicit AvatarJob(AccountPtr account, const QString &userId, int size, QObject *parent = 0);
void start() Q_DECL_OVERRIDE;
/** The retrieved avatar images don't have the circle shape by default */
static QImage makeCircularAvatar(const QImage &baseAvatar);
signals:
/**
* @brief avatarPixmap - returns either a valid pixmap or not.