From 838c072ccc2dd56b56ef256b70179361d8f226d2 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Fri, 30 Sep 2016 14:08:00 +0200 Subject: [PATCH] Folder Setup: Allow to set up more sync connects to the same folder. One local folder can now be configured as sync target for multiple accounts as long as their url and user differ. Also this patch accepts that the sync folder is behind a symlink. Also this patch fixes a bug that before the user input was taken canonically which was not working for the symlink handling. --- src/gui/folderman.cpp | 47 +++++++++++--------- src/gui/folderman.h | 2 +- src/gui/folderwizard.cpp | 14 ++++-- src/gui/folderwizard.h | 3 +- src/gui/wizard/owncloudadvancedsetuppage.cpp | 7 ++- 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 7a9e1db5b..0a7dc28c6 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -1172,17 +1172,16 @@ QString FolderMan::statusToString( SyncResult syncStatus, bool paused ) const return folderMessage; } -QString FolderMan::checkPathValidityForNewFolder(const QString& path, bool forNewDirectory) +QString FolderMan::checkPathValidityForNewFolder(const QString& path, const QUrl &serverUrl, bool forNewDirectory) { if (path.isEmpty()) { return tr("No valid folder selected!"); } QFileInfo selFile( path ); - QString userInput = selFile.canonicalFilePath(); if (!selFile.exists()) { - return checkPathValidityForNewFolder(selFile.dir().path(), true); + return checkPathValidityForNewFolder(selFile.dir().path(), serverUrl, true); } if( !selFile.isDir() ) { @@ -1203,37 +1202,41 @@ QString FolderMan::checkPathValidityForNewFolder(const QString& path, bool forNe } if( ! folderDir.endsWith(QLatin1Char('/')) ) folderDir.append(QLatin1Char('/')); - if (QDir::cleanPath(f->path()) == QDir::cleanPath(userInput) - && QDir::cleanPath(QDir(f->path()).canonicalPath()) == QDir(userInput).canonicalPath()) { - return tr("The local folder %1 is already used in a folder sync connection. " - "Please pick another one!") - .arg(QDir::toNativeSeparators(userInput)); - } - if (!forNewDirectory && QDir::cleanPath(folderDir).startsWith(QDir::cleanPath(userInput)+'/')) { + const QString folderDirClean = QDir::cleanPath(folderDir)+'/'; + const QString userDirClean = QDir::cleanPath(path)+'/'; + bool differentPathes = QDir::cleanPath(folderDir) != QDir::cleanPath(path); + + if (!forNewDirectory && differentPathes && folderDirClean.startsWith(userDirClean)) { return tr("The local folder %1 already contains a folder used in a folder sync connection. " "Please pick another one!") - .arg(QDir::toNativeSeparators(userInput)); + .arg(QDir::toNativeSeparators(path)); } - QString absCleanUserFolder = QDir::cleanPath(QDir(userInput).canonicalPath())+'/'; - if (!forNewDirectory && QDir::cleanPath(folderDir).startsWith(absCleanUserFolder) ) { - return tr("The local folder %1 is a symbolic link. " - "The link target already contains a folder used in a folder sync connection. " - "Please pick another one!") - .arg(QDir::toNativeSeparators(userInput)); - } + QString absCleanUserFolder = QDir::cleanPath(QDir(path).canonicalPath())+'/'; - if (QDir::cleanPath(QString(userInput)).startsWith( QDir::cleanPath(folderDir)+'/')) { + if (differentPathes && userDirClean.startsWith( folderDirClean )) { return tr("The local folder %1 is already contained in a folder used in a folder sync connection. " "Please pick another one!") - .arg(QDir::toNativeSeparators(userInput)); + .arg(QDir::toNativeSeparators(path)); } - if (absCleanUserFolder.startsWith( QDir::cleanPath(folderDir)+'/')) { + if (differentPathes && absCleanUserFolder.startsWith( folderDirClean ) && + absCleanUserFolder != folderDirClean ) { return tr("The local folder %1 is a symbolic link. " "The link target is already contained in a folder used in a folder sync connection. " "Please pick another one!") - .arg(QDir::toNativeSeparators(userInput)); + .arg(QDir::toNativeSeparators(path)); + } + + if( serverUrl.isValid() && absCleanUserFolder == folderDir ) { + QUrl folderUrl = f->accountState()->account()->url(); + QString user = f->accountState()->account()->credentials()->user(); + folderUrl.setUserName(user); + + if( serverUrl == folderUrl ) { + return tr("There is already a sync from the server to this local folder. " + "Please pick another local folder!"); + } } } diff --git a/src/gui/folderman.h b/src/gui/folderman.h index d312d9b0c..19a515541 100644 --- a/src/gui/folderman.h +++ b/src/gui/folderman.h @@ -105,7 +105,7 @@ public: * * @returns an empty string if it is allowed, or an error if it is not allowed */ - QString checkPathValidityForNewFolder(const QString &path, bool forNewDirectory = false); + QString checkPathValidityForNewFolder(const QString &path, const QUrl& serverUrl = QUrl(), bool forNewDirectory = false); /** * While ignoring hidden files can theoretically be switched per folder, diff --git a/src/gui/folderwizard.cpp b/src/gui/folderwizard.cpp index ba7f2de8c..2c614f00e 100644 --- a/src/gui/folderwizard.cpp +++ b/src/gui/folderwizard.cpp @@ -56,8 +56,9 @@ QString FormatWarningsWizardPage::formatWarnings(const QStringList &warnings) co return ret; } -FolderWizardLocalPath::FolderWizardLocalPath() - : FormatWarningsWizardPage() +FolderWizardLocalPath::FolderWizardLocalPath(AccountPtr account) + : FormatWarningsWizardPage(), + _account(account) { _ui.setupUi(this); registerField(QLatin1String("sourceFolder*"), _ui.localFolderLineEdit); @@ -89,8 +90,13 @@ void FolderWizardLocalPath::cleanupPage() bool FolderWizardLocalPath::isComplete() const { + QUrl serverUrl = _account->url(); + serverUrl.setUserName( _account->credentials()->user() ); + QString errorStr = FolderMan::instance()->checkPathValidityForNewFolder( - QDir::fromNativeSeparators(_ui.localFolderLineEdit->text())); + QDir::fromNativeSeparators(_ui.localFolderLineEdit->text()), serverUrl); + + bool isOk = errorStr.isEmpty(); QStringList warnStrings; @@ -527,7 +533,7 @@ void FolderWizardSelectiveSync::cleanupPage() FolderWizard::FolderWizard(AccountPtr account, QWidget *parent) : QWizard(parent), - _folderWizardSourcePage(new FolderWizardLocalPath), + _folderWizardSourcePage(new FolderWizardLocalPath(account)), _folderWizardTargetPage(0), _folderWizardSelectiveSyncPage(new FolderWizardSelectiveSync(account)) { diff --git a/src/gui/folderwizard.h b/src/gui/folderwizard.h index bbed262c7..ed0718bb7 100644 --- a/src/gui/folderwizard.h +++ b/src/gui/folderwizard.h @@ -49,7 +49,7 @@ class FolderWizardLocalPath : public FormatWarningsWizardPage { Q_OBJECT public: - FolderWizardLocalPath(); + FolderWizardLocalPath(AccountPtr account); ~FolderWizardLocalPath(); virtual bool isComplete() const Q_DECL_OVERRIDE; @@ -63,6 +63,7 @@ protected slots: private: Ui_FolderWizardSourcePage _ui; Folder::Map _folderMap; + AccountPtr _account; }; diff --git a/src/gui/wizard/owncloudadvancedsetuppage.cpp b/src/gui/wizard/owncloudadvancedsetuppage.cpp index 0142fa4eb..c0a038151 100644 --- a/src/gui/wizard/owncloudadvancedsetuppage.cpp +++ b/src/gui/wizard/owncloudadvancedsetuppage.cpp @@ -125,8 +125,13 @@ void OwncloudAdvancedSetupPage::initializePage() void OwncloudAdvancedSetupPage::updateStatus() { const QString locFolder = localFolder(); + const QString url = static_cast(wizard())->ocUrl(); + const QString user = static_cast(wizard())->getCredentials()->user(); + + QUrl serverUrl(url); + serverUrl.setUserName(user); // check if the local folder exists. If so, and if its not empty, show a warning. - QString errorStr = FolderMan::instance()->checkPathValidityForNewFolder(locFolder); + QString errorStr = FolderMan::instance()->checkPathValidityForNewFolder(locFolder, serverUrl); _localFolderValid = errorStr.isEmpty(); QString t;