Merge branch 'master' into slideshow

This commit is contained in:
Roeland Jago Douma 2018-11-02 10:43:01 +01:00 committed by GitHub
commit e6f1d7632a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 39422 additions and 41851 deletions

View file

@ -14,7 +14,7 @@ pipeline:
cd /tmp &&
git clone https://github.com/frankosterfeld/qtkeychain.git &&
cd qtkeychain &&
git checkout v0.8.0 &&
git checkout v0.9.1 &&
mkdir build &&
cd build &&
cmake ../ &&
@ -42,7 +42,7 @@ pipeline:
cd /tmp &&
git clone https://github.com/frankosterfeld/qtkeychain.git &&
cd qtkeychain &&
git checkout v0.8.0 &&
git checkout v0.9.1 &&
mkdir build &&
cd build &&
cmake ../ &&
@ -70,7 +70,7 @@ pipeline:
cd /tmp &&
git clone https://github.com/frankosterfeld/qtkeychain.git &&
cd qtkeychain &&
git checkout v0.8.0 &&
git checkout v0.9.1 &&
mkdir build &&
cd build &&
cmake ../ &&
@ -100,7 +100,7 @@ pipeline:
cd /tmp &&
git clone https://github.com/frankosterfeld/qtkeychain.git &&
cd qtkeychain &&
git checkout v0.8.0 &&
git checkout v0.9.1 &&
mkdir build &&
cd build &&
cmake ../ &&
@ -132,7 +132,7 @@ pipeline:
cd /tmp &&
git clone https://github.com/frankosterfeld/qtkeychain.git &&
cd qtkeychain &&
git checkout v0.8.0 &&
git checkout v0.9.1 &&
mkdir build &&
cd build &&
cmake ../ &&
@ -165,7 +165,7 @@ pipeline:
cd /tmp &&
git clone https://github.com/frankosterfeld/qtkeychain.git &&
cd qtkeychain &&
git checkout v0.8.0 &&
git checkout v0.9.1 &&
mkdir build &&
cd build &&
cmake ../ &&

View file

@ -18,11 +18,11 @@ if [ $SUFFIX != "master" ]; then
SUFFIX="PR-$SUFFIX"
fi
#QtKeyChain 0.8.0
#QtKeyChain 0.9.1
cd /build
git clone https://github.com/frankosterfeld/qtkeychain.git
cd qtkeychain
git checkout v0.8.0
git checkout v0.9.1
mkdir build
cd build
cmake -D CMAKE_INSTALL_PREFIX=/usr ../

View file

@ -272,10 +272,12 @@ bool FileSystem::openAndSeekFileSharedRead(QFile *file, QString *errorOrNull, qi
int fd = _open_osfhandle((intptr_t)fileHandle, _O_RDONLY);
if (fd == -1) {
error = "could not make fd from handle";
CloseHandle(fileHandle);
return false;
}
if (!file->open(fd, QIODevice::ReadOnly, QFile::AutoCloseHandle)) {
error = file->errorString();
_close(fd); // implicitly closes fileHandle
return false;
}

View file

@ -666,7 +666,21 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
goto error;
}
while ((dirent = csync_vio_readdir(ctx, dh))) {
while (true) {
// Get the next item in the directory
errno = 0;
dirent = csync_vio_readdir(ctx, dh);
if (!dirent) {
if (errno != 0) {
// Note: Windows vio converts any error into EACCES
qCWarning(lcUpdate, "readdir failed for file in %s - errno %d", uri, errno);
goto error;
}
// Normal case: End of items in directory
break;
}
/* Conversion error */
if (dirent->path.isEmpty() && !dirent->original_path.isEmpty()) {
ctx->status_code = CSYNC_STATUS_INVALID_CHARACTERS;

View file

@ -156,6 +156,7 @@ std::unique_ptr<csync_file_stat_t> csync_vio_local_readdir(csync_vio_handle_t *d
// might be error, check!
int dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES) {
qCWarning(lcCSyncVIOLocal, "FindNextFile error %d", dwError);
errno = EACCES; // no more files is fine. Otherwise EACCESS
}
return nullptr;

View file

@ -53,6 +53,7 @@ set(client_SRCS
folderman.cpp
folderstatusmodel.cpp
folderstatusdelegate.cpp
folderstatusview.cpp
folderwatcher.cpp
folderwizard.cpp
generalsettings.cpp

View file

@ -52,7 +52,7 @@ AccountManager *AccountManager::instance()
bool AccountManager::restore()
{
auto settings = ConfigFile::settingsWithGroup(QLatin1String(accountsC));
if (settings->status() != QSettings::NoError) {
if (settings->status() != QSettings::NoError || !settings->isWritable()) {
qCWarning(lcAccountManager) << "Could not read settings from" << settings->fileName()
<< settings->status();
return false;

View file

@ -117,7 +117,7 @@
</layout>
</item>
<item row="2" column="0">
<widget class="QTreeView" name="_folderList">
<widget class="OCC::FolderStatusView" name="_folderList">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -275,6 +275,11 @@
<extends>QToolButton</extends>
<header>sslbutton.h</header>
</customwidget>
<customwidget>
<class>OCC::FolderStatusView</class>
<extends>QTreeView</extends>
<header>folderstatusview.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View file

@ -125,7 +125,8 @@ Application::Application(int &argc, char **argv)
setAttribute(Qt::AA_UseHighDpiPixmaps, true);
auto confDir = ConfigFile().configPath();
if (!QFileInfo(confDir).exists()) {
if (confDir.endsWith('/')) confDir.chop(1); // macOS 10.11.x does not like trailing slash for rename/move.
if (!QFileInfo(confDir).isDir()) {
// Migrate from version <= 2.4
setApplicationName(_theme->appNameGUI());
#ifndef QT_WARNING_DISABLE_DEPRECATED // Was added in Qt 5.9
@ -136,6 +137,7 @@ Application::Application(int &argc, char **argv)
// We need to use the deprecated QDesktopServices::storageLocation because of its Qt4
// behavior of adding "data" to the path
QString oldDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
if (oldDir.endsWith('/')) oldDir.chop(1); // macOS 10.11.x does not like trailing slash for rename/move.
QT_WARNING_POP
setApplicationName(_theme->appName());
if (QFileInfo(oldDir).isDir()) {

View file

@ -645,9 +645,13 @@ void Folder::startSync(const QStringList &pathList)
}
return interval;
}();
if (_folderWatcher && _folderWatcher->isReliable() && _timeSinceLastFullLocalDiscovery.isValid()
&& (fullLocalDiscoveryInterval.count() < 0
|| _timeSinceLastFullLocalDiscovery.hasExpired(fullLocalDiscoveryInterval.count()))) {
bool hasDoneFullLocalDiscovery = _timeSinceLastFullLocalDiscovery.isValid();
bool periodicFullLocalDiscoveryNow =
fullLocalDiscoveryInterval.count() >= 0 // negative means we don't require periodic full runs
&& _timeSinceLastFullLocalDiscovery.hasExpired(fullLocalDiscoveryInterval.count());
if (_folderWatcher && _folderWatcher->isReliable()
&& hasDoneFullLocalDiscovery
&& !periodicFullLocalDiscoveryNow) {
qCInfo(lcFolder) << "Allowing local discovery to read from the database";
_engine->setLocalDiscoveryOptions(LocalDiscoveryStyle::DatabaseAndFilesystem, _localDiscoveryPaths);

View file

@ -1242,25 +1242,45 @@ QString FolderMan::trayTooltipStatusString(
return folderMessage;
}
QString FolderMan::checkPathValidityForNewFolder(const QString &path, const QUrl &serverUrl, bool forNewDirectory) const
static QString checkPathValidityRecursive(const QString &path)
{
if (path.isEmpty()) {
return tr("No valid folder selected!");
return FolderMan::tr("No valid folder selected!");
}
QFileInfo selFile(path);
if (!selFile.exists()) {
return checkPathValidityForNewFolder(selFile.dir().path(), serverUrl, true);
return checkPathValidityRecursive(selFile.dir().path());
}
if (!selFile.isDir()) {
return tr("The selected path is not a folder!");
return FolderMan::tr("The selected path is not a folder!");
}
if (!selFile.isWritable()) {
return tr("You have no permission to write to the selected folder!");
return FolderMan::tr("You have no permission to write to the selected folder!");
}
return QString();
}
// QFileInfo::canonicalPath returns an empty string if the file does not exist.
// This function also works with files that does not exist and resolve the symlinks in the
// parent directories.
static QString canonicalPath(const QString &path)
{
QFileInfo selFile(path);
if (!selFile.exists()) {
return canonicalPath(selFile.dir().path()) + '/' + selFile.fileName();
}
return selFile.canonicalFilePath();
}
QString FolderMan::checkPathValidityForNewFolder(const QString &path, const QUrl &serverUrl) const
{
QString recursiveValidity = checkPathValidityRecursive(path);
if (!recursiveValidity.isEmpty())
return recursiveValidity;
// check if the local directory isn't used yet in another ownCloud sync
Qt::CaseSensitivity cs = Qt::CaseSensitive;
@ -1268,57 +1288,28 @@ QString FolderMan::checkPathValidityForNewFolder(const QString &path, const QUrl
cs = Qt::CaseInsensitive;
}
const QString userDir = QDir::cleanPath(canonicalPath(path)) + '/';
for (auto i = _folderMap.constBegin(); i != _folderMap.constEnd(); ++i) {
Folder *f = static_cast<Folder *>(i.value());
QString folderDir = QDir(f->path()).canonicalPath();
if (folderDir.isEmpty()) {
continue;
}
if (!folderDir.endsWith(QLatin1Char('/'), cs))
folderDir.append(QLatin1Char('/'));
QString folderDir = QDir::cleanPath(canonicalPath(f->path())) + '/';
const QString folderDirClean = QDir::cleanPath(folderDir) + '/';
const QString userDirClean = QDir::cleanPath(path) + '/';
// folderDir follows sym links, path not.
bool differentPathes = !Utility::fileNamesEqual(QDir::cleanPath(folderDir), QDir::cleanPath(path));
if (!forNewDirectory && differentPathes && folderDirClean.startsWith(userDirClean, cs)) {
bool differentPaths = QString::compare(folderDir, userDir, cs) != 0;
if (differentPaths && folderDir.startsWith(userDir, cs)) {
return tr("The local folder %1 already contains a folder used in a folder sync connection. "
"Please pick another one!")
.arg(QDir::toNativeSeparators(path));
}
// QDir::cleanPath keeps links
// canonicalPath() remove symlinks and uses the symlink targets.
QString absCleanUserFolder = QDir::cleanPath(QDir(path).canonicalPath()) + '/';
if ((forNewDirectory || differentPathes) && userDirClean.startsWith(folderDirClean, cs)) {
if (differentPaths && userDir.startsWith(folderDir, cs)) {
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(path));
}
// both follow symlinks.
bool cleanUserEqualsCleanFolder = Utility::fileNamesEqual(absCleanUserFolder, folderDirClean);
if (differentPathes && absCleanUserFolder.startsWith(folderDirClean, cs) && !cleanUserEqualsCleanFolder) {
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(path));
}
if (differentPathes && folderDirClean.startsWith(absCleanUserFolder, cs) && !cleanUserEqualsCleanFolder && !forNewDirectory) {
return tr("The local folder %1 contains a symbolic link. "
"The link target contains an already synced folder. "
"Please pick another one!")
.arg(QDir::toNativeSeparators(path));
}
// if both pathes are equal, the server url needs to be different
// otherwise it would mean that a new connection from the same local folder
// to the same account is added which is not wanted. The account must differ.
if (serverUrl.isValid() && Utility::fileNamesEqual(absCleanUserFolder, folderDir)) {
if (serverUrl.isValid() && !differentPaths) {
QUrl folderUrl = f->accountState()->account()->url();
QString user = f->accountState()->account()->credentials()->user();
folderUrl.setUserName(user);

View file

@ -127,11 +127,9 @@ public:
*
* 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) const;
QString checkPathValidityForNewFolder(const QString &path, const QUrl &serverUrl = QUrl()) const;
/**
* Attempts to find a non-existing, acceptable path for creating a new sync folder.

View file

@ -16,6 +16,7 @@
#include "folderstatusdelegate.h"
#include "folderstatusmodel.h"
#include "folderstatusview.h"
#include "folderman.h"
#include "accountstate.h"
#include <theme.h>
@ -24,6 +25,7 @@
#include <QFileIconProvider>
#include <QPainter>
#include <QApplication>
#include <QMouseEvent>
inline static QFont makeAliasFont(const QFont &normalFont)
{
@ -110,6 +112,10 @@ int FolderStatusDelegate::rootFolderHeightWithoutErrors(const QFontMetrics &fm,
void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.data(AddButton).toBool()) {
const_cast<QStyleOptionViewItem &>(option).showDecorationSelected = false;
}
QStyledItemDelegate::paint(painter, option, index);
auto textAlign = Qt::AlignLeft;
@ -129,15 +135,15 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
int margin = subFm.height() / 4;
if (index.data(AddButton).toBool()) {
QSize hint = sizeHint(option, index);
QStyleOptionButton opt;
static_cast<QStyleOption &>(opt) = option;
opt.state &= ~QStyle::State_Selected;
opt.state |= QStyle::State_Raised;
if (opt.state & QStyle::State_Enabled && opt.state & QStyle::State_MouseOver && index == _pressedIndex) {
opt.state |= QStyle::State_Sunken;
} else {
opt.state |= QStyle::State_Raised;
}
opt.text = addFolderText();
opt.rect.setWidth(qMin(opt.rect.width(), hint.width()));
opt.rect.adjust(0, aliasMargin, 0, -aliasMargin);
opt.rect = QStyle::visualRect(option.direction, option.rect, opt.rect);
opt.rect = addButtonRect(option.rect, option.direction);
painter->save();
painter->setFont(qApp->font("QPushButton"));
QApplication::style()->drawControl(QStyle::CE_PushButton, &opt, painter, option.widget);
@ -352,6 +358,27 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
bool FolderStatusDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
{
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(option.widget)) {
QMouseEvent *me = static_cast<QMouseEvent *>(event);
QModelIndex index;
if (me->buttons()) {
index = view->indexAt(me->pos());
}
if (_pressedIndex != index) {
_pressedIndex = index;
view->viewport()->update();
}
}
break;
case QEvent::MouseButtonRelease:
_pressedIndex = QModelIndex();
break;
default:
break;
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
@ -375,6 +402,16 @@ QRect FolderStatusDelegate::optionsButtonRect(QRect within, Qt::LayoutDirection
return QStyle::visualRect(direction, within, r);
}
QRect FolderStatusDelegate::addButtonRect(QRect within, Qt::LayoutDirection direction)
{
QFontMetrics fm(qApp->font("QPushButton"));
QStyleOptionButton opt;
opt.text = addFolderText();
QSize size = QApplication::style()->sizeFromContents(QStyle::CT_PushButton, &opt, fm.size(Qt::TextSingleLine, opt.text)).expandedTo(QApplication::globalStrut());
QRect r(QPoint(within.left(), within.top() + within.height() / 2 - size.height() / 2), size);
return QStyle::visualRect(direction, within, r);
}
QRect FolderStatusDelegate::errorsListRect(QRect within)
{
QFont font = QFont();

View file

@ -57,11 +57,13 @@ public:
* return the position of the option button within the item
*/
static QRect optionsButtonRect(QRect within, Qt::LayoutDirection direction);
static QRect addButtonRect(QRect within, Qt::LayoutDirection direction);
static QRect errorsListRect(QRect within);
static int rootFolderHeightWithoutErrors(const QFontMetrics &fm, const QFontMetrics &aliasFm);
private:
static QString addFolderText();
QPersistentModelIndex _pressedIndex;
};
} // namespace OCC

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2018 by J-P Nurmi <jpnurmi@gmail.com>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 "folderstatusview.h"
#include "folderstatusdelegate.h"
namespace OCC {
FolderStatusView::FolderStatusView(QWidget *parent) : QTreeView(parent)
{
}
QModelIndex FolderStatusView::indexAt(const QPoint &point) const
{
QModelIndex index = QTreeView::indexAt(point);
if (index.data(FolderStatusDelegate::AddButton).toBool() && !visualRect(index).contains(point)) {
return QModelIndex();
}
return index;
}
QRect FolderStatusView::visualRect(const QModelIndex &index) const
{
QRect rect = QTreeView::visualRect(index);
if (index.data(FolderStatusDelegate::AddButton).toBool()) {
return FolderStatusDelegate::addButtonRect(rect, layoutDirection());
}
return rect;
}
} // namespace OCC

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2018 by J-P Nurmi <jpnurmi@gmail.com>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 FOLDERSTATUSVIEW_H
#define FOLDERSTATUSVIEW_H
#include <QTreeView>
namespace OCC {
/**
* @brief The FolderStatusView class
* @ingroup gui
*/
class FolderStatusView : public QTreeView
{
Q_OBJECT
public:
explicit FolderStatusView(QWidget *parent = nullptr);
QModelIndex indexAt(const QPoint &point) const override;
QRect visualRect(const QModelIndex &index) const override;
};
} // namespace OCC
#endif // FOLDERSTATUSVIEW_H

View file

@ -66,8 +66,10 @@ FolderWizardLocalPath::FolderWizardLocalPath(const AccountPtr &account)
connect(_ui.localFolderChooseBtn, &QAbstractButton::clicked, this, &FolderWizardLocalPath::slotChooseLocalFolder);
_ui.localFolderChooseBtn->setToolTip(tr("Click to select a local folder to sync."));
QUrl serverUrl = _account->url();
serverUrl.setUserName(_account->credentials()->user());
QString defaultPath = QDir::homePath() + QLatin1Char('/') + Theme::instance()->appName();
defaultPath = FolderMan::instance()->findGoodPathForNewSyncFolder(defaultPath, account->url());
defaultPath = FolderMan::instance()->findGoodPathForNewSyncFolder(defaultPath, serverUrl);
_ui.localFolderLineEdit->setText(QDir::toNativeSeparators(defaultPath));
_ui.localFolderLineEdit->setToolTip(tr("Enter the path to the local folder."));

View file

@ -631,7 +631,7 @@ void ShareUserLine::displayPermissions()
// edit is independent of reshare
if (perm & SharePermissionShare)
_permissionReshare->setChecked(Qt::Checked);
_permissionReshare->setChecked(true);
if(!_isFile){
_permissionCreate->setChecked(perm & SharePermissionCreate);

View file

@ -13,6 +13,8 @@
*/
#include <QVariant>
#include <QMenu>
#include <QClipboard>
#include "wizard/owncloudoauthcredspage.h"
#include "theme.h"
@ -48,6 +50,16 @@ OwncloudOAuthCredsPage::OwncloudOAuthCredsPage()
if (_asyncAuth)
_asyncAuth->openBrowser();
});
_ui.openLinkButton->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(_ui.openLinkButton, &QWidget::customContextMenuRequested, [this](const QPoint &pos) {
auto menu = new QMenu(_ui.openLinkButton);
menu->addAction(tr("Copy link to clipboard"), this, [this] {
if (_asyncAuth)
QApplication::clipboard()->setText(_asyncAuth->authorisationLink().toString(QUrl::FullyEncoded));
});
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->popup(_ui.openLinkButton->mapToGlobal(pos));
});
}
void OwncloudOAuthCredsPage::initializePage()

View file

@ -24,7 +24,6 @@
#include <QNetworkAccessManager>
#include <QPropertyAnimation>
#include <QGraphicsPixmapItem>
#include <QtSvg/QSvgRenderer>
#include "QProgressIndicator.h"
@ -278,12 +277,19 @@ QString OwncloudSetupPage::url() const
bool OwncloudSetupPage::validatePage()
{
if (!_authTypeKnown) {
QString u = url();
QUrl qurl(u);
if (!qurl.isValid() || qurl.host().isEmpty()) {
setErrorString(tr("Invalid URL"), false);
return false;
}
setErrorString(QString(), false);
_checking = true;
startSpinner();
emit completeChanged();
emit determineAuthType(url());
emit determineAuthType(u);
return false;
} else {
// connecting is running

View file

@ -41,6 +41,13 @@ class WebEnginePage : public QWebEnginePage {
public:
WebEnginePage(QWebEngineProfile *profile, QObject* parent = nullptr);
QWebEnginePage * createWindow(QWebEnginePage::WebWindowType type) override;
void setUrl(const QUrl &url);
protected:
bool certificateError(const QWebEngineCertificateError &certificateError) override;
private:
QUrl _rootUrl;
};
// We need a separate class here, since we cannot simply return the same WebEnginePage object
@ -146,6 +153,19 @@ QWebEnginePage * WebEnginePage::createWindow(QWebEnginePage::WebWindowType type)
return view;
}
void WebEnginePage::setUrl(const QUrl &url) {
QWebEnginePage::setUrl(url);
_rootUrl = url;
}
bool WebEnginePage::certificateError(const QWebEngineCertificateError &certificateError) {
if (certificateError.error() == QWebEngineCertificateError::CertificateAuthorityInvalid) {
return certificateError.url().host() == _rootUrl.host();
}
return false;
}
ExternalWebEnginePage::ExternalWebEnginePage(QWebEngineProfile *profile, QObject* parent) : QWebEnginePage(profile, parent) {
}

View file

@ -379,11 +379,12 @@ bool HttpCredentials::refreshAccessToken()
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
QString accessToken = json["access_token"].toString();
if (reply->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError || json.isEmpty()) {
// Network error maybe?
if (jsonParseError.error != QJsonParseError::NoError || json.isEmpty()) {
// Invalid or empty JSON: Network error maybe?
qCWarning(lcHttpCredentials) << "Error while refreshing the token" << reply->errorString() << jsonData << jsonParseError.errorString();
} else if (accessToken.isEmpty()) {
// The token is no longer valid.
// If the json was valid, but the reply did not contain an access token, the token
// is considered expired. (Usually the HTTP reply code is 400)
qCDebug(lcHttpCredentials) << "Expired refresh token. Logging out";
_refreshToken.clear();
} else {

View file

@ -381,13 +381,11 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file, con
std::unique_ptr<csync_file_stat_t> file_stat(new csync_file_stat_t);
file_stat->path = file.toUtf8();
file_stat->size = -1;
file_stat->modtime = -1;
propertyMapToFileStat(map, file_stat.get());
if (file_stat->type == ItemTypeDirectory)
file_stat->size = 0;
if (file_stat->type == ItemTypeSkip
|| file_stat->size == -1
|| file_stat->modtime == -1
|| file_stat->remotePerm.isNull()
|| file_stat->etag.isEmpty()
|| file_stat->file_id.isEmpty()) {

View file

@ -338,7 +338,8 @@ QString Theme::about() const
.arg("http://" MIRALL_STRINGIFY(APPLICATION_DOMAIN))
.arg(MIRALL_STRINGIFY(APPLICATION_DOMAIN));
devString += tr("<p>This release was supplied by the Nextcloud GmbH</p>");
devString += tr("<p>This release was supplied by %1</p>")
.arg(APPLICATION_VENDOR);
devString += gitSHA1();

View file

@ -146,6 +146,12 @@ private slots:
// Invalid paths
QVERIFY(!folderman->checkPathValidityForNewFolder("").isNull());
// REMOVE ownCloud2 from the filesystem, but keep a folder sync'ed to it.
QDir(dirPath + "/ownCloud2/").removeRecursively();
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/blublu").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/sub/subsub/sub").isNull());
}
void testFindGoodPathForNewSyncFolder()
@ -169,6 +175,7 @@ private slots:
HttpCredentialsTest *cred = new HttpCredentialsTest("testuser", "secret");
account->setCredentials(cred);
account->setUrl( url );
url.setUserName(cred->user());
AccountStatePtr newAccountState(new AccountState(account));
FolderMan *folderman = FolderMan::instance();
@ -190,6 +197,14 @@ private slots:
QString(dirPath + "/ownCloud2/bar"));
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/sub", url),
QString(dirPath + "/sub2"));
// REMOVE ownCloud2 from the filesystem, but keep a folder sync'ed to it.
// We should still not suggest this folder as a new folder.
QDir(dirPath + "/ownCloud2/").removeRecursively();
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/ownCloud", url),
QString(dirPath + "/ownCloud3"));
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath + "/ownCloud2", url),
QString(dirPath + "/ownCloud22"));
}
};

View file

@ -22,7 +22,7 @@ signals:
void hooked(const QUrl &);
public:
DesktopServiceHook() { QDesktopServices::setUrlHandler("oauthtest", this, "hooked"); }
} desktopServiceHook;
};
static const QUrl sOAuthTestServer("oauthtest://someserver/owncloud");
@ -90,6 +90,7 @@ public:
class OAuthTestCase : public QObject
{
Q_OBJECT
DesktopServiceHook desktopServiceHook;
public:
enum State { StartState, BrowserOpened, TokenAsked, CustomState } state = StartState;
Q_ENUM(State);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff