QString shortGuiLocalPath() const;
/**
- * local folder path
+ * canonical local folder path, always ends with /
*/
QString path() const;
/**
- * wrapper for QDir::cleanPath("Z:\\"), which returns "Z:\\", but we need "Z:" instead
+ * cleaned canonical folder path, like path() but never ends with a /
+ *
+ * Wrapper for QDir::cleanPath(path()) except for "Z:/",
+ * where it returns "Z:" instead of "Z:/".
*/
QString cleanPath() const;
return folderMessage;
}
-QString FolderMan::checkPathValidityForNewFolder(const QString& path, const QUrl &serverUrl, bool forNewDirectory)
+QString FolderMan::checkPathValidityForNewFolder(const QString& path, const QUrl &serverUrl, bool forNewDirectory) const
{
if (path.isEmpty()) {
return tr("No valid folder selected!");
}
+QString FolderMan::findGoodPathForNewSyncFolder(const QString &basePath, const QUrl &serverUrl) const
+{
+ QString folder = basePath;
+
+ // If the parent folder is a sync folder or contained in one, we can't
+ // possibly find a valid sync folder inside it.
+ // Example: Someone syncs their home directory. Then ~/foobar is not
+ // going to be an acceptable sync folder path for any value of foobar.
+ QString parentFolder = QFileInfo(folder).dir().canonicalPath();
+ if (FolderMan::instance()->folderForPath(parentFolder)) {
+ // Any path with that parent is going to be unacceptable,
+ // so just keep it as-is.
+ return basePath;
+ }
+
+ int attempt = 1;
+ forever {
+ const bool isGood =
+ !QFileInfo(folder).exists()
+ && FolderMan::instance()->checkPathValidityForNewFolder(folder, serverUrl).isEmpty();
+ if (isGood) {
+ break;
+ }
+
+ // Count attempts and give up eventually
+ attempt++;
+ if (attempt > 100) {
+ return basePath;
+ }
+
+ folder = basePath + QString::number(attempt);
+ }
+
+ return folder;
+}
+
bool FolderMan::ignoreHiddenFiles() const
{
if (_folderMap.empty()) {
* Check if @a path is a valid path for a new folder considering the already sync'ed items.
* Make sure that this folder, or any subfolder is not sync'ed already.
*
+ * Note that different accounts are allowed to sync to the same folder.
+ *
* \a forNewDirectory is internal and is used for recursion.
*
* @returns an empty string if it is allowed, or an error if it is not allowed
*/
- QString checkPathValidityForNewFolder(const QString &path, const QUrl& serverUrl = QUrl(), bool forNewDirectory = false);
+ QString checkPathValidityForNewFolder(const QString &path, const QUrl& serverUrl = QUrl(), bool forNewDirectory = false) const;
+
+ /**
+ * Attempts to find a non-existing, acceptable path for creating a new sync folder.
+ *
+ * Uses \a basePath as the baseline. It'll return this path if it's acceptable.
+ *
+ * Note that this can fail. If someone syncs ~ and \a basePath is ~/ownCloud, no
+ * subfolder of ~ would be a good candidate. When that happens \a basePath
+ * is returned.
+ */
+ QString findGoodPathForNewSyncFolder(const QString &basePath, const QUrl &serverUrl) const;
/**
* While ignoring hidden files can theoretically be switched per folder,
_ui.localFolderChooseBtn->setToolTip(tr("Click to select a local folder to sync."));
QString defaultPath = QDir::homePath() + QLatin1Char('/') + Theme::instance()->appName();
+ defaultPath = FolderMan::instance()->findGoodPathForNewSyncFolder(defaultPath, account->url());
_ui.localFolderLineEdit->setText( QDir::toNativeSeparators( defaultPath ) );
_ui.localFolderLineEdit->setToolTip(tr("Enter the path to the local folder."));
_ui.lSelectiveSyncSizeLabel->setText(QString());
_ui.lSyncEverythingSizeLabel->setText(QString());
+ // Update the local folder - this is not guaranteed to find a good one
+ QString goodLocalFolder = FolderMan::instance()->findGoodPathForNewSyncFolder(localFolder(), serverUrl());
+ wizard()->setProperty("localFolder", goodLocalFolder);
+
// call to init label
updateStatus();
void OwncloudAdvancedSetupPage::updateStatus()
{
const QString locFolder = localFolder();
- const QString url = static_cast<OwncloudWizard *>(wizard())->ocUrl();
- const QString user = static_cast<OwncloudWizard *>(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, serverUrl);
+ QString errorStr = FolderMan::instance()->checkPathValidityForNewFolder(locFolder, serverUrl());
_localFolderValid = errorStr.isEmpty();
QString t;
_progressIndi->stopAnimation();
}
+QUrl OwncloudAdvancedSetupPage::serverUrl() const
+{
+ const QString urlString = static_cast<OwncloudWizard *>(wizard())->ocUrl();
+ const QString user = static_cast<OwncloudWizard *>(wizard())->getCredentials()->user();
+
+ QUrl url(urlString);
+ url.setUserName(user);
+ return url;
+}
+
int OwncloudAdvancedSetupPage::nextId() const
{
return WizardCommon::Page_Result;
bool dataChanged();
void startSpinner();
void stopSpinner();
+ QUrl serverUrl() const;
Ui_OwncloudAdvancedSetupPage _ui;
bool _checking;
QVERIFY(!folderman->checkPathValidityForNewFolder("/usr/bin/somefolder").isNull());
#else
QSKIP("Test not supported with Qt4", SkipSingle);
+#endif
+ }
+
+ void testFindGoodPathForNewSyncFolder()
+ {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
+ // SETUP
+
+ QTemporaryDir dir;
+ ConfigFile::setConfDir(dir.path()); // we don't want to pollute the user's config file
+ QVERIFY(dir.isValid());
+ QDir dir2(dir.path());
+ QVERIFY(dir2.mkpath("sub/ownCloud1/folder/f"));
+ QVERIFY(dir2.mkpath("ownCloud"));
+ QVERIFY(dir2.mkpath("ownCloud2"));
+ QVERIFY(dir2.mkpath("ownCloud2/foo"));
+ QVERIFY(dir2.mkpath("sub/free"));
+ QVERIFY(dir2.mkpath("free2/sub"));
+ QString dirPath = dir2.canonicalPath();
+
+ AccountPtr account = Account::create();
+ QUrl url("http://example.de");
+ HttpCredentialsTest *cred = new HttpCredentialsTest("testuser", "secret");
+ account->setCredentials(cred);
+ account->setUrl( url );
+
+ AccountStatePtr newAccountState(new AccountState(account));
+ FolderMan *folderman = FolderMan::instance();
+ QCOMPARE(folderman, &_fm);
+ QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/sub/ownCloud/")));
+ QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/ownCloud2/")));
+
+ // TEST
+
+ QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/oc", url),
+ QString(dirPath + "/oc"));
+ QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/ownCloud", url),
+ QString(dirPath + "/ownCloud3"));
+ QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/ownCloud2", url),
+ QString(dirPath + "/ownCloud22"));
+ QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/ownCloud2/foo", url),
+ QString(dirPath + "/ownCloud2/foo"));
+ QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/ownCloud2/bar", url),
+ QString(dirPath + "/ownCloud2/bar"));
+ QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/sub", url),
+ QString(dirPath + "/sub2"));
+#else
+ QSKIP("Test not supported with Qt4", SkipSingle);
#endif
}
};