From f854c5263beaf2932938e9cab70e286aeb14a7a5 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 24 Jan 2017 10:16:10 +0100 Subject: [PATCH] Wizard: Add options to ask confirmation for external storage Added two checkboxes in the Account Wizard in the advanced page to change the first options. Also added a checkbox in the general settings to ask for confirmation for external storages. Theme options allow to hide the checkboxes in the wizard. As described in issue #5340 --- src/gui/accountsettings.cpp | 9 +- src/gui/folder.cpp | 6 +- src/gui/generalsettings.cpp | 3 + src/gui/generalsettings.ui | 55 ++++---- src/gui/wizard/owncloudadvancedsetuppage.cpp | 22 ++++ src/gui/wizard/owncloudadvancedsetuppage.ui | 129 ++++++++++++++++++- src/libsync/configfile.cpp | 11 ++ src/libsync/configfile.h | 2 + src/libsync/discoveryphase.cpp | 30 +++-- src/libsync/discoveryphase.h | 13 +- src/libsync/syncengine.cpp | 3 +- src/libsync/syncengine.h | 8 +- src/libsync/theme.cpp | 13 +- src/libsync/theme.h | 16 ++- 14 files changed, 256 insertions(+), 64 deletions(-) diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp index cceba75bae9..0fb32cfbf94 100644 --- a/src/gui/accountsettings.cpp +++ b/src/gui/accountsettings.cpp @@ -675,8 +675,13 @@ void AccountSettings::refreshSelectiveSyncStatus() ui->selectiveSyncButtons->setVisible(true); ui->bigFolderUi->setVisible(false); } else { - QString wholeMsg = tr("There are new folders that were not synchronized because they are too big: ") + msg; - ui->selectiveSyncNotification->setText(wholeMsg); + ConfigFile cfg; + QString info = + !cfg.confirmExternalStorage() ? tr("There are folders that were not synchronized because they are too big: ") : + !cfg.newBigFolderSizeLimit().first ? tr("There are folders that were not synchronized because they are external storages: ") : + tr("There are folders that were not synchronized because they are too big or external storages: "); + + ui->selectiveSyncNotification->setText(info + msg); ui->selectiveSyncButtons->setVisible(false); ui->bigFolderUi->setVisible(true); shouldBeVisible = true; diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 24ed2cc1c6a..6079edb28bc 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -748,10 +748,12 @@ void Folder::startSync(const QStringList &pathList) setDirtyNetworkLimits(); + SyncOptions opt; ConfigFile cfgFile; auto newFolderLimit = cfgFile.newBigFolderSizeLimit(); - quint64 limit = newFolderLimit.first ? newFolderLimit.second * 1000 * 1000 : -1; // convert from MB to B - _engine->setNewBigFolderSizeLimit(limit); + opt._newBigFolderSizeLimit = newFolderLimit.first ? newFolderLimit.second * 1000LL * 1000LL : -1; // convert from MB to B + opt._confirmExternalStorage = cfgFile.confirmExternalStorage(); + _engine->setSyncOptions(opt); _engine->setIgnoreHiddenFiles(_definition.ignoreHiddenFiles); diff --git a/src/gui/generalsettings.cpp b/src/gui/generalsettings.cpp index d6eae4116b2..25a3c282845 100644 --- a/src/gui/generalsettings.cpp +++ b/src/gui/generalsettings.cpp @@ -106,6 +106,8 @@ void GeneralSettings::loadMiscSettings() auto newFolderLimit = cfgFile.newBigFolderSizeLimit(); _ui->newFolderLimitCheckBox->setChecked(newFolderLimit.first); _ui->newFolderLimitSpinBox->setValue(newFolderLimit.second); + _ui->newExternalStorage->setChecked(cfgFile.confirmExternalStorage()); + _ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons()); } void GeneralSettings::slotUpdateInfo() @@ -138,6 +140,7 @@ void GeneralSettings::saveMiscSettings() cfgFile.setNewBigFolderSizeLimit(_ui->newFolderLimitCheckBox->isChecked(), _ui->newFolderLimitSpinBox->value()); + cfgFile.setConfirmExternalStorage(_ui->newExternalStorage->isChecked()); } void GeneralSettings::slotToggleLaunchOnStartup(bool enable) diff --git a/src/gui/generalsettings.ui b/src/gui/generalsettings.ui index 4bc4b995883..06b7aa0343f 100644 --- a/src/gui/generalsettings.ui +++ b/src/gui/generalsettings.ui @@ -6,7 +6,7 @@ 0 0 - 706 + 785 523 @@ -53,13 +53,6 @@ Advanced - - - - Edit &Ignored Files - - - @@ -73,12 +66,25 @@ + + + + + 0 + 0 + + + + S&how crash reporter + + + - Ask &confirmation before downloading folders larger than + Ask for confirmation before synchronizing folders larger than true @@ -98,7 +104,7 @@ - MB + MB @@ -117,20 +123,7 @@ - - - - - 0 - 0 - - - - S&how crash reporter - - - - + @@ -147,6 +140,20 @@ + + + + Edit &Ignored Files + + + + + + + Ask for confirmation before synchronizing external storages + + + diff --git a/src/gui/wizard/owncloudadvancedsetuppage.cpp b/src/gui/wizard/owncloudadvancedsetuppage.cpp index c0a03815139..ae6d6d81f91 100644 --- a/src/gui/wizard/owncloudadvancedsetuppage.cpp +++ b/src/gui/wizard/owncloudadvancedsetuppage.cpp @@ -68,6 +68,15 @@ OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage() _ui.lServerIcon->setPixmap(appIcon.pixmap(48)); _ui.lLocalIcon->setText(QString()); _ui.lLocalIcon->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/folder-sync.png"))); + + if (theme->wizardHideExternalStorageConfirmationCheckbox()) { + _ui.confCheckBoxExternal->hide(); + } + if (theme->wizardHideFolderSizeLimitCheckbox()) { + _ui.confCheckBoxSize->hide(); + _ui.confSpinBox->hide(); + _ui.confTraillingSizeLabel->hide(); + } } void OwncloudAdvancedSetupPage::setupCustomization() @@ -118,6 +127,12 @@ void OwncloudAdvancedSetupPage::initializePage() _selectiveSyncBlacklist = QStringList("/"); QTimer::singleShot(0, this, SLOT(slotSelectiveSyncClicked())); } + + ConfigFile cfgFile; + auto newFolderLimit = cfgFile.newBigFolderSizeLimit(); + _ui.confCheckBoxSize->setChecked(newFolderLimit.first); + _ui.confSpinBox->setValue(newFolderLimit.second); + _ui.confCheckBoxExternal->setChecked(cfgFile.confirmExternalStorage()); } // Called if the user changes the user- or url field. Adjust the texts and @@ -208,6 +223,13 @@ bool OwncloudAdvancedSetupPage::validatePage() startSpinner(); emit completeChanged(); + if (_ui.rSyncEverything->isChecked()) { + ConfigFile cfgFile; + cfgFile.setNewBigFolderSizeLimit(_ui.confCheckBoxSize->isChecked(), + _ui.confSpinBox->value()); + cfgFile.setConfirmExternalStorage(_ui.confCheckBoxExternal->isChecked()); + } + emit createLocalAndRemoteFolders(localFolder(), _remoteFolder); return false; } else { diff --git a/src/gui/wizard/owncloudadvancedsetuppage.ui b/src/gui/wizard/owncloudadvancedsetuppage.ui index 74ec741eaf3..bd3aa2c30a4 100644 --- a/src/gui/wizard/owncloudadvancedsetuppage.ui +++ b/src/gui/wizard/owncloudadvancedsetuppage.ui @@ -6,8 +6,8 @@ 0 0 - 917 - 493 + 1099 + 636 @@ -228,9 +228,6 @@ - - 0 - @@ -263,6 +260,61 @@ + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + + + Ask for confirmation before synchroni&zing folders larger than + + + + + + + 1000000000 + + + 500 + + + + + + + MB + + + + + + + + + Ask for confirmation before synchronizing e&xternal storages + + + + + @@ -345,5 +397,70 @@ - + + + rSyncEverything + toggled(bool) + confCheckBoxSize + setEnabled(bool) + + + 217 + 78 + + + 298 + 126 + + + + + rSyncEverything + toggled(bool) + confSpinBox + setEnabled(bool) + + + 311 + 83 + + + 952 + 134 + + + + + rSyncEverything + toggled(bool) + confTraillingSizeLabel + setEnabled(bool) + + + 277 + 76 + + + 1076 + 136 + + + + + rSyncEverything + toggled(bool) + confCheckBoxExternal + setEnabled(bool) + + + 181 + 78 + + + 382 + 174 + + + + diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp index 4c8a30bf6f9..8982b33b395 100644 --- a/src/libsync/configfile.cpp +++ b/src/libsync/configfile.cpp @@ -67,6 +67,7 @@ static const char downloadLimitC[] = "BWLimit/downloadLimit"; static const char newBigFolderSizeLimitC[] = "newBigFolderSizeLimit"; static const char useNewBigFolderSizeLimitC[] = "useNewBigFolderSizeLimit"; +static const char confirmExternalStorageC[] = "confirmExternalStorage"; static const char maxLogLinesC[] = "Logging/maxLogLines"; @@ -596,6 +597,16 @@ void ConfigFile::setNewBigFolderSizeLimit(bool isChecked, quint64 mbytes) setValue(useNewBigFolderSizeLimitC, isChecked); } +bool ConfigFile::confirmExternalStorage() const +{ + return getValue(confirmExternalStorageC, QString(), true).toBool(); +} + +void ConfigFile::setConfirmExternalStorage(bool isChecked) +{ + setValue(confirmExternalStorageC, isChecked); +} + bool ConfigFile::promptDeleteFiles() const { QSettings settings(configFile(), QSettings::IniFormat); diff --git a/src/libsync/configfile.h b/src/libsync/configfile.h index cd95f1a0bce..0fe3b3cd063 100644 --- a/src/libsync/configfile.h +++ b/src/libsync/configfile.h @@ -105,6 +105,8 @@ class OWNCLOUDSYNC_EXPORT ConfigFile /** [checked, size in MB] **/ QPair newBigFolderSizeLimit() const; void setNewBigFolderSizeLimit(bool isChecked, quint64 mbytes); + bool confirmExternalStorage() const; + void setConfirmExternalStorage(bool); static bool setConfDir(const QString &value); diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index b629b426ed9..5e3a6bbdbd8 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -86,20 +86,29 @@ int DiscoveryJob::isInSelectiveSyncBlackListCallback(void *data, const char *pat bool DiscoveryJob::checkSelectiveSyncNewFolder(const QString& path, const char *remotePerm) { - // If this path or the parent is in the white list, then we do not block this file - if (findPathInList(_selectiveSyncWhiteList, path)) { - return false; - } - if (Theme::instance()->dontSyncMountedStorageByDefault()) { - // 'M' in the permission means that it is unselected by default. (issue #5331) - if (std::strchr(remotePerm, 'M')) { - emit newBigFolder(path); - return true; + if (_syncOptions._confirmExternalStorage && std::strchr(remotePerm, 'M')) { + // 'M' in the permission means external storage. + + // Only allow it if the white list contains exactly this path (not parents) + // We want to ask confirmation for external storage even if the parents where selected + if (_selectiveSyncWhiteList.contains(path + QLatin1Char('/'))) { + return false; } + + // FIXME! if the parent folder has 'M': return false + + emit newBigFolder(path); + return true; + } + + // If this path or the parent is in the white list, then we do not block this file + if (findPathInList(_selectiveSyncWhiteList, path)) { + return false; } - if (_newBigFolderSizeLimit < 0) { + auto limit = _syncOptions._newBigFolderSizeLimit; + if (limit < 0) { // no limit, everything is allowed; return false; } @@ -113,7 +122,6 @@ bool DiscoveryJob::checkSelectiveSyncNewFolder(const QString& path, const char * _vioWaitCondition.wait(&_vioMutex); } - auto limit = _newBigFolderSizeLimit; if (result >= limit) { // we tell the UI there is a new folder emit newBigFolder(path); diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index 701581c06df..7c352c2f181 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -34,6 +34,15 @@ class Account; * if the files are new, or changed. */ +struct SyncOptions { + /** Maximum size (in Bytes) a folder can have without asking for confirmation. + * -1 means infinite */ + qint64 _newBigFolderSizeLimit = -1; + /** If a confirmation should be asked for external storages */ + bool _confirmExternalStorage = false; +}; + + /** * @brief The FileStatPointer class * @ingroup libsync @@ -197,7 +206,7 @@ class DiscoveryJob : public QObject { public: explicit DiscoveryJob(CSYNC *ctx, QObject* parent = 0) - : QObject(parent), _csync_ctx(ctx), _newBigFolderSizeLimit(-1) { + : QObject(parent), _csync_ctx(ctx) { // We need to forward the log property as csync uses thread local // and updates run in another thread _log_callback = csync_get_log_callback(); @@ -207,7 +216,7 @@ class DiscoveryJob : public QObject { QStringList _selectiveSyncBlackList; QStringList _selectiveSyncWhiteList; - qint64 _newBigFolderSizeLimit; + SyncOptions _syncOptions; Q_INVOKABLE void start(); signals: void finished(int result); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index a4e2fceabcd..b6c347fe3d6 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -71,7 +71,6 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath, , _backInTimeFiles(0) , _uploadLimit(0) , _downloadLimit(0) - , _newBigFolderSizeLimit(-1) , _checksum_hook(journal) , _anotherSyncNeeded(NoFollowUpSync) { @@ -830,7 +829,7 @@ void SyncEngine::startSync() return; } - discoveryJob->_newBigFolderSizeLimit = _newBigFolderSizeLimit; + discoveryJob->_syncOptions = _syncOptions; discoveryJob->moveToThread(&_thread); connect(discoveryJob, SIGNAL(finished(int)), this, SLOT(slotDiscoveryJobFinished(int))); connect(discoveryJob, SIGNAL(folderDiscovered(bool,QString)), diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h index d29c433b160..927c7ad5bf2 100644 --- a/src/libsync/syncengine.h +++ b/src/libsync/syncengine.h @@ -78,10 +78,7 @@ class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject bool isSyncRunning() const { return _syncRunning; } - /* Set the maximum size a folder can have without asking for confirmation - * -1 means infinite - */ - void setNewBigFolderSizeLimit(qint64 limit) { _newBigFolderSizeLimit = limit; } + void setSyncOptions(const SyncOptions &options) { _syncOptions = options; } bool ignoreHiddenFiles() const { return _csync_ctx->ignore_hidden_files; } void setIgnoreHiddenFiles(bool ignore) { _csync_ctx->ignore_hidden_files = ignore; } @@ -257,8 +254,7 @@ private slots: int _uploadLimit; int _downloadLimit; - /* maximum size a folder can have without asking for confirmation: -1 means infinite */ - qint64 _newBigFolderSizeLimit; + SyncOptions _syncOptions; // hash containing the permissions on the remote directory QHash _remotePerms; diff --git a/src/libsync/theme.cpp b/src/libsync/theme.cpp index 3a0c0b3edbb..54612b545e6 100644 --- a/src/libsync/theme.cpp +++ b/src/libsync/theme.cpp @@ -275,6 +275,15 @@ qint64 Theme::newBigFolderSizeLimit() const return 500; } +bool Theme::wizardHideExternalStorageConfirmationCheckbox() const +{ + return false; +} + +bool Theme::wizardHideFolderSizeLimitCheckbox() const +{ + return false; +} QString Theme::gitSHA1() const { @@ -479,9 +488,5 @@ QString Theme::quotaBaseFolder() const return QLatin1String("/"); } -bool Theme::dontSyncMountedStorageByDefault() const -{ - return false; -} } // end namespace client diff --git a/src/libsync/theme.h b/src/libsync/theme.h index 4e6130fd6da..a3632fb7096 100644 --- a/src/libsync/theme.h +++ b/src/libsync/theme.h @@ -219,6 +219,17 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject **/ virtual qint64 newBigFolderSizeLimit() const; + /** + * Hide the checkbox that says "Ask for confirmation before synchronizing folders larger than X MB" + * in the account wizard + */ + virtual bool wizardHideFolderSizeLimitCheckbox() const; + /** + * Hide the checkbox that says "Ask for confirmation before synchronizing external storages" + * in the account wizard + */ + virtual bool wizardHideExternalStorageConfirmationCheckbox() const; + /** * Alternative path on the server that provides access to the webdav capabilities * @@ -302,11 +313,6 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject */ virtual QString quotaBaseFolder() const; - /** - * By default, mounted storage will not be sync'ed (i.e, they will be disabled in the - * selective sync - */ - virtual bool dontSyncMountedStorageByDefault() const; protected: #ifndef TOKEN_AUTH_ONLY