Refactores sharing link to support multiple share links.

Signed-off-by: Camila San <hello@camila.codes>
This commit is contained in:
Camila San 2019-04-06 20:15:24 +02:00
parent 0fed1cc54d
commit e07c472057
No known key found for this signature in database
GPG Key ID: 7A4A6121E88E2AD4
7 changed files with 361 additions and 295 deletions

View File

@ -37,6 +37,7 @@
<file>resources/confirm.svg</file> <file>resources/confirm.svg</file>
<file>resources/copy.svg</file> <file>resources/copy.svg</file>
<file>resources/state-sync.svg</file> <file>resources/state-sync.svg</file>
<file>resources/add.png</file>
</qresource> </qresource>
<qresource prefix="/"/> <qresource prefix="/"/>
</RCC> </RCC>

BIN
resources/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -18,6 +18,8 @@
#include "sharelinkwidget.h" #include "sharelinkwidget.h"
#include "shareusergroupwidget.h" #include "shareusergroupwidget.h"
#include "sharemanager.h"
#include "account.h" #include "account.h"
#include "accountstate.h" #include "accountstate.h"
#include "configfile.h" #include "configfile.h"
@ -49,7 +51,8 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
, _maxSharingPermissions(maxSharingPermissions) , _maxSharingPermissions(maxSharingPermissions)
, _privateLinkUrl(accountState->account()->deprecatedPrivateLinkUrl(numericFileId).toString(QUrl::FullyEncoded)) , _privateLinkUrl(accountState->account()->deprecatedPrivateLinkUrl(numericFileId).toString(QUrl::FullyEncoded))
, _startPage(startPage) , _startPage(startPage)
, _linkWidget(nullptr) , _linkWidgetList({})
, _emptyShareLinkWidget(nullptr)
, _userGroupWidget(nullptr) , _userGroupWidget(nullptr)
, _progressIndicator(nullptr) , _progressIndicator(nullptr)
{ {
@ -101,11 +104,6 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
this->setWindowTitle(tr("%1 Sharing").arg(Theme::instance()->appNameGUI())); this->setWindowTitle(tr("%1 Sharing").arg(Theme::instance()->appNameGUI()));
if (!accountState->account()->capabilities().shareAPI()) { if (!accountState->account()->capabilities().shareAPI()) {
// TODO do we want to display it?
//auto label = new QLabel(tr("The server does not allow sharing"));
//label->setWordWrap(true);
//label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
//layout()->replaceWidget(_ui->shareWidgets, label);
return; return;
} }
@ -115,14 +113,6 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
job->start(); job->start();
} }
//TODO Progress Indicator where should it go?
// _progressIndicator = new QProgressIndicator(this);
// _progressIndicator->startAnimation();
// _progressIndicator->setToolTip(tr("Retrieving maximum possible sharing permissions from server..."));
// _ui->buttonBoxLayout->insertWidget(0, _progressIndicator);
// Server versions >= 9.1 support the "share-permissions" property
// older versions will just return share-permissions: ""
auto job = new PropfindJob(accountState->account(), _sharePath); auto job = new PropfindJob(accountState->account(), _sharePath);
job->setProperties( job->setProperties(
QList<QByteArray>() QList<QByteArray>()
@ -133,6 +123,98 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
connect(job, &PropfindJob::result, this, &ShareDialog::slotPropfindReceived); connect(job, &PropfindJob::result, this, &ShareDialog::slotPropfindReceived);
connect(job, &PropfindJob::finishedWithError, this, &ShareDialog::slotPropfindError); connect(job, &PropfindJob::finishedWithError, this, &ShareDialog::slotPropfindError);
job->start(); job->start();
bool sharingPossible = true;
if (!accountState->account()->capabilities().sharePublicLink()) {
qCWarning(lcSharing) << "Link shares have been disabled";
sharingPossible = false;
} else if (!(maxSharingPermissions & SharePermissionShare)) {
qCWarning(lcSharing) << "The file can not be shared because it was shared without sharing permission.";
sharingPossible = false;
}
if (sharingPossible) {
_manager = new ShareManager(accountState->account(), this);
connect(_manager, &ShareManager::sharesFetched, this, &ShareDialog::slotSharesFetched);
connect(_manager, &ShareManager::linkShareCreated, this, &ShareDialog::slotAddLinkShareWidget);
}
}
void ShareDialog::addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare){
_linkWidgetList.append(new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this));
int index = _linkWidgetList.size()-1;
_linkWidgetList.at(index)->setLinkShare(linkShare);
connect(linkShare.data(), &Share::serverError, _linkWidgetList.at(index), &ShareLinkWidget::slotServerError);
connect(linkShare.data(), &Share::shareDeleted, _linkWidgetList.at(index), &ShareLinkWidget::slotDeleteShareFetched);
connect(_manager, &ShareManager::linkShareRequiresPassword, _linkWidgetList.at(index), &ShareLinkWidget::slotCreateShareRequiresPassword);
connect(_manager, &ShareManager::serverError, _linkWidgetList.at(index), &ShareLinkWidget::slotServerError);
// Connect all shares signals to gui slots
connect(this, &ShareDialog::toggleAnimation, _linkWidgetList.at(index), &ShareLinkWidget::slotToggleAnimation);
connect(_linkWidgetList.at(index), &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
connect(_linkWidgetList.at(index), &ShareLinkWidget::deleteLinkShare, this, &ShareDialog::slotDeleteShare);
//connect(_linkWidgetList.at(index), &ShareLinkWidget::resizeRequested, this, &ShareDialog::slotAdjustScrollWidgetSize);
_ui->verticalLayout->insertWidget(_linkWidgetList.size()+1, _linkWidgetList.at(index));
_linkWidgetList.at(index)->setupUiOptions();
}
void ShareDialog::initLinkShareWidget(){
if(_linkWidgetList.size() == 0){
_emptyShareLinkWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this);
_linkWidgetList.append(_emptyShareLinkWidget);
// connect(_emptyShareLinkWidget, &ShareLinkWidget::resizeRequested, this, &ShareDialog::slotAdjustScrollWidgetSize);
// connect(this, &ShareDialog::toggleAnimation, _emptyShareLinkWidget, &ShareLinkWidget::slotToggleAnimation);
connect(_emptyShareLinkWidget, &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
_ui->verticalLayout->insertWidget(_linkWidgetList.size()+1, _emptyShareLinkWidget);
_emptyShareLinkWidget->show();
} else if(_emptyShareLinkWidget) {
_emptyShareLinkWidget->hide();
_ui->verticalLayout->removeWidget(_emptyShareLinkWidget);
_linkWidgetList.removeAll(_emptyShareLinkWidget);
_emptyShareLinkWidget = nullptr;
}
}
void ShareDialog::slotAddLinkShareWidget(const QSharedPointer<LinkShare> &linkShare){
emit toggleAnimation(true);
addLinkShareWidget(linkShare);
initLinkShareWidget();
emit toggleAnimation(false);
}
void ShareDialog::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
{
emit toggleAnimation(true);
const QString versionString = _accountState->account()->serverVersion();
qCInfo(lcSharing) << versionString << "Fetched" << shares.count() << "shares";
foreach (auto share, shares) {
if (share->getShareType() != Share::TypeLink) {
continue;
}
QSharedPointer<LinkShare> linkShare = qSharedPointerDynamicCast<LinkShare>(share);
addLinkShareWidget(linkShare);
}
initLinkShareWidget();
emit toggleAnimation(false);
}
// TODO
void ShareDialog::slotAdjustScrollWidgetSize()
{
int count = this->findChildren<ShareLinkWidget *>().count();
_ui->scrollArea->setVisible(count > 0);
if (count > 0 && count <= 3) {
_ui->scrollArea->setFixedHeight(_ui->scrollArea->widget()->sizeHint().height());
}
_ui->scrollArea->setFrameShape(count > 3 ? QFrame::StyledPanel : QFrame::NoFrame);
} }
ShareDialog::~ShareDialog() ShareDialog::~ShareDialog()
@ -178,8 +260,6 @@ void ShareDialog::slotPropfindError()
void ShareDialog::showSharingUi() void ShareDialog::showSharingUi()
{ {
//_progressIndicator->stopAnimation();
auto theme = Theme::instance(); auto theme = Theme::instance();
// There's no difference between being unable to reshare and // There's no difference between being unable to reshare and
@ -205,15 +285,25 @@ void ShareDialog::showSharingUi()
} }
if (theme->linkSharing()) { if (theme->linkSharing()) {
_linkWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this); _manager->fetchShares(_sharePath);
_ui->verticalLayout->insertWidget(2, _linkWidget);
_linkWidget->getShares();
if (_startPage == ShareDialogStartPage::PublicLinks)
_ui->verticalLayout->insertWidget(3, _linkWidget);
} }
} }
void ShareDialog::slotCreateLinkShare()
{
_manager->createLinkShare(_sharePath, QString(), QString());
}
void ShareDialog::slotDeleteShare()
{
auto sharelinkWidget = dynamic_cast<ShareLinkWidget*>(sender());
sharelinkWidget->hide();
_ui->verticalLayout->removeWidget(sharelinkWidget);
_linkWidgetList.removeAll(sharelinkWidget);
initLinkShareWidget();
}
void ShareDialog::slotThumbnailFetched(const int &statusCode, const QByteArray &reply) void ShareDialog::slotThumbnailFetched(const int &statusCode, const QByteArray &reply)
{ {
if (statusCode != 200) { if (statusCode != 200) {
@ -237,8 +327,6 @@ void ShareDialog::slotAccountStateChanged(int state)
_userGroupWidget->setEnabled(enabled); _userGroupWidget->setEnabled(enabled);
} }
if (_linkWidget != nullptr) {
_linkWidget->setEnabled(enabled);
}
} }
} }

View File

@ -19,6 +19,7 @@
#include "sharepermissions.h" #include "sharepermissions.h"
#include "owncloudgui.h" #include "owncloudgui.h"
#include <QSharedPointer>
#include <QPointer> #include <QPointer>
#include <QString> #include <QString>
#include <QDialog> #include <QDialog>
@ -34,6 +35,9 @@ namespace Ui {
class ShareLinkWidget; class ShareLinkWidget;
class ShareUserGroupWidget; class ShareUserGroupWidget;
class ShareManager;
class LinkShare;
class Share;
class ShareDialog : public QDialog class ShareDialog : public QDialog
{ {
@ -56,8 +60,19 @@ private slots:
void slotThumbnailFetched(const int &statusCode, const QByteArray &reply); void slotThumbnailFetched(const int &statusCode, const QByteArray &reply);
void slotAccountStateChanged(int state); void slotAccountStateChanged(int state);
void slotSharesFetched(const QList<QSharedPointer<Share>> &shares);
void slotAddLinkShareWidget(const QSharedPointer<LinkShare> &linkShare);
void slotDeleteShare();
void slotCreateLinkShare();
void slotAdjustScrollWidgetSize();
signals:
void toggleAnimation(bool);
private: private:
void showSharingUi(); void showSharingUi();
void addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare);
void initLinkShareWidget();
Ui::ShareDialog *_ui; Ui::ShareDialog *_ui;
@ -68,8 +83,10 @@ private:
QByteArray _numericFileId; QByteArray _numericFileId;
QString _privateLinkUrl; QString _privateLinkUrl;
ShareDialogStartPage _startPage; ShareDialogStartPage _startPage;
ShareManager *_manager;
ShareLinkWidget *_linkWidget; QList<ShareLinkWidget*> _linkWidgetList;
ShareLinkWidget* _emptyShareLinkWidget;
ShareUserGroupWidget *_userGroupWidget; ShareUserGroupWidget *_userGroupWidget;
QProgressIndicator *_progressIndicator; QProgressIndicator *_progressIndicator;
}; };

View File

@ -17,9 +17,8 @@
#include "sharelinkwidget.h" #include "sharelinkwidget.h"
#include "account.h" #include "account.h"
#include "capabilities.h" #include "capabilities.h"
#include "sharemanager.h"
#include "guiutility.h" #include "guiutility.h"
#include "sharemanager.h"
#include "QProgressIndicator.h" #include "QProgressIndicator.h"
#include <QBuffer> #include <QBuffer>
@ -29,9 +28,12 @@
#include <QMessageBox> #include <QMessageBox>
#include <QMenu> #include <QMenu>
#include <QToolButton> #include <QToolButton>
#include <QPropertyAnimation>
namespace OCC { namespace OCC {
Q_LOGGING_CATEGORY(lcShareLink, "nextcloud.gui.sharelink", QtInfoMsg)
ShareLinkWidget::ShareLinkWidget(AccountPtr account, ShareLinkWidget::ShareLinkWidget(AccountPtr account,
const QString &sharePath, const QString &sharePath,
const QString &localPath, const QString &localPath,
@ -42,13 +44,11 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
, _account(account) , _account(account)
, _sharePath(sharePath) , _sharePath(sharePath)
, _localPath(localPath) , _localPath(localPath)
, _manager(nullptr)
, _linkShare(nullptr) , _linkShare(nullptr)
, _passwordRequired(false) , _passwordRequired(false)
, _expiryRequired(false) , _expiryRequired(false)
, _namesSupported(true) , _namesSupported(true)
, _linkContextMenu(nullptr) , _linkContextMenu(nullptr)
, _copyLinkAction(nullptr)
, _readOnlyLinkAction(nullptr) , _readOnlyLinkAction(nullptr)
, _allowEditingLinkAction(nullptr) , _allowEditingLinkAction(nullptr)
, _allowUploadEditingLinkAction(nullptr) , _allowUploadEditingLinkAction(nullptr)
@ -68,26 +68,26 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
QFileInfo fi(localPath); QFileInfo fi(localPath);
_isFile = fi.isFile(); _isFile = fi.isFile();
connect(_ui->enableShareLink, &QCheckBox::clicked, this, &ShareLinkWidget::slotCreateOrDeleteShareLink); connect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCreateShareLink);
connect(_ui->lineEdit_password, &QLineEdit::returnPressed, this, &ShareLinkWidget::slotCreatePassword); connect(_ui->lineEdit_password, &QLineEdit::returnPressed, this, &ShareLinkWidget::slotCreatePassword);
connect(_ui->confirmPassword, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreatePassword); connect(_ui->confirmPassword, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreatePassword);
connect(_ui->confirmExpirationDate, &QAbstractButton::clicked, this, &ShareLinkWidget::slotSetExpireDate); connect(_ui->confirmExpirationDate, &QAbstractButton::clicked, this, &ShareLinkWidget::slotSetExpireDate);
connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareLinkWidget::slotExpireDateChanged); connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareLinkWidget::slotSetExpireDate);
_ui->errorLabel->hide(); _ui->errorLabel->hide();
bool sharingPossible = true; bool sharingPossible = true;
if (!_account->capabilities().sharePublicLink()) { if (!_account->capabilities().sharePublicLink()) {
qCWarning(lcSharing) << "Link shares have been disabled"; qCWarning(lcShareLink) << "Link shares have been disabled";
sharingPossible = false; sharingPossible = false;
} else if (!(maxSharingPermissions & SharePermissionShare)) { } else if (!(maxSharingPermissions & SharePermissionShare)) {
qCWarning(lcSharing) << "The file can not be shared because it was shared without sharing permission."; qCWarning(lcShareLink) << "The file can not be shared because it was shared without sharing permission.";
sharingPossible = false; sharingPossible = false;
} }
_ui->createShareButton->setVisible(sharingPossible); _ui->enableShareLink->setChecked(false);
_ui->enableShareLink->setVisible(sharingPossible); _ui->shareLinkToolButton->setEnabled(false);
_ui->shareLinkToolButton->setVisible(sharingPossible); _ui->shareLinkToolButton->hide();
// Older servers don't support multiple public link shares // Older servers don't support multiple public link shares
if (!_account->capabilities().sharePublicLinkMultiple()) { if (!_account->capabilities().sharePublicLinkMultiple()) {
@ -100,34 +100,9 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
// check if the file is already inside of a synced folder // check if the file is already inside of a synced folder
if (sharePath.isEmpty()) { if (sharePath.isEmpty()) {
// The file is not yet in an ownCloud synced folder. We could automatically qCWarning(lcShareLink) << "Unable to share files not in a sync folder.";
// copy it over, but that is skipped as not all questions can be answered that
// are involved in that, see https://github.com/owncloud/client/issues/2732
//
// _ui->checkBox_shareLink->setEnabled(false);
// uploadExternalFile();
qCWarning(lcSharing) << "Unable to share files not in a sync folder.";
return; return;
} }
// TODO File Drop
// File can't have public upload set; we also hide it if the capability isn't there
// _ui->widget_editing->setVisible(
// !_isFile && _account->capabilities().sharePublicLinkAllowUpload());
//_ui->radio_uploadOnly->setVisible(
//_account->capabilities().sharePublicLinkSupportsUploadOnly());
/*
* Create the share manager and connect it properly
*/
if (sharingPossible) {
_manager = new ShareManager(_account, this);
connect(_manager, &ShareManager::sharesFetched, this, &ShareLinkWidget::slotSharesFetched);
connect(_manager, &ShareManager::linkShareCreated, this, &ShareLinkWidget::slotCreateShareFetched);
connect(_manager, &ShareManager::linkShareRequiresPassword, this, &ShareLinkWidget::slotCreateShareRequiresPassword);
connect(_manager, &ShareManager::serverError, this, &ShareLinkWidget::slotServerError);
}
} }
ShareLinkWidget::~ShareLinkWidget() ShareLinkWidget::~ShareLinkWidget()
@ -135,7 +110,7 @@ ShareLinkWidget::~ShareLinkWidget()
delete _ui; delete _ui;
} }
void ShareLinkWidget::toggleAnimation(bool start){ void ShareLinkWidget::slotToggleAnimation(bool start){
if (start) { if (start) {
if (!_ui->progressIndicator->isAnimated()) if (!_ui->progressIndicator->isAnimated())
_ui->progressIndicator->startAnimation(); _ui->progressIndicator->startAnimation();
@ -144,218 +119,170 @@ void ShareLinkWidget::toggleAnimation(bool start){
} }
} }
void ShareLinkWidget::getShares() void ShareLinkWidget::setLinkShare(QSharedPointer<LinkShare> linkShare){
{ _linkShare = linkShare;
if (_manager) {
toggleAnimation(true);
_manager->fetchShares(_sharePath);
}
} }
void ShareLinkWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shares) QSharedPointer<LinkShare> ShareLinkWidget::getLinkShare(){
{ return _linkShare;
const QString versionString = _account->serverVersion();
qCInfo(lcSharing) << versionString << "Fetched" << shares.count() << "shares";
foreach (auto share, shares) {
if (share->getShareType() != Share::TypeLink) {
continue;
}
_linkShare = qSharedPointerDynamicCast<LinkShare>(share);
// Connect all shares signals to gui slots
connect(share.data(), &Share::serverError, this, &ShareLinkWidget::slotServerError);
connect(share.data(), &Share::shareDeleted, this, &ShareLinkWidget::slotDeleteShareFetched);
connect(_linkShare.data(), &LinkShare::expireDateSet, this, &ShareLinkWidget::slotExpireDateSet);
connect(_linkShare.data(), &LinkShare::passwordSet, this, &ShareLinkWidget::slotPasswordSet);
connect(_linkShare.data(), &LinkShare::passwordSetError, this, &ShareLinkWidget::slotPasswordSetError);
// Prepare permissions check and create group action
bool checked = false;
SharePermissions perm = _linkShare->getPermissions();
QActionGroup *permissionsGroup = new QActionGroup(this);
// Prepare sharing menu
_linkContextMenu = new QMenu(this);
// radio button style
permissionsGroup->setExclusive(true);
if(_isFile){
checked = perm & (SharePermissionRead & SharePermissionUpdate);
_allowEditingLinkAction = _linkContextMenu->addAction(tr("Allow Editing"));
_allowEditingLinkAction->setCheckable(true);
_allowEditingLinkAction->setChecked(checked);
} else {
checked = perm & SharePermissionRead;
_readOnlyLinkAction = permissionsGroup->addAction(tr("Read only"));
_readOnlyLinkAction->setCheckable(true);
_readOnlyLinkAction->setChecked(checked);
checked = perm & (SharePermissionRead &
SharePermissionCreate &
SharePermissionUpdate &
SharePermissionDelete);
_allowUploadEditingLinkAction = permissionsGroup->addAction(tr("Allow Upload && Editing"));
_allowUploadEditingLinkAction->setCheckable(true);
_allowUploadEditingLinkAction->setChecked(checked);
checked = perm & SharePermissionCreate;
_allowUploadLinkAction = permissionsGroup->addAction(tr("File Drop (Upload Only)"));
_allowUploadLinkAction->setCheckable(true);
_allowUploadLinkAction->setChecked(checked);
}
// Add copy action (icon only)
_copyLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/copy.svg"),
tr("Copy link"));
// Adds permissions actions (radio button style)
if(_isFile){
_linkContextMenu->addAction(_allowEditingLinkAction);
} else {
_linkContextMenu->addAction(_readOnlyLinkAction);
_linkContextMenu->addAction(_allowUploadEditingLinkAction);
_linkContextMenu->addAction(_allowUploadLinkAction);
}
// Adds action to display password widget (check box)
_passwordProtectLinkAction = _linkContextMenu->addAction(tr("Password Protect"));
_passwordProtectLinkAction->setCheckable(true);
if(_linkShare->isPasswordSet()){
_passwordProtectLinkAction->setChecked(true);
_ui->lineEdit_password->setPlaceholderText("********");
showPasswordOptions(true);
}
// If password is enforced then don't allow users to disable it
if (_account->capabilities().sharePublicLinkEnforcePassword()) {
_passwordProtectLinkAction->setChecked(true);
_passwordProtectLinkAction->setEnabled(false);
_passwordRequired = true;
}
// Adds action to display expiration date widget (check box)
_expirationDateLinkAction = _linkContextMenu->addAction(tr("Expiration Date"));
_expirationDateLinkAction->setCheckable(true);
if(_linkShare->getExpireDate().isValid()){
_ui->calendar->setDate(_linkShare->getExpireDate());
_expirationDateLinkAction->setChecked(true);
showExpireDateOptions(true);
}
// If expiredate is enforced do not allow disable and set max days
if (_account->capabilities().sharePublicLinkEnforceExpireDate()) {
_ui->calendar->setMaximumDate(QDate::currentDate().addDays(
_account->capabilities().sharePublicLinkExpireDateDays()));
_expirationDateLinkAction->setChecked(true);
_expirationDateLinkAction->setEnabled(false);
_expiryRequired = true;
}
// Adds action to unshare widget (check box)
_unshareLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/delete.png"),
tr("Unshare"));
connect(_linkContextMenu, &QMenu::triggered,
this, &ShareLinkWidget::slotLinkContextMenuActionTriggered);
_ui->shareLinkToolButton->setMenu(_linkContextMenu);
_ui->shareLinkToolButton->setEnabled(true);
_ui->enableShareLink->setEnabled(true);
_ui->enableShareLink->setChecked(true);
// show sharing options
_ui->shareLinkToolButton->show();
}
toggleAnimation(false);
} }
void ShareLinkWidget::setExpireDate(const QDate &date) void ShareLinkWidget::setupUiOptions(){
{ connect(_linkShare.data(), &LinkShare::expireDateSet, this, &ShareLinkWidget::slotExpireDateSet);
if (_linkShare) { connect(_linkShare.data(), &LinkShare::passwordSet, this, &ShareLinkWidget::slotPasswordSet);
toggleAnimation(true); connect(_linkShare.data(), &LinkShare::passwordSetError, this, &ShareLinkWidget::slotPasswordSetError);
_ui->errorLabel->hide();
_linkShare->setExpireDate(date); // Prepare permissions check and create group action
const QDate expireDate = _linkShare.data()->getExpireDate().isValid()? _linkShare.data()->getExpireDate() : QDate();
const SharePermissions perm = _linkShare.data()->getPermissions();
bool checked = false;
QActionGroup *permissionsGroup = new QActionGroup(this);
// Prepare sharing menu
_linkContextMenu = new QMenu(this);
// radio button style
permissionsGroup->setExclusive(true);
if(_isFile){
checked = perm & (SharePermissionRead & SharePermissionUpdate);
_allowEditingLinkAction = _linkContextMenu->addAction(tr("Allow Editing"));
_allowEditingLinkAction->setCheckable(true);
_allowEditingLinkAction->setChecked(checked);
} else {
checked = perm & SharePermissionRead;
_readOnlyLinkAction = permissionsGroup->addAction(tr("Read only"));
_readOnlyLinkAction->setCheckable(true);
_readOnlyLinkAction->setChecked(checked);
checked = perm & (SharePermissionRead &
SharePermissionCreate &
SharePermissionUpdate &
SharePermissionDelete);
_allowUploadEditingLinkAction = permissionsGroup->addAction(tr("Allow Upload && Editing"));
_allowUploadEditingLinkAction->setCheckable(true);
_allowUploadEditingLinkAction->setChecked(checked);
checked = perm & SharePermissionCreate;
_allowUploadLinkAction = permissionsGroup->addAction(tr("File Drop (Upload Only)"));
_allowUploadLinkAction->setCheckable(true);
_allowUploadLinkAction->setChecked(checked);
} }
// Adds permissions actions (radio button style)
if(_isFile){
_linkContextMenu->addAction(_allowEditingLinkAction);
} else {
_linkContextMenu->addAction(_readOnlyLinkAction);
_linkContextMenu->addAction(_allowUploadEditingLinkAction);
_linkContextMenu->addAction(_allowUploadLinkAction);
}
// Adds action to display password widget (check box)
_passwordProtectLinkAction = _linkContextMenu->addAction(tr("Password Protect"));
_passwordProtectLinkAction->setCheckable(true);
if(_linkShare.data()->isPasswordSet()){
_passwordProtectLinkAction->setChecked(true);
_ui->lineEdit_password->setPlaceholderText("********");
showPasswordOptions(true);
}
// If password is enforced then don't allow users to disable it
if (_account->capabilities().sharePublicLinkEnforcePassword()) {
_passwordProtectLinkAction->setChecked(true);
_passwordProtectLinkAction->setEnabled(false);
_passwordRequired = true;
}
// Adds action to display expiration date widget (check box)
_expirationDateLinkAction = _linkContextMenu->addAction(tr("Expiration Date"));
_expirationDateLinkAction->setCheckable(true);
if(!expireDate.isNull()){
_ui->calendar->setDate(expireDate);
_expirationDateLinkAction->setChecked(true);
showExpireDateOptions(true);
}
// If expiredate is enforced do not allow disable and set max days
if (_account->capabilities().sharePublicLinkEnforceExpireDate()) {
_ui->calendar->setMaximumDate(QDate::currentDate().addDays(
_account->capabilities().sharePublicLinkExpireDateDays()));
_expirationDateLinkAction->setChecked(true);
_expirationDateLinkAction->setEnabled(false);
_expiryRequired = true;
}
// Adds action to unshare widget (check box)
_unshareLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/delete.png"),
tr("Unshare"));
_linkContextMenu->addSeparator();
_addAnotherLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/add.png"),
tr("Add another link"));
_ui->enableShareLink->setIcon(QIcon(":/client/resources/copy.svg"));
disconnect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCreateShareLink);
connect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCopyLinkShare);
connect(_linkContextMenu, &QMenu::triggered,
this, &ShareLinkWidget::slotLinkContextMenuActionTriggered);
_ui->shareLinkToolButton->setMenu(_linkContextMenu);
_ui->shareLinkToolButton->setEnabled(true);
_ui->enableShareLink->setEnabled(true);
_ui->enableShareLink->setChecked(true);
// show sharing options
_ui->shareLinkToolButton->show();
//TO DO
//startAnimation(0, height());
}
void ShareLinkWidget::slotCopyLinkShare(bool clicked){
Q_UNUSED(clicked);
QApplication::clipboard()->setText(_linkShare->getLink().toString());
} }
void ShareLinkWidget::slotExpireDateSet() void ShareLinkWidget::slotExpireDateSet()
{ {
toggleAnimation(false); slotToggleAnimation(false);
}
void ShareLinkWidget::slotExpireDateChanged(const QDate &date)
{
setExpireDate(date);
} }
void ShareLinkWidget::slotSetExpireDate() void ShareLinkWidget::slotSetExpireDate()
{ {
slotExpireDateChanged(_ui->calendar->date()); if(!_linkShare){
return;
}
slotToggleAnimation(true);
_ui->errorLabel->hide();
_linkShare->setExpireDate(_ui->calendar->date());
} }
void ShareLinkWidget::slotCreatePassword() void ShareLinkWidget::slotCreatePassword()
{ {
if (!_manager) {
return;
}
toggleAnimation(true);
if (!_linkShare) { if (!_linkShare) {
// If share creation requires a password, we'll be in this case
if (_ui->lineEdit_password->text().isEmpty()) {
_ui->lineEdit_password->setFocus();
return;
}
_manager->createLinkShare(_sharePath, QString(), _ui->lineEdit_password->text());
} else {
setPassword(_ui->lineEdit_password->text());
}
}
void ShareLinkWidget::slotCreateOrDeleteShareLink(bool checked)
{
if (!_manager) {
qCWarning(lcSharing) << "No share manager set.";
return; return;
} }
toggleAnimation(true); slotToggleAnimation(true);
_ui->errorLabel->hide();
if(checked){ _linkShare->setPassword(_ui->lineEdit_password->text());
_manager->createLinkShare(_sharePath, QString(), QString());
} else {
if (!_linkShare) {
qCWarning(lcSharing) << "No public link set.";
return;
}
confirmAndDeleteShare();
}
} }
void ShareLinkWidget::setPassword(const QString &password) void ShareLinkWidget::slotCreateShareLink(bool clicked)
{ {
if (_linkShare) { slotToggleAnimation(true);
toggleAnimation(true); emit createLinkShare();
_ui->errorLabel->hide();
_linkShare->setPassword(password);
}
} }
void ShareLinkWidget::slotPasswordSet() void ShareLinkWidget::slotPasswordSet()
{ {
if (!_linkShare)
return;
_ui->lineEdit_password->setText(QString()); _ui->lineEdit_password->setText(QString());
if (_linkShare->isPasswordSet()) { if (_linkShare->isPasswordSet()) {
_ui->lineEdit_password->setPlaceholderText("********"); _ui->lineEdit_password->setPlaceholderText("********");
@ -364,39 +291,55 @@ void ShareLinkWidget::slotPasswordSet()
_ui->lineEdit_password->setPlaceholderText(QString()); _ui->lineEdit_password->setPlaceholderText(QString());
} }
toggleAnimation(false); slotToggleAnimation(false);
}
/* void ShareLinkWidget::startAnimation(const int start, const int end){
* When setting/deleting a password from a share the old share is
* deleted and a new one is created. So we need to refetch the shares QPropertyAnimation *animation = new QPropertyAnimation(this, "maximumHeight", this);
* at this point.
* animation->setDuration(500);
* NOTE: I don't see this happening with oC > 10 animation->setStartValue(start);
*/ animation->setEndValue(end);
getShares();
connect(animation, &QAbstractAnimation::finished, this, &ShareLinkWidget::slotAnimationFinished);
if(end < start) // that is to remove the widget, not to show it
connect(animation, &QAbstractAnimation::finished, this, &ShareLinkWidget::slotDeleteAnimationFinished);
connect(animation, &QVariantAnimation::valueChanged, this, &ShareLinkWidget::resizeRequested);
animation->start();
} }
void ShareLinkWidget::slotDeleteShareFetched() void ShareLinkWidget::slotDeleteShareFetched()
{ {
toggleAnimation(true); slotToggleAnimation(false);
// TODO
//startAnimation(height(), 0);
_linkShare.clear(); _linkShare.clear();
_ui->enableShareLink->setChecked(false);
_ui->shareLinkToolButton->setEnabled(false);
_ui->shareLinkToolButton->hide();
togglePasswordOptions(false); togglePasswordOptions(false);
toggleExpireDateOptions(false); toggleExpireDateOptions(false);
getShares(); emit deleteLinkShare();
} }
void ShareLinkWidget::slotCreateShareFetched() void ShareLinkWidget::slotAnimationFinished()
{ {
toggleAnimation(true); emit resizeRequested();
getShares(); deleteLater();
}
void ShareLinkWidget::slotDeleteAnimationFinished()
{
// 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()));
} }
void ShareLinkWidget::slotCreateShareRequiresPassword(const QString &message) void ShareLinkWidget::slotCreateShareRequiresPassword(const QString &message)
{ {
toggleAnimation(true); slotToggleAnimation(true);
showPasswordOptions(true); showPasswordOptions(true);
if (!message.isEmpty()) { if (!message.isEmpty()) {
@ -468,8 +411,10 @@ void ShareLinkWidget::confirmAndDeleteShare()
connect(messageBox, &QMessageBox::finished, this, connect(messageBox, &QMessageBox::finished, this,
[messageBox, yesButton, this]() { [messageBox, yesButton, this]() {
if (messageBox->clickedButton() == yesButton) if (messageBox->clickedButton() == yesButton) {
this->slotToggleAnimation(true);
this->_linkShare->deleteShare(); this->_linkShare->deleteShare();
}
}); });
messageBox->open(); messageBox->open();
} }
@ -495,8 +440,8 @@ void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action)
bool state = action->isChecked(); bool state = action->isChecked();
SharePermissions perm = SharePermissionRead; SharePermissions perm = SharePermissionRead;
if (action == _copyLinkAction) { if(action == _addAnotherLinkAction){
QApplication::clipboard()->setText(_linkShare->getLink().toString()); emit createLinkShare();
} else if (action == _readOnlyLinkAction && state) { } else if (action == _readOnlyLinkAction && state) {
_linkShare->setPermissions(perm); _linkShare->setPermissions(perm);
@ -520,13 +465,13 @@ void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action)
toggleExpireDateOptions(state); toggleExpireDateOptions(state);
} else if (action == _unshareLinkAction) { } else if (action == _unshareLinkAction) {
slotCreateOrDeleteShareLink(state); confirmAndDeleteShare();
} }
} }
void ShareLinkWidget::slotServerError(int code, const QString &message) void ShareLinkWidget::slotServerError(int code, const QString &message)
{ {
toggleAnimation(false); slotToggleAnimation(false);
qCWarning(lcSharing) << "Error from server" << code << message; qCWarning(lcSharing) << "Error from server" << code << message;
displayError(message); displayError(message);

View File

@ -37,7 +37,6 @@ class QuotaInfo;
class SyncResult; class SyncResult;
class LinkShare; class LinkShare;
class Share; class Share;
class ShareManager;
/** /**
* @brief The ShareDialog class * @brief The ShareDialog class
@ -54,44 +53,51 @@ public:
SharePermissions maxSharingPermissions, SharePermissions maxSharingPermissions,
QWidget *parent = nullptr); QWidget *parent = nullptr);
~ShareLinkWidget(); ~ShareLinkWidget();
void getShares();
void toggleButton(bool show); void toggleButton(bool show);
void setupUiOptions();
void setLinkShare(QSharedPointer<LinkShare> linkShare);
QSharedPointer<LinkShare> getLinkShare();
public slots:
void slotDeleteShareFetched();
void slotToggleAnimation(bool start);
void slotServerError(int code, const QString &message);
void slotCreateShareRequiresPassword(const QString &message);
private slots: private slots:
void slotSharesFetched(const QList<QSharedPointer<Share>> &shares); void slotCreateShareLink(bool clicked);
//void slotShareSelectionChanged();
void slotCreateOrDeleteShareLink(bool checked);
void slotCreatePassword(); void slotCreatePassword();
void slotPasswordSet();
void slotPasswordSetError(int code, const QString &message);
void slotExpireDateChanged(const QDate &date);
void slotSetExpireDate(); void slotSetExpireDate();
void slotExpireDateSet();
void slotContextMenuButtonClicked(); void slotContextMenuButtonClicked();
void slotLinkContextMenuActionTriggered(QAction *action); void slotLinkContextMenuActionTriggered(QAction *action);
void slotDeleteShareFetched(); void slotDeleteAnimationFinished();
void slotCreateShareFetched(); void slotAnimationFinished();
void slotCreateShareRequiresPassword(const QString &message);
void slotPasswordSet(); signals:
void slotExpireDateSet(); void createLinkShare();
void deleteLinkShare();
void slotServerError(int code, const QString &message); void resizeRequested();
void slotPasswordSetError(int code, const QString &message); void visualDeletionDone();
private: private:
void displayError(const QString &errMsg); void displayError(const QString &errMsg);
void showPasswordOptions(bool show); void showPasswordOptions(bool show);
void togglePasswordOptions(bool enable); void togglePasswordOptions(bool enable);
void setPassword(const QString &password);
void showExpireDateOptions(bool show); void showExpireDateOptions(bool show);
void toggleExpireDateOptions(bool enable); void toggleExpireDateOptions(bool enable);
void setExpireDate(const QDate &date);
void copyShareLink(const QUrl &url); void slotCopyLinkShare(bool clicked);
/** Confirm with the user and then delete the share */ /** Confirm with the user and then delete the share */
void confirmAndDeleteShare(); void confirmAndDeleteShare();
@ -99,7 +105,7 @@ private:
/** Retrieve a share's name, accounting for _namesSupported */ /** Retrieve a share's name, accounting for _namesSupported */
QString shareName() const; QString shareName() const;
void toggleAnimation(bool start); void startAnimation(const int start, const int end);
Ui::ShareLinkWidget *_ui; Ui::ShareLinkWidget *_ui;
AccountPtr _account; AccountPtr _account;
@ -107,7 +113,6 @@ private:
QString _localPath; QString _localPath;
QString _shareUrl; QString _shareUrl;
ShareManager *_manager;
QSharedPointer<LinkShare> _linkShare; QSharedPointer<LinkShare> _linkShare;
bool _isFile; bool _isFile;
@ -116,7 +121,6 @@ private:
bool _namesSupported; bool _namesSupported;
QMenu *_linkContextMenu; QMenu *_linkContextMenu;
QAction *_copyLinkAction;
QAction *_readOnlyLinkAction; QAction *_readOnlyLinkAction;
QAction *_allowEditingLinkAction; QAction *_allowEditingLinkAction;
QAction *_allowUploadEditingLinkAction; QAction *_allowUploadEditingLinkAction;
@ -124,6 +128,7 @@ private:
QAction *_passwordProtectLinkAction; QAction *_passwordProtectLinkAction;
QAction *_expirationDateLinkAction; QAction *_expirationDateLinkAction;
QAction *_unshareLinkAction; QAction *_unshareLinkAction;
QAction *_addAnotherLinkAction;
}; };
} }

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>350</width> <width>350</width>
<height>126</height> <height>136</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -68,7 +68,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QProgressIndicator" name="progressIndicator"/> <widget class="QProgressIndicator" name="progressIndicator" native="true"/>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
@ -84,9 +84,19 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="enableShareLink"> <widget class="QPushButton" name="enableShareLink">
<property name="text"> <property name="text">
<string>Enable</string> <string/>
</property>
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/add.png</normaloff>:/client/resources/add.png</iconset>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="flat">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>