2015-11-01 00:21:09 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Roeland Jago Douma <roeland@owncloud.com>
|
|
|
|
*
|
|
|
|
* 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
|
2016-10-25 12:00:07 +03:00
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
2015-11-01 00:21:09 +03:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2015-11-05 11:58:16 +03:00
|
|
|
#include "ui_shareusergroupwidget.h"
|
2017-04-04 16:05:08 +03:00
|
|
|
#include "ui_shareuserline.h"
|
2018-08-02 22:19:57 +03:00
|
|
|
#include "shareusergroupwidget.h"
|
2015-11-01 00:21:09 +03:00
|
|
|
#include "account.h"
|
|
|
|
#include "folderman.h"
|
|
|
|
#include "folder.h"
|
|
|
|
#include "accountmanager.h"
|
|
|
|
#include "theme.h"
|
|
|
|
#include "configfile.h"
|
|
|
|
#include "capabilities.h"
|
2017-05-10 10:37:10 +03:00
|
|
|
#include "guiutility.h"
|
2015-11-01 00:21:09 +03:00
|
|
|
#include "thumbnailjob.h"
|
2015-11-02 00:23:22 +03:00
|
|
|
#include "sharee.h"
|
2016-09-14 16:31:05 +03:00
|
|
|
#include "sharemanager.h"
|
2015-11-01 00:21:09 +03:00
|
|
|
|
|
|
|
#include "QProgressIndicator.h"
|
|
|
|
#include <QBuffer>
|
|
|
|
#include <QFileIconProvider>
|
|
|
|
#include <QClipboard>
|
|
|
|
#include <QFileInfo>
|
2015-11-09 19:21:42 +03:00
|
|
|
#include <QAbstractProxyModel>
|
2015-11-02 00:23:22 +03:00
|
|
|
#include <QCompleter>
|
2015-11-16 19:59:24 +03:00
|
|
|
#include <qlayout.h>
|
2015-11-13 13:03:51 +03:00
|
|
|
#include <QPropertyAnimation>
|
2015-11-25 13:26:21 +03:00
|
|
|
#include <QMenu>
|
|
|
|
#include <QAction>
|
2017-05-10 10:37:10 +03:00
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QMessageBox>
|
2015-12-21 18:19:09 +03:00
|
|
|
#include <QCryptographicHash>
|
|
|
|
#include <QColor>
|
|
|
|
#include <QPainter>
|
2018-07-25 12:18:08 +03:00
|
|
|
#include <QListWidget>
|
2015-11-01 00:21:09 +03:00
|
|
|
|
|
|
|
namespace OCC {
|
|
|
|
|
2016-03-30 12:33:34 +03:00
|
|
|
ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account,
|
|
|
|
const QString &sharePath,
|
|
|
|
const QString &localPath,
|
|
|
|
SharePermissions maxSharingPermissions,
|
2017-09-15 15:24:34 +03:00
|
|
|
const QString &privateLinkUrl,
|
2016-03-30 12:33:34 +03:00
|
|
|
QWidget *parent)
|
2015-11-05 11:58:16 +03:00
|
|
|
: QWidget(parent)
|
|
|
|
, _ui(new Ui::ShareUserGroupWidget)
|
2015-11-01 00:21:09 +03:00
|
|
|
, _account(account)
|
|
|
|
, _sharePath(sharePath)
|
|
|
|
, _localPath(localPath)
|
2016-03-30 12:33:34 +03:00
|
|
|
, _maxSharingPermissions(maxSharingPermissions)
|
2017-09-15 15:24:34 +03:00
|
|
|
, _privateLinkUrl(privateLinkUrl)
|
2016-01-12 16:35:35 +03:00
|
|
|
, _disableCompleterActivated(false)
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
|
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
setObjectName("SharingDialogUG"); // required as group for saveGeometry call
|
|
|
|
|
|
|
|
_ui->setupUi(this);
|
|
|
|
|
|
|
|
//Is this a file or folder?
|
|
|
|
_isFile = QFileInfo(localPath).isFile();
|
|
|
|
|
2015-11-05 00:00:35 +03:00
|
|
|
_completer = new QCompleter(this);
|
2015-11-16 16:18:01 +03:00
|
|
|
_completerModel = new ShareeModel(_account,
|
|
|
|
_isFile ? QLatin1String("file") : QLatin1String("folder"),
|
|
|
|
_completer);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(_completerModel, &ShareeModel::shareesReady, this, &ShareUserGroupWidget::slotShareesReady);
|
|
|
|
connect(_completerModel, &ShareeModel::displayErrorMessage, this, &ShareUserGroupWidget::displayError);
|
2015-11-16 16:18:01 +03:00
|
|
|
|
|
|
|
_completer->setModel(_completerModel);
|
2015-12-10 16:56:15 +03:00
|
|
|
_completer->setCaseSensitivity(Qt::CaseInsensitive);
|
2016-05-26 01:52:33 +03:00
|
|
|
_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
2015-11-05 00:00:35 +03:00
|
|
|
_ui->shareeLineEdit->setCompleter(_completer);
|
|
|
|
|
2015-11-01 00:21:09 +03:00
|
|
|
_manager = new ShareManager(_account, this);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(_manager, &ShareManager::sharesFetched, this, &ShareUserGroupWidget::slotSharesFetched);
|
|
|
|
connect(_manager, &ShareManager::shareCreated, this, &ShareUserGroupWidget::getShares);
|
|
|
|
connect(_manager, &ShareManager::serverError, this, &ShareUserGroupWidget::displayError);
|
|
|
|
connect(_ui->shareeLineEdit, &QLineEdit::returnPressed, this, &ShareUserGroupWidget::slotLineEditReturn);
|
2018-11-16 23:11:55 +03:00
|
|
|
connect(_ui->confirmShare, &QAbstractButton::clicked, this, &ShareUserGroupWidget::slotLineEditReturn);
|
2018-08-02 19:15:18 +03:00
|
|
|
//TODO connect(_ui->privateLinkText, &QLabel::linkActivated, this, &ShareUserGroupWidget::slotPrivateLinkShare);
|
2015-12-10 16:56:15 +03:00
|
|
|
|
|
|
|
// By making the next two QueuedConnections we can override
|
|
|
|
// the strings the completer sets on the line edit.
|
|
|
|
connect(_completer, SIGNAL(activated(QModelIndex)), SLOT(slotCompleterActivated(QModelIndex)),
|
|
|
|
Qt::QueuedConnection);
|
|
|
|
connect(_completer, SIGNAL(highlighted(QModelIndex)), SLOT(slotCompleterHighlighted(QModelIndex)),
|
|
|
|
Qt::QueuedConnection);
|
2015-11-13 12:27:26 +03:00
|
|
|
|
2015-11-16 16:18:01 +03:00
|
|
|
// Queued connection so this signal is recieved after textChanged
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(_ui->shareeLineEdit, &QLineEdit::textEdited,
|
|
|
|
this, &ShareUserGroupWidget::slotLineEditTextEdited, Qt::QueuedConnection);
|
2018-03-15 21:43:26 +03:00
|
|
|
_ui->shareeLineEdit->installEventFilter(this);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(&_completionTimer, &QTimer::timeout, this, &ShareUserGroupWidget::searchForSharees);
|
2015-11-16 16:18:01 +03:00
|
|
|
_completionTimer.setSingleShot(true);
|
|
|
|
_completionTimer.setInterval(600);
|
2015-11-16 19:59:24 +03:00
|
|
|
|
2016-01-12 15:19:33 +03:00
|
|
|
_ui->errorLabel->hide();
|
2016-04-29 15:11:27 +03:00
|
|
|
|
2018-08-02 19:15:18 +03:00
|
|
|
// TODO Progress Indicator where should it go?
|
2016-04-29 15:11:27 +03:00
|
|
|
// Setup the sharee search progress indicator
|
2018-08-02 19:15:18 +03:00
|
|
|
//_ui->shareeHorizontalLayout->addWidget(&_pi_sharee);
|
2018-03-15 21:43:26 +03:00
|
|
|
|
2018-07-25 12:18:08 +03:00
|
|
|
_parentScrollArea = parentWidget()->findChild<QScrollArea*>("scrollArea");
|
2015-11-01 00:21:09 +03:00
|
|
|
}
|
|
|
|
|
2015-11-05 11:58:16 +03:00
|
|
|
ShareUserGroupWidget::~ShareUserGroupWidget()
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
|
|
|
delete _ui;
|
|
|
|
}
|
|
|
|
|
2015-11-17 12:24:35 +03:00
|
|
|
void ShareUserGroupWidget::on_shareeLineEdit_textChanged(const QString &)
|
2015-11-02 00:23:22 +03:00
|
|
|
{
|
2015-11-16 16:18:01 +03:00
|
|
|
_completionTimer.stop();
|
2018-03-15 21:43:26 +03:00
|
|
|
emit togglePublicLinkShare(false);
|
2015-11-02 00:23:22 +03:00
|
|
|
}
|
|
|
|
|
2015-11-16 16:18:01 +03:00
|
|
|
void ShareUserGroupWidget::slotLineEditTextEdited(const QString &text)
|
|
|
|
{
|
2016-01-12 16:35:35 +03:00
|
|
|
_disableCompleterActivated = false;
|
2015-11-16 16:18:01 +03:00
|
|
|
// First textChanged is called first and we stopped the timer when the text is changed, programatically or not
|
|
|
|
// Then we restart the timer here if the user touched a key
|
|
|
|
if (!text.isEmpty()) {
|
|
|
|
_completionTimer.start();
|
2018-03-15 21:43:26 +03:00
|
|
|
emit togglePublicLinkShare(true);
|
2015-11-16 16:18:01 +03:00
|
|
|
}
|
2015-12-10 15:49:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void ShareUserGroupWidget::slotLineEditReturn()
|
|
|
|
{
|
2016-01-12 16:35:35 +03:00
|
|
|
_disableCompleterActivated = false;
|
2015-12-10 15:49:47 +03:00
|
|
|
// did the user type in one of the options?
|
|
|
|
const auto text = _ui->shareeLineEdit->text();
|
|
|
|
for (int i = 0; i < _completerModel->rowCount(); ++i) {
|
|
|
|
const auto sharee = _completerModel->getSharee(i);
|
2015-12-10 16:56:15 +03:00
|
|
|
if (sharee->format() == text
|
|
|
|
|| sharee->displayName() == text
|
|
|
|
|| sharee->shareWith() == text) {
|
2015-12-10 15:49:47 +03:00
|
|
|
slotCompleterActivated(_completerModel->index(i));
|
2016-01-12 16:35:35 +03:00
|
|
|
// make sure we do not send the same item twice (because return is called when we press
|
|
|
|
// return to activate an item inthe completer)
|
|
|
|
_disableCompleterActivated = true;
|
|
|
|
return;
|
2015-12-10 15:49:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// nothing found? try to refresh completion
|
|
|
|
_completionTimer.start();
|
2015-11-16 16:18:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-17 12:24:35 +03:00
|
|
|
void ShareUserGroupWidget::searchForSharees()
|
2015-11-02 00:23:22 +03:00
|
|
|
{
|
2015-11-16 16:18:01 +03:00
|
|
|
_completionTimer.stop();
|
2016-04-29 15:11:27 +03:00
|
|
|
_pi_sharee.startAnimation();
|
2015-11-16 16:18:01 +03:00
|
|
|
ShareeModel::ShareeSet blacklist;
|
2015-11-05 17:01:29 +03:00
|
|
|
|
|
|
|
// Add the current user to _sharees since we can't share with ourself
|
|
|
|
QSharedPointer<Sharee> currentUser(new Sharee(_account->credentials()->user(), "", Sharee::Type::User));
|
2015-11-16 16:18:01 +03:00
|
|
|
blacklist << currentUser;
|
2015-11-05 17:01:29 +03:00
|
|
|
|
2018-07-25 12:18:08 +03:00
|
|
|
foreach (auto sw, _parentScrollArea->findChildren<ShareUserLine *>()) {
|
2015-11-16 19:59:24 +03:00
|
|
|
blacklist << sw->share()->getShareWith();
|
2015-11-05 17:01:29 +03:00
|
|
|
}
|
2016-01-12 16:35:35 +03:00
|
|
|
_ui->errorLabel->hide();
|
2015-11-16 16:18:01 +03:00
|
|
|
_completerModel->fetch(_ui->shareeLineEdit->text(), blacklist);
|
2015-11-02 00:23:22 +03:00
|
|
|
}
|
|
|
|
|
2015-11-05 11:58:16 +03:00
|
|
|
void ShareUserGroupWidget::getShares()
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
|
|
|
_manager->fetchShares(_sharePath);
|
|
|
|
}
|
|
|
|
|
2015-11-05 11:58:16 +03:00
|
|
|
void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
2018-08-02 16:30:23 +03:00
|
|
|
QScrollArea *scrollArea = _parentScrollArea;
|
|
|
|
|
|
|
|
auto newViewPort = new QWidget(scrollArea);
|
|
|
|
auto layout = new QVBoxLayout(newViewPort);
|
2018-11-15 22:28:55 +03:00
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
2018-08-02 16:30:23 +03:00
|
|
|
int x = 0;
|
2018-11-17 10:34:28 +03:00
|
|
|
int height = 0;
|
2018-08-02 16:30:23 +03:00
|
|
|
|
|
|
|
foreach (const auto &share, shares) {
|
2018-08-02 19:15:18 +03:00
|
|
|
// We don't handle link shares, only TypeUser or TypeGroup
|
2018-08-02 16:30:23 +03:00
|
|
|
if (share->getShareType() == Share::TypeLink) {
|
|
|
|
continue;
|
2017-11-21 15:04:09 +03:00
|
|
|
}
|
|
|
|
|
2018-08-02 16:30:23 +03:00
|
|
|
ShareUserLine *s = new ShareUserLine(share, _maxSharingPermissions, _isFile, _parentScrollArea);
|
|
|
|
connect(s, &ShareUserLine::resizeRequested, this, &ShareUserGroupWidget::slotAdjustScrollWidgetSize);
|
|
|
|
connect(s, &ShareUserLine::visualDeletionDone, this, &ShareUserGroupWidget::getShares);
|
|
|
|
s->setBackgroundRole(layout->count() % 2 == 0 ? QPalette::Base : QPalette::AlternateBase);
|
|
|
|
layout->addWidget(s);
|
|
|
|
|
|
|
|
x++;
|
|
|
|
if (x <= 3) {
|
2018-11-17 10:34:28 +03:00
|
|
|
height = newViewPort->sizeHint().height();
|
2017-11-21 15:04:09 +03:00
|
|
|
}
|
2018-08-02 16:30:23 +03:00
|
|
|
}
|
2015-11-16 19:59:24 +03:00
|
|
|
|
2018-11-17 10:34:28 +03:00
|
|
|
scrollArea->setVisible(!shares.isEmpty());
|
|
|
|
scrollArea->setFixedHeight(height);
|
2018-08-02 16:30:23 +03:00
|
|
|
scrollArea->setWidget(newViewPort);
|
2018-03-15 21:43:26 +03:00
|
|
|
|
2018-08-02 16:30:23 +03:00
|
|
|
_disableCompleterActivated = false;
|
|
|
|
_ui->shareeLineEdit->setEnabled(true);
|
2015-11-05 00:00:35 +03:00
|
|
|
}
|
|
|
|
|
2015-11-19 14:32:50 +03:00
|
|
|
void ShareUserGroupWidget::slotAdjustScrollWidgetSize()
|
|
|
|
{
|
2018-07-25 12:18:08 +03:00
|
|
|
QScrollArea *scrollArea = _parentScrollArea;
|
2018-11-17 10:34:28 +03:00
|
|
|
int count = scrollArea->findChildren<ShareUserLine *>().count();
|
|
|
|
scrollArea->setVisible(count > 0);
|
|
|
|
if (count > 0 && count <= 3) {
|
|
|
|
scrollArea->setFixedHeight(scrollArea->widget()->sizeHint().height());
|
2015-11-19 14:32:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-10 10:37:10 +03:00
|
|
|
void ShareUserGroupWidget::slotPrivateLinkShare()
|
|
|
|
{
|
|
|
|
auto menu = new QMenu(this);
|
|
|
|
menu->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
|
2018-08-02 16:30:23 +03:00
|
|
|
menu->addAction(QIcon(":/client/resources/copy.svg"),
|
|
|
|
tr("Copy link"),
|
2017-05-10 10:37:10 +03:00
|
|
|
this, SLOT(slotPrivateLinkCopy()));
|
|
|
|
|
|
|
|
menu->exec(QCursor::pos());
|
|
|
|
}
|
|
|
|
|
2015-11-16 16:18:01 +03:00
|
|
|
void ShareUserGroupWidget::slotShareesReady()
|
|
|
|
{
|
2016-04-29 15:11:27 +03:00
|
|
|
_pi_sharee.stopAnimation();
|
2016-01-12 16:35:35 +03:00
|
|
|
if (_completerModel->rowCount() == 0) {
|
|
|
|
displayError(0, tr("No results for '%1'").arg(_completerModel->currentSearch()));
|
|
|
|
return;
|
|
|
|
}
|
2015-11-16 16:18:01 +03:00
|
|
|
_completer->complete();
|
|
|
|
}
|
|
|
|
|
2015-11-09 19:21:42 +03:00
|
|
|
void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex &index)
|
|
|
|
{
|
2016-01-12 16:35:35 +03:00
|
|
|
if (_disableCompleterActivated)
|
|
|
|
return;
|
2015-11-09 19:21:42 +03:00
|
|
|
// The index is an index from the QCompletion model which is itelf a proxy
|
|
|
|
// model proxying the _completerModel
|
|
|
|
auto sharee = qvariant_cast<QSharedPointer<Sharee>>(index.data(Qt::UserRole));
|
2015-11-05 00:00:35 +03:00
|
|
|
if (sharee.isNull()) {
|
|
|
|
return;
|
|
|
|
}
|
2015-11-01 00:21:09 +03:00
|
|
|
|
2018-08-02 19:15:18 +03:00
|
|
|
// TODO Progress Indicator where should it go?
|
2018-03-15 21:43:26 +03:00
|
|
|
// auto indicator = new QProgressIndicator(viewPort);
|
|
|
|
// indicator->startAnimation();
|
|
|
|
// if (layout->count() == 1) {
|
|
|
|
// // No shares yet! Remove the label, add some stretch.
|
|
|
|
// delete layout->itemAt(0)->widget();
|
|
|
|
// layout->addStretch(1);
|
|
|
|
// }
|
|
|
|
// layout->insertWidget(layout->count() - 1, indicator);
|
2016-03-08 22:54:14 +03:00
|
|
|
|
2016-02-22 13:44:13 +03:00
|
|
|
/*
|
2016-06-27 12:09:51 +03:00
|
|
|
* Don't send the reshare permissions for federated shares for servers <9.1
|
2016-02-22 13:44:13 +03:00
|
|
|
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
2016-06-27 12:09:51 +03:00
|
|
|
* https://github.com/owncloud/client/issues/4996
|
2016-02-22 13:44:13 +03:00
|
|
|
*/
|
2016-06-27 12:09:51 +03:00
|
|
|
if (sharee->type() == Sharee::Federated
|
2017-03-14 17:57:57 +03:00
|
|
|
&& _account->serverVersionInt() < Account::makeServerVersion(9, 1, 0)) {
|
2016-03-30 12:33:34 +03:00
|
|
|
int permissions = SharePermissionRead | SharePermissionUpdate;
|
2016-02-22 13:44:13 +03:00
|
|
|
if (!_isFile) {
|
2016-03-30 12:33:34 +03:00
|
|
|
permissions |= SharePermissionCreate | SharePermissionDelete;
|
2016-02-22 13:44:13 +03:00
|
|
|
}
|
|
|
|
_manager->createShare(_sharePath, Share::ShareType(sharee->type()),
|
2016-03-30 12:33:34 +03:00
|
|
|
sharee->shareWith(), SharePermission(permissions));
|
2016-02-22 13:44:13 +03:00
|
|
|
} else {
|
2018-08-02 16:30:23 +03:00
|
|
|
|
|
|
|
// Default permissions on creation
|
|
|
|
int permissions = SharePermissionRead | SharePermissionUpdate;
|
2016-02-22 13:44:13 +03:00
|
|
|
_manager->createShare(_sharePath, Share::ShareType(sharee->type()),
|
2018-03-15 21:43:26 +03:00
|
|
|
sharee->shareWith(), SharePermission(permissions));
|
2016-02-22 13:44:13 +03:00
|
|
|
}
|
2015-11-05 15:16:52 +03:00
|
|
|
|
2016-02-22 17:14:05 +03:00
|
|
|
_ui->shareeLineEdit->setEnabled(false);
|
2015-11-05 15:16:52 +03:00
|
|
|
_ui->shareeLineEdit->setText(QString());
|
2015-11-01 00:21:09 +03:00
|
|
|
}
|
|
|
|
|
2015-12-10 16:56:15 +03:00
|
|
|
void ShareUserGroupWidget::slotCompleterHighlighted(const QModelIndex &index)
|
|
|
|
{
|
|
|
|
// By default the completer would set the text to EditRole,
|
|
|
|
// override that here.
|
|
|
|
_ui->shareeLineEdit->setText(index.data(Qt::DisplayRole).toString());
|
|
|
|
}
|
|
|
|
|
2016-01-12 15:19:33 +03:00
|
|
|
void ShareUserGroupWidget::displayError(int code, const QString &message)
|
|
|
|
{
|
2016-04-29 15:11:27 +03:00
|
|
|
_pi_sharee.stopAnimation();
|
2017-04-11 16:50:32 +03:00
|
|
|
|
|
|
|
// Also remove the spinner in the widget list, if any
|
2018-07-25 12:18:08 +03:00
|
|
|
foreach (auto pi, _parentScrollArea->findChildren<QProgressIndicator *>()) {
|
2017-04-11 16:50:32 +03:00
|
|
|
delete pi;
|
|
|
|
}
|
|
|
|
|
2017-03-30 14:46:20 +03:00
|
|
|
qCWarning(lcSharing) << "Sharing error from server" << code << message;
|
2016-01-12 15:19:33 +03:00
|
|
|
_ui->errorLabel->setText(message);
|
|
|
|
_ui->errorLabel->show();
|
2017-04-11 16:50:32 +03:00
|
|
|
_ui->shareeLineEdit->setEnabled(true);
|
2016-01-12 15:19:33 +03:00
|
|
|
}
|
|
|
|
|
2017-05-10 10:37:10 +03:00
|
|
|
void ShareUserGroupWidget::slotPrivateLinkOpenBrowser()
|
|
|
|
{
|
2017-09-15 15:24:34 +03:00
|
|
|
Utility::openBrowser(_privateLinkUrl, this);
|
2017-05-10 10:37:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void ShareUserGroupWidget::slotPrivateLinkCopy()
|
|
|
|
{
|
2017-09-15 15:24:34 +03:00
|
|
|
QApplication::clipboard()->setText(_privateLinkUrl);
|
2017-05-10 10:37:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void ShareUserGroupWidget::slotPrivateLinkEmail()
|
|
|
|
{
|
|
|
|
Utility::openEmailComposer(
|
|
|
|
tr("I shared something with you"),
|
2017-09-15 15:24:34 +03:00
|
|
|
_privateLinkUrl,
|
2017-05-10 10:37:10 +03:00
|
|
|
this);
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
ShareUserLine::ShareUserLine(QSharedPointer<Share> share,
|
|
|
|
SharePermissions maxSharingPermissions,
|
|
|
|
bool isFile,
|
|
|
|
QWidget *parent)
|
2015-11-01 00:21:09 +03:00
|
|
|
: QWidget(parent)
|
2017-04-04 16:05:08 +03:00
|
|
|
, _ui(new Ui::ShareUserLine)
|
2015-11-13 12:27:26 +03:00
|
|
|
, _share(share)
|
2015-11-25 13:26:21 +03:00
|
|
|
, _isFile(isFile)
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
|
|
|
_ui->setupUi(this);
|
|
|
|
|
2018-11-15 12:23:07 +03:00
|
|
|
_ui->sharedWith->setElideMode(Qt::ElideRight);
|
|
|
|
_ui->sharedWith->setText(share->getShareWith()->format());
|
2017-05-17 11:55:42 +03:00
|
|
|
|
2018-08-02 16:30:23 +03:00
|
|
|
// adds permissions
|
2018-08-02 17:42:06 +03:00
|
|
|
// can edit permission
|
2018-08-19 17:52:53 +03:00
|
|
|
bool enabled = (maxSharingPermissions & SharePermissionUpdate);
|
|
|
|
if(!_isFile) enabled = enabled && (maxSharingPermissions & SharePermissionCreate &&
|
|
|
|
maxSharingPermissions & SharePermissionDelete);
|
2018-08-02 17:42:06 +03:00
|
|
|
_ui->permissionsEdit->setEnabled(enabled);
|
2018-08-02 16:30:23 +03:00
|
|
|
connect(_ui->permissionsEdit, &QAbstractButton::clicked, this, &ShareUserLine::slotEditPermissionsChanged);
|
|
|
|
|
|
|
|
// create menu with checkable permissions
|
2015-11-25 13:26:21 +03:00
|
|
|
QMenu *menu = new QMenu(this);
|
2018-08-15 18:02:28 +03:00
|
|
|
_permissionReshare= new QAction(tr("Can reshare"), this);
|
2018-08-02 16:30:23 +03:00
|
|
|
_permissionReshare->setCheckable(true);
|
|
|
|
_permissionReshare->setEnabled(maxSharingPermissions & SharePermissionShare);
|
|
|
|
menu->addAction(_permissionReshare);
|
|
|
|
connect(_permissionReshare, &QAction::triggered, this, &ShareUserLine::slotPermissionsChanged);
|
|
|
|
|
2015-11-30 17:47:10 +03:00
|
|
|
/*
|
|
|
|
* Files can't have create or delete permissions
|
|
|
|
*/
|
2015-11-25 13:26:21 +03:00
|
|
|
if (!_isFile) {
|
2018-08-15 18:02:28 +03:00
|
|
|
_permissionCreate = new QAction(tr("Can create"), this);
|
2018-08-02 16:30:23 +03:00
|
|
|
_permissionCreate->setCheckable(true);
|
|
|
|
_permissionCreate->setEnabled(maxSharingPermissions & SharePermissionCreate);
|
2015-11-30 17:47:10 +03:00
|
|
|
menu->addAction(_permissionCreate);
|
2018-08-02 16:30:23 +03:00
|
|
|
connect(_permissionCreate, &QAction::triggered, this, &ShareUserLine::slotPermissionsChanged);
|
|
|
|
|
2018-08-15 18:02:28 +03:00
|
|
|
_permissionChange = new QAction(tr("Can change"), this);
|
2018-08-02 16:30:23 +03:00
|
|
|
_permissionChange->setCheckable(true);
|
|
|
|
_permissionChange->setEnabled(maxSharingPermissions & SharePermissionUpdate);
|
|
|
|
menu->addAction(_permissionChange);
|
|
|
|
connect(_permissionChange, &QAction::triggered, this, &ShareUserLine::slotPermissionsChanged);
|
|
|
|
|
2018-08-15 18:02:28 +03:00
|
|
|
_permissionDelete = new QAction(tr("Can delete"), this);
|
2018-08-02 16:30:23 +03:00
|
|
|
_permissionDelete->setCheckable(true);
|
|
|
|
_permissionDelete->setEnabled(maxSharingPermissions & SharePermissionDelete);
|
2015-11-25 13:26:21 +03:00
|
|
|
menu->addAction(_permissionDelete);
|
2018-08-02 16:30:23 +03:00
|
|
|
connect(_permissionDelete, &QAction::triggered, this, &ShareUserLine::slotPermissionsChanged);
|
2015-11-25 13:26:21 +03:00
|
|
|
}
|
2018-08-02 16:30:23 +03:00
|
|
|
|
2015-11-25 13:26:21 +03:00
|
|
|
_ui->permissionToolButton->setMenu(menu);
|
|
|
|
_ui->permissionToolButton->setPopupMode(QToolButton::InstantPopup);
|
2015-11-05 00:00:35 +03:00
|
|
|
|
2018-04-19 11:27:37 +03:00
|
|
|
QIcon icon(QLatin1String(":/client/resources/more.svg"));
|
2015-11-25 16:02:45 +03:00
|
|
|
_ui->permissionToolButton->setIcon(icon);
|
2015-11-05 00:00:35 +03:00
|
|
|
|
2015-11-13 12:27:26 +03:00
|
|
|
// Set the permissions checkboxes
|
|
|
|
displayPermissions();
|
|
|
|
|
2016-02-22 13:44:13 +03:00
|
|
|
/*
|
2018-08-02 16:30:23 +03:00
|
|
|
* We don't show permission share for federated shares with server <9.1
|
2016-02-22 13:44:13 +03:00
|
|
|
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
2016-06-27 12:09:51 +03:00
|
|
|
* https://github.com/owncloud/client/issues/4996
|
2016-02-22 13:44:13 +03:00
|
|
|
*/
|
2016-06-27 12:09:51 +03:00
|
|
|
if (share->getShareType() == Share::TypeRemote
|
2017-03-14 17:57:57 +03:00
|
|
|
&& share->account()->serverVersionInt() < Account::makeServerVersion(9, 1, 0)) {
|
2018-08-02 16:30:23 +03:00
|
|
|
_permissionReshare->setVisible(false);
|
2016-02-22 13:44:13 +03:00
|
|
|
_ui->permissionToolButton->setVisible(false);
|
|
|
|
}
|
|
|
|
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(share.data(), &Share::permissionsSet, this, &ShareUserLine::slotPermissionsSet);
|
|
|
|
connect(share.data(), &Share::shareDeleted, this, &ShareUserLine::slotShareDeleted);
|
2015-11-17 12:40:45 +03:00
|
|
|
|
|
|
|
_ui->deleteShareButton->setIcon(QIcon::fromTheme(QLatin1String("user-trash"),
|
2018-08-02 16:30:23 +03:00
|
|
|
QIcon(QLatin1String(":/client/resources/delete.png"))));
|
2015-12-08 14:58:56 +03:00
|
|
|
|
|
|
|
if (!share->account()->capabilities().shareResharing()) {
|
2018-08-02 16:30:23 +03:00
|
|
|
_permissionReshare->setVisible(false);
|
2015-12-08 14:58:56 +03:00
|
|
|
}
|
2015-12-21 18:19:09 +03:00
|
|
|
|
|
|
|
loadAvatar();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ShareUserLine::loadAvatar()
|
|
|
|
{
|
2017-11-21 15:59:51 +03:00
|
|
|
const int avatarSize = 36;
|
2015-12-21 18:19:09 +03:00
|
|
|
|
|
|
|
// Set size of the placeholder
|
2017-11-21 12:29:06 +03:00
|
|
|
_ui->avatar->setMinimumHeight(avatarSize);
|
|
|
|
_ui->avatar->setMinimumWidth(avatarSize);
|
|
|
|
_ui->avatar->setMaximumHeight(avatarSize);
|
|
|
|
_ui->avatar->setMaximumWidth(avatarSize);
|
2015-12-21 18:19:09 +03:00
|
|
|
_ui->avatar->setAlignment(Qt::AlignCenter);
|
|
|
|
|
2017-11-21 12:29:06 +03:00
|
|
|
/* Create the fallback avatar.
|
|
|
|
*
|
|
|
|
* This will be shown until the avatar image data arrives.
|
2015-12-21 18:19:09 +03:00
|
|
|
*/
|
2017-11-21 15:59:51 +03:00
|
|
|
const QByteArray hash = QCryptographicHash::hash(_ui->sharedWith->text().toUtf8(), QCryptographicHash::Md5);
|
|
|
|
double hue = static_cast<quint8>(hash[0]) / 255.;
|
|
|
|
|
|
|
|
// See core/js/placeholder.js for details on colors and styling
|
|
|
|
const QColor bg = QColor::fromHslF(hue, 0.7, 0.68);
|
|
|
|
const QString style = QString(R"(* {
|
|
|
|
color: #fff;
|
|
|
|
background-color: %1;
|
|
|
|
border-radius: %2px;
|
|
|
|
text-align: center;
|
|
|
|
line-height: %2px;
|
|
|
|
font-size: %2px;
|
|
|
|
})").arg(bg.name(), QString::number(avatarSize / 2));
|
2015-12-21 18:19:09 +03:00
|
|
|
_ui->avatar->setStyleSheet(style);
|
|
|
|
|
2017-11-21 12:29:06 +03:00
|
|
|
// The avatar label is the first character of the user name.
|
|
|
|
const QString text = _share->getShareWith()->displayName();
|
2015-12-21 18:19:09 +03:00
|
|
|
_ui->avatar->setText(text.at(0).toUpper());
|
|
|
|
|
2017-11-21 12:29:06 +03:00
|
|
|
/* Start the network job to fetch the avatar data.
|
|
|
|
*
|
|
|
|
* Currently only regular users can have avatars.
|
|
|
|
*/
|
2015-12-21 18:19:09 +03:00
|
|
|
if (_share->getShareWith()->type() == Sharee::User) {
|
2017-11-21 12:29:06 +03:00
|
|
|
AvatarJob *job = new AvatarJob(_share->account(), _share->getShareWith()->shareWith(), avatarSize, this);
|
2017-11-21 12:18:15 +03:00
|
|
|
connect(job, &AvatarJob::avatarPixmap, this, &ShareUserLine::slotAvatarLoaded);
|
2015-12-21 18:19:09 +03:00
|
|
|
job->start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-21 12:18:15 +03:00
|
|
|
void ShareUserLine::slotAvatarLoaded(QImage avatar)
|
2015-12-21 18:19:09 +03:00
|
|
|
{
|
2017-11-21 12:18:15 +03:00
|
|
|
if (avatar.isNull())
|
|
|
|
return;
|
2015-12-21 18:19:09 +03:00
|
|
|
|
2017-11-21 12:18:15 +03:00
|
|
|
avatar = AvatarJob::makeCircularAvatar(avatar);
|
|
|
|
_ui->avatar->setPixmap(QPixmap::fromImage(avatar));
|
|
|
|
|
|
|
|
// Remove the stylesheet for the fallback avatar
|
|
|
|
_ui->avatar->setStyleSheet("");
|
2015-11-01 00:21:09 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
void ShareUserLine::on_deleteShareButton_clicked()
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
|
|
|
setEnabled(false);
|
|
|
|
_share->deleteShare();
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
ShareUserLine::~ShareUserLine()
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
|
|
|
delete _ui;
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
void ShareUserLine::slotEditPermissionsChanged()
|
2015-11-13 12:27:26 +03:00
|
|
|
{
|
|
|
|
setEnabled(false);
|
|
|
|
|
2017-03-22 15:22:22 +03:00
|
|
|
// Can never manually be set to "partial".
|
|
|
|
// This works because the state cycle for clicking is
|
|
|
|
// unchecked -> partial -> checked -> unchecked.
|
|
|
|
if (_ui->permissionsEdit->checkState() == Qt::PartiallyChecked) {
|
|
|
|
_ui->permissionsEdit->setCheckState(Qt::Checked);
|
|
|
|
}
|
|
|
|
|
2016-03-30 12:33:34 +03:00
|
|
|
Share::Permissions permissions = SharePermissionRead;
|
2015-11-13 12:27:26 +03:00
|
|
|
|
2018-08-19 17:52:53 +03:00
|
|
|
// folders edit = CREATE, READ, UPDATE, DELETE
|
|
|
|
// files edit = READ + UPDATE
|
2015-11-13 12:27:26 +03:00
|
|
|
if (_ui->permissionsEdit->checkState() == Qt::Checked) {
|
2015-11-25 13:26:21 +03:00
|
|
|
|
2015-11-30 17:47:10 +03:00
|
|
|
/*
|
|
|
|
* Files can't have create or delete permisisons
|
|
|
|
*/
|
2015-11-25 13:26:21 +03:00
|
|
|
if (!_isFile) {
|
2018-08-19 17:52:53 +03:00
|
|
|
if (_permissionChange->isEnabled())
|
|
|
|
permissions |= SharePermissionUpdate;
|
2016-03-30 12:33:34 +03:00
|
|
|
if (_permissionCreate->isEnabled())
|
|
|
|
permissions |= SharePermissionCreate;
|
|
|
|
if (_permissionDelete->isEnabled())
|
|
|
|
permissions |= SharePermissionDelete;
|
2018-08-19 17:52:53 +03:00
|
|
|
} else {
|
|
|
|
permissions |= SharePermissionUpdate;
|
2015-11-25 13:26:21 +03:00
|
|
|
}
|
2015-11-13 12:27:26 +03:00
|
|
|
}
|
|
|
|
|
2018-08-19 17:52:53 +03:00
|
|
|
if(_isFile && _permissionReshare->isEnabled() && _permissionReshare->isChecked())
|
|
|
|
permissions |= SharePermissionShare;
|
|
|
|
|
2015-11-13 12:27:26 +03:00
|
|
|
_share->setPermissions(permissions);
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
void ShareUserLine::slotPermissionsChanged()
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
|
|
|
setEnabled(false);
|
2017-05-17 11:55:42 +03:00
|
|
|
|
2016-03-30 12:33:34 +03:00
|
|
|
Share::Permissions permissions = SharePermissionRead;
|
2015-11-01 00:21:09 +03:00
|
|
|
|
2018-08-19 17:52:53 +03:00
|
|
|
if (_permissionReshare->isChecked())
|
2018-08-02 17:42:06 +03:00
|
|
|
permissions |= SharePermissionShare;
|
2015-11-01 00:21:09 +03:00
|
|
|
|
2018-08-02 17:42:06 +03:00
|
|
|
if (!_isFile) {
|
2018-08-19 17:52:53 +03:00
|
|
|
if (_permissionChange->isChecked())
|
2018-08-02 17:42:06 +03:00
|
|
|
permissions |= SharePermissionUpdate;
|
2018-08-19 17:52:53 +03:00
|
|
|
if (_permissionCreate->isChecked())
|
|
|
|
permissions |= SharePermissionCreate;
|
|
|
|
if (_permissionDelete->isChecked())
|
2018-08-02 17:42:06 +03:00
|
|
|
permissions |= SharePermissionDelete;
|
2018-08-19 17:52:53 +03:00
|
|
|
} else {
|
|
|
|
if (_ui->permissionsEdit->isChecked())
|
|
|
|
permissions |= SharePermissionUpdate;
|
|
|
|
}
|
2015-11-01 00:21:09 +03:00
|
|
|
|
|
|
|
_share->setPermissions(permissions);
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
void ShareUserLine::slotDeleteAnimationFinished()
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
2017-04-04 15:41:25 +03:00
|
|
|
emit resizeRequested();
|
|
|
|
emit visualDeletionDone();
|
2015-11-01 00:21:09 +03:00
|
|
|
deleteLater();
|
2015-11-25 12:09:17 +03:00
|
|
|
|
|
|
|
// There is a painting bug where a small line of this widget isn't
|
|
|
|
// properly cleared. This explicit repaint() call makes sure any trace of
|
|
|
|
// the share widget is removed once it's destroyed. #4189
|
|
|
|
connect(this, SIGNAL(destroyed(QObject *)), parentWidget(), SLOT(repaint()));
|
2015-11-01 00:21:09 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
void ShareUserLine::slotShareDeleted()
|
2015-11-13 13:03:51 +03:00
|
|
|
{
|
|
|
|
QPropertyAnimation *animation = new QPropertyAnimation(this, "maximumHeight", this);
|
|
|
|
|
|
|
|
animation->setDuration(500);
|
|
|
|
animation->setStartValue(height());
|
|
|
|
animation->setEndValue(0);
|
|
|
|
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(animation, &QAbstractAnimation::finished, this, &ShareUserLine::slotDeleteAnimationFinished);
|
|
|
|
connect(animation, &QVariantAnimation::valueChanged, this, &ShareUserLine::resizeRequested);
|
2015-11-13 13:03:51 +03:00
|
|
|
|
|
|
|
animation->start();
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
void ShareUserLine::slotPermissionsSet()
|
2015-11-01 00:21:09 +03:00
|
|
|
{
|
2015-11-13 12:27:26 +03:00
|
|
|
displayPermissions();
|
2015-11-01 00:21:09 +03:00
|
|
|
setEnabled(true);
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
QSharedPointer<Share> ShareUserLine::share() const
|
2015-11-05 17:01:29 +03:00
|
|
|
{
|
|
|
|
return _share;
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:05:08 +03:00
|
|
|
void ShareUserLine::displayPermissions()
|
2015-11-13 12:27:26 +03:00
|
|
|
{
|
2017-03-22 15:22:22 +03:00
|
|
|
auto perm = _share->getPermissions();
|
|
|
|
|
2018-08-19 17:52:53 +03:00
|
|
|
// folders edit = CREATE, READ, UPDATE, DELETE
|
|
|
|
// files edit = READ + UPDATE
|
|
|
|
if (perm & SharePermissionUpdate && (_isFile ||
|
|
|
|
(perm & SharePermissionCreate && perm & SharePermissionDelete))) {
|
2015-11-13 12:27:26 +03:00
|
|
|
_ui->permissionsEdit->setCheckState(Qt::Checked);
|
2018-08-19 17:52:53 +03:00
|
|
|
} else if (!_isFile && perm & (SharePermissionUpdate | SharePermissionCreate | SharePermissionDelete)) {
|
2017-03-22 15:22:22 +03:00
|
|
|
_ui->permissionsEdit->setCheckState(Qt::PartiallyChecked);
|
2018-08-19 17:52:53 +03:00
|
|
|
} else if(perm & SharePermissionRead) {
|
2017-03-22 15:22:22 +03:00
|
|
|
_ui->permissionsEdit->setCheckState(Qt::Unchecked);
|
2015-11-13 12:27:26 +03:00
|
|
|
}
|
2017-03-22 15:22:22 +03:00
|
|
|
|
2018-08-19 17:52:53 +03:00
|
|
|
// edit is independent of reshare
|
|
|
|
if (perm & SharePermissionShare)
|
2018-11-01 12:26:19 +03:00
|
|
|
_permissionReshare->setChecked(true);
|
2018-08-02 16:30:23 +03:00
|
|
|
|
|
|
|
if(!_isFile){
|
|
|
|
_permissionCreate->setChecked(perm & SharePermissionCreate);
|
|
|
|
_permissionChange->setChecked(perm & SharePermissionUpdate);
|
|
|
|
_permissionDelete->setChecked(perm & SharePermissionDelete);
|
2015-11-13 12:27:26 +03:00
|
|
|
}
|
|
|
|
}
|
2015-11-01 00:21:09 +03:00
|
|
|
}
|