From 309be57a12e4d6ef4190e0cd1dd2599aae7d9fc0 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Sat, 31 Oct 2015 22:21:09 +0100 Subject: [PATCH] [Sharing] Add user/group sharing dialog Dialog can now retrive current shares for path, set the permissions on those shares and delete the share. --- src/gui/CMakeLists.txt | 3 + src/gui/application.cpp | 2 + src/gui/owncloudgui.cpp | 22 ++++ src/gui/owncloudgui.h | 1 + src/gui/shareusergroupdialog.cpp | 170 +++++++++++++++++++++++++++++++ src/gui/shareusergroupdialog.h | 98 ++++++++++++++++++ src/gui/shareusergroupdialog.ui | 133 ++++++++++++++++++++++++ src/gui/socketapi.cpp | 45 ++++++++ src/gui/socketapi.h | 2 + 9 files changed, 476 insertions(+) create mode 100644 src/gui/shareusergroupdialog.cpp create mode 100644 src/gui/shareusergroupdialog.h create mode 100644 src/gui/shareusergroupdialog.ui diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index af7393301..917739b28 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -23,6 +23,8 @@ set(client_UI protocolwidget.ui settingsdialog.ui sharedialog.ui + shareusergroupdialog.ui + sharedialogshare.ui sslerrordialog.ui owncloudsetuppage.ui addcertificatedialog.ui @@ -60,6 +62,7 @@ set(client_SRCS settingsdialog.cpp share.cpp sharedialog.cpp + shareusergroupdialog.cpp socketapi.cpp sslbutton.cpp sslerrordialog.cpp diff --git a/src/gui/application.cpp b/src/gui/application.cpp index add9add91..41e72e245 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -174,6 +174,8 @@ Application::Application(int &argc, char **argv) : connect(FolderMan::instance()->socketApi(), SIGNAL(shareCommandReceived(QString, QString, bool)), _gui, SLOT(slotShowShareDialog(QString, QString, bool))); + connect(FolderMan::instance()->socketApi(), SIGNAL(shareUserGroupCommandReceived(QString, QString, bool)), + _gui, SLOT(slotShowShareUserGroupDialog(QString, QString, bool))); // startup procedure. connect(&_checkConnectionTimer, SIGNAL(timeout()), this, SLOT(slotCheckConnection())); diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 4adaeaa50..4a04598c3 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -20,6 +20,7 @@ #include "progressdispatcher.h" #include "owncloudsetupwizard.h" #include "sharedialog.h" +#include "shareusergroupdialog.h" #if defined(Q_OS_MAC) # include "settingsdialogmac.h" # include "macwindow.h" // qtmacgoodies @@ -780,5 +781,26 @@ void ownCloudGui::slotShowShareDialog(const QString &sharePath, const QString &l raiseDialog(w); } +void ownCloudGui::slotShowShareUserGroupDialog(const QString &sharePath, const QString &localPath, bool resharingAllowed) +{ + const auto folder = FolderMan::instance()->folderForPath(localPath); + if (!folder) { + qDebug() << "Could not open share dialog for" << localPath << "no responsible folder found"; + return; + } + + // For https://github.com/owncloud/client/issues/3783 + _settingsDialog->hide(); + + const auto accountState = folder->accountState(); + + qDebug() << Q_FUNC_INFO << "Opening share dialog" << sharePath << localPath; + ShareUserGroupDialog *w = new ShareUserGroupDialog(accountState->account(), sharePath, localPath, resharingAllowed); + w->getShares(); + w->setAttribute( Qt::WA_DeleteOnClose, true ); + raiseDialog(w); +} + + } // end namespace diff --git a/src/gui/owncloudgui.h b/src/gui/owncloudgui.h index 891bd74d7..014c3b180 100644 --- a/src/gui/owncloudgui.h +++ b/src/gui/owncloudgui.h @@ -77,6 +77,7 @@ public slots: void slotOpenPath(const QString& path); void slotAccountStateChanged(); void slotShowShareDialog(const QString &sharePath, const QString &localPath, bool resharingAllowed); + void slotShowShareUserGroupDialog(const QString &sharePath, const QString &localPath, bool resharingAllowed); private slots: void slotDisplayIdle(); diff --git a/src/gui/shareusergroupdialog.cpp b/src/gui/shareusergroupdialog.cpp new file mode 100644 index 000000000..530f80b9b --- /dev/null +++ b/src/gui/shareusergroupdialog.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) by Roeland Jago Douma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "shareusergroupdialog.h" +#include "ui_shareusergroupdialog.h" +#include "ui_sharedialogshare.h" +#include "account.h" +#include "json.h" +#include "folderman.h" +#include "folder.h" +#include "accountmanager.h" +#include "theme.h" +#include "configfile.h" +#include "capabilities.h" + +#include "thumbnailjob.h" +#include "share.h" + +#include "QProgressIndicator.h" +#include +#include +#include +#include + +namespace OCC { + +ShareUserGroupDialog::ShareUserGroupDialog(AccountPtr account, const QString &sharePath, const QString &localPath, bool resharingAllowed, QWidget *parent) : + QDialog(parent), + _ui(new Ui::ShareUserGroupDialog), + _account(account), + _sharePath(sharePath), + _localPath(localPath), + _resharingAllowed(resharingAllowed) +{ + 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(); + + _manager = new ShareManager(_account, this); + connect(_manager, SIGNAL(sharesFetched(QList>)), SLOT(slotSharesFetched(QList>))); +} + +void ShareUserGroupDialog::done( int r ) { + ConfigFile cfg; + cfg.saveGeometry(this); + QDialog::done(r); +} + +ShareUserGroupDialog::~ShareUserGroupDialog() +{ + delete _ui; +} + +void ShareUserGroupDialog::getShares() +{ + _manager->fetchShares(_sharePath); +} + +void ShareUserGroupDialog::slotSharesFetched(const QList> &shares) +{ + const QString versionString = _account->serverVersion(); + qDebug() << Q_FUNC_INFO << versionString << "Fetched" << shares.count() << "shares"; + + // TODO clear old shares + + foreach(const auto &share, shares) { + + if (share->getShareType() == Share::TypeLink) { + continue; + } + + ShareDialogShare *s = new ShareDialogShare(share, this); + _ui->sharesLayout->addWidget(s); + } + + // Add all new shares to share list + +} + +ShareDialogShare::ShareDialogShare(QSharedPointer share, + QWidget *parent) : + QWidget(parent), + _ui(new Ui::ShareDialogShare), + _share(share) +{ + _ui->setupUi(this); + + if (share->getPermissions() & Share::PermissionUpdate) { + _ui->permissionUpdate->setCheckState(Qt::Checked); + } + if (share->getPermissions() & Share::PermissionCreate) { + _ui->permissionCreate->setCheckState(Qt::Checked); + } + if (share->getPermissions() & Share::PermissionDelete) { + _ui->permissionDelete->setCheckState(Qt::Checked); + } + if (share->getPermissions() & Share::PermissionShare) { + _ui->permissionShare->setCheckState(Qt::Checked); + } + + connect(_ui->permissionUpdate, SIGNAL(clicked(bool)), SLOT(slotPermissionsChanged())); + connect(_ui->permissionCreate, SIGNAL(clicked(bool)), SLOT(slotPermissionsChanged())); + connect(_ui->permissionDelete, SIGNAL(clicked(bool)), SLOT(slotPermissionsChanged())); + connect(_ui->permissionShare, SIGNAL(clicked(bool)), SLOT(slotPermissionsChanged())); + + connect(share.data(), SIGNAL(permissionsSet()), SLOT(slotPermissionsSet())); + connect(share.data(), SIGNAL(shareDeleted()), SLOT(slotShareDeleted())); +} + +void ShareDialogShare::on_deleteShareButton_clicked() +{ + setEnabled(false); + _share->deleteShare(); +} + +ShareDialogShare::~ShareDialogShare() +{ + delete _ui; +} + +void ShareDialogShare::slotPermissionsChanged() +{ + setEnabled(false); + + Share::Permissions permissions = Share::PermissionRead; + + if (_ui->permissionUpdate->checkState() == Qt::Checked) { + permissions |= Share::PermissionUpdate; + } + + if (_ui->permissionCreate->checkState() == Qt::Checked) { + permissions |= Share::PermissionCreate; + } + + if (_ui->permissionDelete->checkState() == Qt::Checked) { + permissions |= Share::PermissionDelete; + } + + if (_ui->permissionShare->checkState() == Qt::Checked) { + permissions |= Share::PermissionShare; + } + + _share->setPermissions(permissions); +} + +void ShareDialogShare::slotShareDeleted() +{ + deleteLater(); +} + +void ShareDialogShare::slotPermissionsSet() +{ + setEnabled(true); +} + +} diff --git a/src/gui/shareusergroupdialog.h b/src/gui/shareusergroupdialog.h new file mode 100644 index 000000000..f6d4954fd --- /dev/null +++ b/src/gui/shareusergroupdialog.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) by Roeland Jago Douma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef SHAREDIALOG_UG_H +#define SHAREDIALOG_UG_H + +#include "accountfwd.h" +#include "QProgressIndicator.h" +#include +#include +#include +#include +#include + +namespace OCC { + +namespace Ui { +class ShareUserGroupDialog; +class ShareDialogShare; +} + +class AbstractCredentials; +class QuotaInfo; +class SyncResult; +class Share; +class ShareManager; + +class ShareDialogShare : public QWidget +{ + Q_OBJECT + +public: + explicit ShareDialogShare(QSharedPointer Share, QWidget *parent = 0); + ~ShareDialogShare(); + +signals: + void shareDeleted(ShareDialogShare *share); + +private slots: + void on_deleteShareButton_clicked(); + void slotPermissionsChanged(); + + void slotShareDeleted(); + void slotPermissionsSet(); + +private: + Ui::ShareDialogShare *_ui; + QSharedPointer _share; +}; + + +/** + * @brief The ShareDialog (user/group) class + * @ingroup gui + */ +class ShareUserGroupDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ShareUserGroupDialog(AccountPtr account, + const QString &sharePath, + const QString &localPath, + bool resharingAllowed, + QWidget *parent = 0); + ~ShareUserGroupDialog(); + void getShares(); + +private slots: + void slotSharesFetched(const QList> &shares); + void done( int r ); + +private: + Ui::ShareUserGroupDialog *_ui; + AccountPtr _account; + QString _sharePath; + QString _localPath; + + bool _resharingAllowed; + bool _isFile; + + ShareManager *_manager; + QList _shares; +}; + +} + +#endif // SHAREDIALOG_UG_H diff --git a/src/gui/shareusergroupdialog.ui b/src/gui/shareusergroupdialog.ui new file mode 100644 index 000000000..9759130c0 --- /dev/null +++ b/src/gui/shareusergroupdialog.ui @@ -0,0 +1,133 @@ + + + OCC::ShareUserGroupDialog + + + + 0 + 0 + 372 + 505 + + + + Share NewDocument.odt + + + + + + + + TextLabel + + + + + + + + 0 + 0 + + + + + 75 + true + + + + share label + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + ownCloud Path: + + + + + + + + + + 0 + 0 + + + + TextLabel + + + + + + + + 0 + 0 + + + + QDialogButtonBox::Close + + + + + + + + + + + + Share + + + + + + + + + + + Shares + + + + + + + + + + + QProgressIndicator + QWidget +
QProgressIndicator.h
+ 1 +
+
+ + +
diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index a3ffa9327..5b59bb9fa 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -404,6 +404,51 @@ void SocketApi::command_SHARE(const QString& localFile, QIODevice* socket) } } +void SocketApi::command_SHARE_USER_GROUP(const QString& localFile, QIODevice* socket) +{ + if (!socket) { + qDebug() << Q_FUNC_INFO << "No valid socket object."; + return; + } + + qDebug() << Q_FUNC_INFO << localFile; + + Folder *shareFolder = FolderMan::instance()->folderForPath(localFile); + if (!shareFolder) { + const QString message = QLatin1String("SHARE:NOP:")+QDir::toNativeSeparators(localFile); + // files that are not within a sync folder are not synced. + sendMessage(socket, message); + } else if (!shareFolder->accountState()->isConnected()) { + const QString message = QLatin1String("SHARE:NOTCONNECTED:")+QDir::toNativeSeparators(localFile); + // if the folder isn't connected, don't open the share dialog + sendMessage(socket, message); + } else { + const QString folderForPath = shareFolder->path(); + const QString remotePath = shareFolder->remotePath() + localFile.right(localFile.count()-folderForPath.count()+1); + + // Can't share root folder + if (QDir::cleanPath(remotePath) == "/") { + const QString message = QLatin1String("SHARE:CANNOTSHAREROOT:")+QDir::toNativeSeparators(localFile); + sendMessage(socket, message); + return; + } + + SyncJournalFileRecord rec = dbFileRecord_capi(shareFolder, localFile); + + bool allowReshare = true; // lets assume the good + if( rec.isValid() ) { + // check the permission: Is resharing allowed? + if( !rec._remotePerm.contains('R') ) { + allowReshare = false; + } + } + const QString message = QLatin1String("SHARE:OK:")+QDir::toNativeSeparators(localFile); + sendMessage(socket, message); + + emit shareUserGroupCommandReceived(remotePath, localFile, allowReshare); + } +} + void SocketApi::command_VERSION(const QString&, QIODevice* socket) { sendMessage(socket, QLatin1String("VERSION:" MIRALL_VERSION_STRING ":" MIRALL_SOCKET_API_VERSION)); diff --git a/src/gui/socketapi.h b/src/gui/socketapi.h index 238c342f9..482f15158 100644 --- a/src/gui/socketapi.h +++ b/src/gui/socketapi.h @@ -55,6 +55,7 @@ public slots: signals: void shareCommandReceived(const QString &sharePath, const QString &localPath, bool resharingAllowed); + void shareUserGroupCommandReceived(const QString &sharePath, const QString &localPath, bool resharingAllowed); private slots: void slotNewConnection(); @@ -74,6 +75,7 @@ private: Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, QIODevice* socket); Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* socket); Q_INVOKABLE void command_SHARE(const QString& localFile, QIODevice* socket); + Q_INVOKABLE void command_SHARE_USER_GROUP(const QString& localFile, QIODevice* socket); Q_INVOKABLE void command_VERSION(const QString& argument, QIODevice* socket);