diff --git a/client.qrc b/client.qrc index 471f4c23d..00db6b163 100644 --- a/client.qrc +++ b/client.qrc @@ -37,6 +37,7 @@ resources/confirm.svg resources/copy.svg resources/state-sync.svg + resources/add.png diff --git a/resources/add.png b/resources/add.png new file mode 100644 index 000000000..2c624c182 Binary files /dev/null and b/resources/add.png differ diff --git a/src/gui/sharedialog.cpp b/src/gui/sharedialog.cpp index 09c2e2e95..f7e25173a 100644 --- a/src/gui/sharedialog.cpp +++ b/src/gui/sharedialog.cpp @@ -18,6 +18,8 @@ #include "sharelinkwidget.h" #include "shareusergroupwidget.h" +#include "sharemanager.h" + #include "account.h" #include "accountstate.h" #include "configfile.h" @@ -49,7 +51,8 @@ ShareDialog::ShareDialog(QPointer accountState, , _maxSharingPermissions(maxSharingPermissions) , _privateLinkUrl(accountState->account()->deprecatedPrivateLinkUrl(numericFileId).toString(QUrl::FullyEncoded)) , _startPage(startPage) - , _linkWidget(nullptr) + , _linkWidgetList({}) + , _emptyShareLinkWidget(nullptr) , _userGroupWidget(nullptr) , _progressIndicator(nullptr) { @@ -101,11 +104,6 @@ ShareDialog::ShareDialog(QPointer accountState, this->setWindowTitle(tr("%1 Sharing").arg(Theme::instance()->appNameGUI())); 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; } @@ -115,14 +113,6 @@ ShareDialog::ShareDialog(QPointer accountState, 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); job->setProperties( QList() @@ -133,6 +123,98 @@ ShareDialog::ShareDialog(QPointer accountState, connect(job, &PropfindJob::result, this, &ShareDialog::slotPropfindReceived); connect(job, &PropfindJob::finishedWithError, this, &ShareDialog::slotPropfindError); 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){ + _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){ + emit toggleAnimation(true); + addLinkShareWidget(linkShare); + initLinkShareWidget(); + emit toggleAnimation(false); +} + +void ShareDialog::slotSharesFetched(const QList> &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 = qSharedPointerDynamicCast(share); + addLinkShareWidget(linkShare); + } + + initLinkShareWidget(); + emit toggleAnimation(false); +} + +// TODO +void ShareDialog::slotAdjustScrollWidgetSize() +{ + int count = this->findChildren().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() @@ -178,8 +260,6 @@ void ShareDialog::slotPropfindError() void ShareDialog::showSharingUi() { - //_progressIndicator->stopAnimation(); - auto theme = Theme::instance(); // There's no difference between being unable to reshare and @@ -205,15 +285,25 @@ void ShareDialog::showSharingUi() } if (theme->linkSharing()) { - _linkWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this); - _ui->verticalLayout->insertWidget(2, _linkWidget); - _linkWidget->getShares(); - - if (_startPage == ShareDialogStartPage::PublicLinks) - _ui->verticalLayout->insertWidget(3, _linkWidget); + _manager->fetchShares(_sharePath); } } +void ShareDialog::slotCreateLinkShare() +{ + _manager->createLinkShare(_sharePath, QString(), QString()); +} + + +void ShareDialog::slotDeleteShare() +{ + auto sharelinkWidget = dynamic_cast(sender()); + sharelinkWidget->hide(); + _ui->verticalLayout->removeWidget(sharelinkWidget); + _linkWidgetList.removeAll(sharelinkWidget); + initLinkShareWidget(); +} + void ShareDialog::slotThumbnailFetched(const int &statusCode, const QByteArray &reply) { if (statusCode != 200) { @@ -237,8 +327,6 @@ void ShareDialog::slotAccountStateChanged(int state) _userGroupWidget->setEnabled(enabled); } - if (_linkWidget != nullptr) { - _linkWidget->setEnabled(enabled); - } + } } diff --git a/src/gui/sharedialog.h b/src/gui/sharedialog.h index 36d495e3f..dbd0ca775 100644 --- a/src/gui/sharedialog.h +++ b/src/gui/sharedialog.h @@ -19,6 +19,7 @@ #include "sharepermissions.h" #include "owncloudgui.h" +#include #include #include #include @@ -34,6 +35,9 @@ namespace Ui { class ShareLinkWidget; class ShareUserGroupWidget; +class ShareManager; +class LinkShare; +class Share; class ShareDialog : public QDialog { @@ -56,8 +60,19 @@ private slots: void slotThumbnailFetched(const int &statusCode, const QByteArray &reply); void slotAccountStateChanged(int state); + void slotSharesFetched(const QList> &shares); + void slotAddLinkShareWidget(const QSharedPointer &linkShare); + void slotDeleteShare(); + void slotCreateLinkShare(); + void slotAdjustScrollWidgetSize(); + +signals: + void toggleAnimation(bool); + private: void showSharingUi(); + void addLinkShareWidget(const QSharedPointer &linkShare); + void initLinkShareWidget(); Ui::ShareDialog *_ui; @@ -68,8 +83,10 @@ private: QByteArray _numericFileId; QString _privateLinkUrl; ShareDialogStartPage _startPage; + ShareManager *_manager; - ShareLinkWidget *_linkWidget; + QList _linkWidgetList; + ShareLinkWidget* _emptyShareLinkWidget; ShareUserGroupWidget *_userGroupWidget; QProgressIndicator *_progressIndicator; }; diff --git a/src/gui/sharelinkwidget.cpp b/src/gui/sharelinkwidget.cpp index 51c437965..a09e2c4e3 100644 --- a/src/gui/sharelinkwidget.cpp +++ b/src/gui/sharelinkwidget.cpp @@ -17,9 +17,8 @@ #include "sharelinkwidget.h" #include "account.h" #include "capabilities.h" - -#include "sharemanager.h" #include "guiutility.h" +#include "sharemanager.h" #include "QProgressIndicator.h" #include @@ -29,9 +28,12 @@ #include #include #include +#include namespace OCC { +Q_LOGGING_CATEGORY(lcShareLink, "nextcloud.gui.sharelink", QtInfoMsg) + ShareLinkWidget::ShareLinkWidget(AccountPtr account, const QString &sharePath, const QString &localPath, @@ -42,13 +44,11 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account, , _account(account) , _sharePath(sharePath) , _localPath(localPath) - , _manager(nullptr) , _linkShare(nullptr) , _passwordRequired(false) , _expiryRequired(false) , _namesSupported(true) , _linkContextMenu(nullptr) - , _copyLinkAction(nullptr) , _readOnlyLinkAction(nullptr) , _allowEditingLinkAction(nullptr) , _allowUploadEditingLinkAction(nullptr) @@ -68,26 +68,26 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account, QFileInfo fi(localPath); _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->confirmPassword, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreatePassword); 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(); bool sharingPossible = true; if (!_account->capabilities().sharePublicLink()) { - qCWarning(lcSharing) << "Link shares have been disabled"; + qCWarning(lcShareLink) << "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."; + qCWarning(lcShareLink) << "The file can not be shared because it was shared without sharing permission."; sharingPossible = false; } - _ui->createShareButton->setVisible(sharingPossible); - _ui->enableShareLink->setVisible(sharingPossible); - _ui->shareLinkToolButton->setVisible(sharingPossible); + _ui->enableShareLink->setChecked(false); + _ui->shareLinkToolButton->setEnabled(false); + _ui->shareLinkToolButton->hide(); // Older servers don't support multiple public link shares if (!_account->capabilities().sharePublicLinkMultiple()) { @@ -100,34 +100,9 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account, // check if the file is already inside of a synced folder if (sharePath.isEmpty()) { - // The file is not yet in an ownCloud synced folder. We could automatically - // 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."; + qCWarning(lcShareLink) << "Unable to share files not in a sync folder."; 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() @@ -135,7 +110,7 @@ ShareLinkWidget::~ShareLinkWidget() delete _ui; } -void ShareLinkWidget::toggleAnimation(bool start){ +void ShareLinkWidget::slotToggleAnimation(bool start){ if (start) { if (!_ui->progressIndicator->isAnimated()) _ui->progressIndicator->startAnimation(); @@ -144,218 +119,170 @@ void ShareLinkWidget::toggleAnimation(bool start){ } } -void ShareLinkWidget::getShares() -{ - if (_manager) { - toggleAnimation(true); - _manager->fetchShares(_sharePath); - } +void ShareLinkWidget::setLinkShare(QSharedPointer linkShare){ + _linkShare = linkShare; } -void ShareLinkWidget::slotSharesFetched(const QList> &shares) -{ - const QString versionString = _account->serverVersion(); - qCInfo(lcSharing) << versionString << "Fetched" << shares.count() << "shares"; - - foreach (auto share, shares) { - if (share->getShareType() != Share::TypeLink) { - continue; - } - _linkShare = qSharedPointerDynamicCast(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); +QSharedPointer ShareLinkWidget::getLinkShare(){ + return _linkShare; } -void ShareLinkWidget::setExpireDate(const QDate &date) -{ - if (_linkShare) { - toggleAnimation(true); - _ui->errorLabel->hide(); - _linkShare->setExpireDate(date); +void ShareLinkWidget::setupUiOptions(){ + 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 + 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() { - toggleAnimation(false); -} - -void ShareLinkWidget::slotExpireDateChanged(const QDate &date) -{ - setExpireDate(date); + slotToggleAnimation(false); } void ShareLinkWidget::slotSetExpireDate() { - slotExpireDateChanged(_ui->calendar->date()); + if(!_linkShare){ + return; + } + + slotToggleAnimation(true); + _ui->errorLabel->hide(); + _linkShare->setExpireDate(_ui->calendar->date()); } void ShareLinkWidget::slotCreatePassword() { - if (!_manager) { - return; - } - - toggleAnimation(true); - 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; } - toggleAnimation(true); - - if(checked){ - _manager->createLinkShare(_sharePath, QString(), QString()); - } else { - if (!_linkShare) { - qCWarning(lcSharing) << "No public link set."; - return; - } - confirmAndDeleteShare(); - } + slotToggleAnimation(true); + _ui->errorLabel->hide(); + _linkShare->setPassword(_ui->lineEdit_password->text()); } -void ShareLinkWidget::setPassword(const QString &password) +void ShareLinkWidget::slotCreateShareLink(bool clicked) { - if (_linkShare) { - toggleAnimation(true); - - _ui->errorLabel->hide(); - _linkShare->setPassword(password); - } + slotToggleAnimation(true); + emit createLinkShare(); } void ShareLinkWidget::slotPasswordSet() { - if (!_linkShare) - return; - _ui->lineEdit_password->setText(QString()); if (_linkShare->isPasswordSet()) { _ui->lineEdit_password->setPlaceholderText("********"); @@ -364,39 +291,55 @@ void ShareLinkWidget::slotPasswordSet() _ui->lineEdit_password->setPlaceholderText(QString()); } - toggleAnimation(false); + slotToggleAnimation(false); +} - /* - * 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 - * at this point. - * - * NOTE: I don't see this happening with oC > 10 - */ - getShares(); +void ShareLinkWidget::startAnimation(const int start, const int end){ + + QPropertyAnimation *animation = new QPropertyAnimation(this, "maximumHeight", this); + + animation->setDuration(500); + animation->setStartValue(start); + animation->setEndValue(end); + + 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() { - toggleAnimation(true); + slotToggleAnimation(false); + + // TODO + //startAnimation(height(), 0); + _linkShare.clear(); - _ui->enableShareLink->setChecked(false); - _ui->shareLinkToolButton->setEnabled(false); - _ui->shareLinkToolButton->hide(); togglePasswordOptions(false); toggleExpireDateOptions(false); - getShares(); + emit deleteLinkShare(); } -void ShareLinkWidget::slotCreateShareFetched() +void ShareLinkWidget::slotAnimationFinished() { - toggleAnimation(true); - getShares(); + emit resizeRequested(); + 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) { - toggleAnimation(true); + slotToggleAnimation(true); showPasswordOptions(true); if (!message.isEmpty()) { @@ -468,8 +411,10 @@ void ShareLinkWidget::confirmAndDeleteShare() connect(messageBox, &QMessageBox::finished, this, [messageBox, yesButton, this]() { - if (messageBox->clickedButton() == yesButton) + if (messageBox->clickedButton() == yesButton) { + this->slotToggleAnimation(true); this->_linkShare->deleteShare(); + } }); messageBox->open(); } @@ -495,8 +440,8 @@ void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action) bool state = action->isChecked(); SharePermissions perm = SharePermissionRead; - if (action == _copyLinkAction) { - QApplication::clipboard()->setText(_linkShare->getLink().toString()); + if(action == _addAnotherLinkAction){ + emit createLinkShare(); } else if (action == _readOnlyLinkAction && state) { _linkShare->setPermissions(perm); @@ -520,13 +465,13 @@ void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action) toggleExpireDateOptions(state); } else if (action == _unshareLinkAction) { - slotCreateOrDeleteShareLink(state); + confirmAndDeleteShare(); } } void ShareLinkWidget::slotServerError(int code, const QString &message) { - toggleAnimation(false); + slotToggleAnimation(false); qCWarning(lcSharing) << "Error from server" << code << message; displayError(message); diff --git a/src/gui/sharelinkwidget.h b/src/gui/sharelinkwidget.h index 8094a9789..276dc88a0 100644 --- a/src/gui/sharelinkwidget.h +++ b/src/gui/sharelinkwidget.h @@ -37,7 +37,6 @@ class QuotaInfo; class SyncResult; class LinkShare; class Share; -class ShareManager; /** * @brief The ShareDialog class @@ -54,44 +53,51 @@ public: SharePermissions maxSharingPermissions, QWidget *parent = nullptr); ~ShareLinkWidget(); - void getShares(); + void toggleButton(bool show); + void setupUiOptions(); + + void setLinkShare(QSharedPointer linkShare); + QSharedPointer getLinkShare(); + +public slots: + void slotDeleteShareFetched(); + void slotToggleAnimation(bool start); + void slotServerError(int code, const QString &message); + void slotCreateShareRequiresPassword(const QString &message); private slots: - void slotSharesFetched(const QList> &shares); - //void slotShareSelectionChanged(); + void slotCreateShareLink(bool clicked); - void slotCreateOrDeleteShareLink(bool checked); void slotCreatePassword(); + void slotPasswordSet(); + void slotPasswordSetError(int code, const QString &message); - void slotExpireDateChanged(const QDate &date); void slotSetExpireDate(); + void slotExpireDateSet(); void slotContextMenuButtonClicked(); void slotLinkContextMenuActionTriggered(QAction *action); - void slotDeleteShareFetched(); - void slotCreateShareFetched(); - void slotCreateShareRequiresPassword(const QString &message); + void slotDeleteAnimationFinished(); + void slotAnimationFinished(); - void slotPasswordSet(); - void slotExpireDateSet(); - - void slotServerError(int code, const QString &message); - void slotPasswordSetError(int code, const QString &message); +signals: + void createLinkShare(); + void deleteLinkShare(); + void resizeRequested(); + void visualDeletionDone(); private: void displayError(const QString &errMsg); void showPasswordOptions(bool show); void togglePasswordOptions(bool enable); - void setPassword(const QString &password); void showExpireDateOptions(bool show); 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 */ void confirmAndDeleteShare(); @@ -99,7 +105,7 @@ private: /** Retrieve a share's name, accounting for _namesSupported */ QString shareName() const; - void toggleAnimation(bool start); + void startAnimation(const int start, const int end); Ui::ShareLinkWidget *_ui; AccountPtr _account; @@ -107,7 +113,6 @@ private: QString _localPath; QString _shareUrl; - ShareManager *_manager; QSharedPointer _linkShare; bool _isFile; @@ -116,7 +121,6 @@ private: bool _namesSupported; QMenu *_linkContextMenu; - QAction *_copyLinkAction; QAction *_readOnlyLinkAction; QAction *_allowEditingLinkAction; QAction *_allowUploadEditingLinkAction; @@ -124,6 +128,7 @@ private: QAction *_passwordProtectLinkAction; QAction *_expirationDateLinkAction; QAction *_unshareLinkAction; + QAction *_addAnotherLinkAction; }; } diff --git a/src/gui/sharelinkwidget.ui b/src/gui/sharelinkwidget.ui index 8affe169a..c0b85261f 100644 --- a/src/gui/sharelinkwidget.ui +++ b/src/gui/sharelinkwidget.ui @@ -7,7 +7,7 @@ 0 0 350 - 126 + 136 @@ -68,7 +68,7 @@ - + @@ -84,9 +84,19 @@ - + - Enable + + + + + :/client/resources/add.png:/client/resources/add.png + + + false + + + true