Comparar commits
12 Commits
2.1
...
share_avatars
| Autor | SHA1 | Data | |
|---|---|---|---|
| a0b0e3ca3d | |||
| 22ca648a3d | |||
| 4daf051e1d | |||
| ae806e8214 | |||
| e67bb1c5ce | |||
| f2c9a49c50 | |||
| e27374324d | |||
| 895f0b29aa | |||
| f54f48615d | |||
| 06bb97e6d9 | |||
| 0763f65329 | |||
| 40395bdc0e |
+1
-1
@@ -1,5 +1,5 @@
|
||||
set( MIRALL_VERSION_MAJOR 2 )
|
||||
set( MIRALL_VERSION_MINOR 1 )
|
||||
set( MIRALL_VERSION_MINOR 2 )
|
||||
set( MIRALL_VERSION_PATCH 0 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
|
||||
+12
-11
@@ -193,25 +193,26 @@ You can download the desktop sync client from the ownCloud `Client Download Page
|
||||
|
||||
To build the most up to date version of the client:
|
||||
|
||||
1. Clone the latest versions of the client from Git_ as follows:
|
||||
1. Clone the latest versions of the client from Git_ as follows::
|
||||
|
||||
``git clone git://github.com/owncloud/client.git``
|
||||
``git submodule init``
|
||||
``git submodule update``
|
||||
git clone git://github.com/owncloud/client.git
|
||||
cd client
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
2. Create the build directory:
|
||||
2. Create the build directory::
|
||||
|
||||
``mkdir client-build``
|
||||
``cd client-build``
|
||||
mkdir client-build
|
||||
cd client-build
|
||||
|
||||
3. Configure the client build:
|
||||
3. Configure the client build::
|
||||
|
||||
``cmake -DCMAKE_BUILD_TYPE="Debug" ../client``
|
||||
cmake -DCMAKE_BUILD_TYPE="Debug" ..
|
||||
|
||||
..note:: You must use absolute paths for the ``include`` and ``library``
|
||||
.. note:: You must use absolute paths for the ``include`` and ``library``
|
||||
directories.
|
||||
|
||||
..note:: On Mac OS X, you need to specify ``-DCMAKE_INSTALL_PREFIX=target``,
|
||||
.. note:: On Mac OS X, you need to specify ``-DCMAKE_INSTALL_PREFIX=target``,
|
||||
where ``target`` is a private location, i.e. in parallel to your build
|
||||
dir by specifying ``../install``.
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ set(client_SRCS
|
||||
accountmanager.cpp
|
||||
accountsettings.cpp
|
||||
application.cpp
|
||||
avatarjob.cpp
|
||||
folder.cpp
|
||||
folderman.cpp
|
||||
folderstatusmodel.cpp
|
||||
|
||||
@@ -103,11 +103,6 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
|
||||
connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
this, SLOT(refreshSelectiveSyncStatus()));
|
||||
|
||||
QAction *resetFolderAction = new QAction(this);
|
||||
resetFolderAction->setShortcut(QKeySequence(Qt::Key_F5));
|
||||
connect(resetFolderAction, SIGNAL(triggered()), SLOT(slotResetCurrentFolder()));
|
||||
addAction(resetFolderAction);
|
||||
|
||||
QAction *syncNowAction = new QAction(this);
|
||||
syncNowAction->setShortcut(QKeySequence(Qt::Key_F6));
|
||||
connect(syncNowAction, SIGNAL(triggered()), SLOT(slotSyncCurrentFolderNow()));
|
||||
@@ -359,31 +354,6 @@ void AccountSettings::slotRemoveCurrentFolder()
|
||||
}
|
||||
}
|
||||
|
||||
void AccountSettings::slotResetCurrentFolder()
|
||||
{
|
||||
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
||||
if( selected.isValid() ) {
|
||||
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
||||
if (alias.isEmpty())
|
||||
return;
|
||||
int ret = QMessageBox::question( 0, tr("Confirm Folder Reset"),
|
||||
tr("<p>Do you really want to reset folder <i>%1</i> and rebuild your client database?</p>"
|
||||
"<p><b>Note:</b> This function is designed for maintenance purposes only. "
|
||||
"No files will be removed, but this can cause significant data traffic and "
|
||||
"take several minutes or hours to complete, depending on the size of the folder. "
|
||||
"Only use this option if advised by your administrator.</p>").arg(alias),
|
||||
QMessageBox::Yes|QMessageBox::No );
|
||||
if( ret == QMessageBox::Yes ) {
|
||||
FolderMan *folderMan = FolderMan::instance();
|
||||
if(Folder *f = folderMan->folder(alias)) {
|
||||
f->slotTerminateSync();
|
||||
f->wipe();
|
||||
}
|
||||
folderMan->slotScheduleAllFolders();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AccountSettings::slotOpenCurrentFolder()
|
||||
{
|
||||
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
||||
|
||||
@@ -72,7 +72,6 @@ protected slots:
|
||||
void slotEnableCurrentFolder();
|
||||
void slotSyncCurrentFolderNow();
|
||||
void slotRemoveCurrentFolder();
|
||||
void slotResetCurrentFolder();
|
||||
void slotOpenCurrentFolder();
|
||||
void slotFolderWizardAccepted();
|
||||
void slotFolderWizardRejected();
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
AvatarJob::AvatarJob(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 AvatarJob::start()
|
||||
{
|
||||
setReply(getRequest(path()));
|
||||
setupConnections(reply());
|
||||
AbstractNetworkJob::start();
|
||||
}
|
||||
|
||||
bool AvatarJob::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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 AvatarJob : 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 AvatarJob(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
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "thumbnailjob.h"
|
||||
#include "share.h"
|
||||
#include "sharee.h"
|
||||
#include "avatarjob.h"
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
#include <QBuffer>
|
||||
@@ -39,6 +40,9 @@
|
||||
#include <QPropertyAnimation>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QCryptographicHash>
|
||||
#include <QColor>
|
||||
#include <QPainter>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
@@ -145,7 +149,7 @@ void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>>
|
||||
continue;
|
||||
}
|
||||
|
||||
ShareWidget *s = new ShareWidget(share, _isFile, _ui->scrollArea);
|
||||
ShareWidget *s = new ShareWidget(share, _isFile, _account, _ui->scrollArea);
|
||||
connect(s, SIGNAL(resizeRequested()), this, SLOT(slotAdjustScrollWidgetSize()));
|
||||
layout->addWidget(s);
|
||||
|
||||
@@ -199,11 +203,13 @@ void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex & index)
|
||||
|
||||
ShareWidget::ShareWidget(QSharedPointer<Share> share,
|
||||
bool isFile,
|
||||
AccountPtr account,
|
||||
QWidget *parent) :
|
||||
QWidget(parent),
|
||||
_ui(new Ui::ShareWidget),
|
||||
_share(share),
|
||||
_isFile(isFile)
|
||||
_isFile(isFile),
|
||||
_account(account)
|
||||
{
|
||||
_ui->setupUi(this);
|
||||
|
||||
@@ -250,6 +256,103 @@ ShareWidget::ShareWidget(QSharedPointer<Share> share,
|
||||
if (!share->account()->capabilities().shareResharing()) {
|
||||
_ui->permissionShare->hide();
|
||||
}
|
||||
|
||||
loadAvatar();
|
||||
}
|
||||
|
||||
void ShareWidget::loadAvatar()
|
||||
{
|
||||
/* Set the default place holder
|
||||
* This is calculated the same way as on the webinterface
|
||||
* So that the colors match
|
||||
*
|
||||
* This is done first so that we can directly show something
|
||||
*/
|
||||
|
||||
// Set size of the placeholder
|
||||
_ui->avatar->setMinimumHeight(48);
|
||||
_ui->avatar->setMinimumWidth(48);
|
||||
_ui->avatar->setMaximumHeight(48);
|
||||
_ui->avatar->setMaximumWidth(48);
|
||||
_ui->avatar->setAlignment(Qt::AlignCenter);
|
||||
|
||||
/* Calculate the hue
|
||||
* We could use more digits but we have the MSB now which
|
||||
* is already plenty
|
||||
*/
|
||||
const QString text = _share->getShareWith()->displayName();
|
||||
|
||||
QString seed = _share->getShareWith()->shareWith();
|
||||
if (_share->getShareWith()->type() != Sharee::User) {
|
||||
seed += QString(" %1").arg(_share->getShareWith()->type());
|
||||
}
|
||||
|
||||
const QByteArray hash = QCryptographicHash::hash(seed.toUtf8(), QCryptographicHash::Md5);
|
||||
int hue = ((double)hash.mid(0, 3).toHex().toInt(0, 16) / (double)0xffffff) * 255;
|
||||
|
||||
const QColor bg = QColor::fromHsl(hue, 230, 166);
|
||||
const QString style = QString("* {\
|
||||
color: #fff;\
|
||||
background-color: %1;\
|
||||
border-radius: 24px;\
|
||||
font-size: 26px\
|
||||
}").arg(bg.name());
|
||||
|
||||
// Set the style
|
||||
_ui->avatar->setStyleSheet(style);
|
||||
|
||||
// Set the placeholder text
|
||||
_ui->avatar->setText(text.at(0).toUpper());
|
||||
|
||||
// We can only fetch avatars for local users currently
|
||||
if (_share->getShareWith()->type() == Sharee::User) {
|
||||
AvatarJob *job = new AvatarJob(_share->getShareWith()->shareWith(), 48, _account, this);
|
||||
connect(job, SIGNAL(avatarReady(QByteArray, QString)), SLOT(slotAvatarLoaded(QByteArray, QString)));
|
||||
job->start();
|
||||
}
|
||||
}
|
||||
|
||||
void ShareWidget::slotAvatarLoaded(const QByteArray &data, const QString &mimeType)
|
||||
{
|
||||
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 the image was loaded succesfully set it!
|
||||
if (valid) {
|
||||
|
||||
/*
|
||||
* 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));
|
||||
|
||||
// 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("");
|
||||
}
|
||||
}
|
||||
|
||||
void ShareWidget::on_deleteShareButton_clicked()
|
||||
|
||||
@@ -48,7 +48,10 @@ class ShareWidget : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ShareWidget(QSharedPointer<Share> Share, bool isFile, QWidget *parent = 0);
|
||||
explicit ShareWidget(QSharedPointer<Share> Share,
|
||||
bool isFile,
|
||||
AccountPtr account,
|
||||
QWidget *parent = 0);
|
||||
~ShareWidget();
|
||||
|
||||
QSharedPointer<Share> share() const;
|
||||
@@ -65,12 +68,16 @@ private slots:
|
||||
|
||||
void slotShareDeleted();
|
||||
void slotPermissionsSet();
|
||||
void slotAvatarLoaded(const QByteArray &data, const QString &mimeType);
|
||||
|
||||
private:
|
||||
void displayPermissions();
|
||||
void loadAvatar();
|
||||
|
||||
Ui::ShareWidget *_ui;
|
||||
QSharedPointer<Share> _share;
|
||||
bool _isFile;
|
||||
AccountPtr _account;
|
||||
|
||||
QAction *_permissionCreate;
|
||||
QAction *_permissionUpdate;
|
||||
|
||||
@@ -31,6 +31,13 @@
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="avatar">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sharedWith">
|
||||
<property name="text">
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário