Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHannah von Reth <hannah.vonreth@owncloud.com>2019-12-06 18:52:12 +0300
committerHannah von Reth <hannah.vonreth@owncloud.com>2019-12-06 18:52:12 +0300
commitac1102070f737fb37f006c737d25a6279fa6a823 (patch)
treedbd687a54f35395656195ea75ae589ff07fe726b /src
parent3461c0668e190cec8a3dff5f5bbd56afdea531cb (diff)
parent86c1a666600ee6f83b4c56a77f2a7cc09f281c81 (diff)
Merge branch '2.6'
Diffstat (limited to 'src')
-rw-r--r--src/gui/accountsettings.cpp10
-rw-r--r--src/gui/activityitemdelegate.cpp2
-rw-r--r--src/gui/activitylistmodel.cpp2
-rw-r--r--src/gui/application.cpp23
-rw-r--r--src/gui/application.h2
-rw-r--r--src/gui/networksettings.cpp22
-rw-r--r--src/gui/networksettings.h2
-rw-r--r--src/gui/networksettings.ui25
-rw-r--r--src/gui/owncloudgui.cpp17
-rw-r--r--src/gui/settingsdialog.cpp64
-rw-r--r--src/gui/settingsdialogcommon.cpp28
-rw-r--r--src/gui/socketapi.cpp4
-rw-r--r--src/libsync/accessmanager.cpp12
-rw-r--r--src/libsync/account.cpp10
-rw-r--r--src/libsync/capabilities.cpp12
-rw-r--r--src/libsync/capabilities.h4
-rw-r--r--src/libsync/discovery.cpp29
-rw-r--r--src/libsync/syncengine.cpp2
-rw-r--r--src/libsync/syncfileitem.h2
19 files changed, 181 insertions, 91 deletions
diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp
index 52de0dfa1..baec02e6b 100644
--- a/src/gui/accountsettings.cpp
+++ b/src/gui/accountsettings.cpp
@@ -363,6 +363,16 @@ void AccountSettings::slotFolderListClicked(const QModelIndex &indx)
{
if (indx.data(FolderStatusDelegate::AddButton).toBool()) {
// "Add Folder Sync Connection"
+ QTreeView *tv = ui->_folderList;
+ auto pos = tv->mapFromGlobal(QCursor::pos());
+ QStyleOptionViewItem opt;
+ opt.initFrom(tv);
+ auto btnRect = tv->visualRect(indx);
+ auto btnSize = tv->itemDelegate(indx)->sizeHint(opt, indx);
+ auto actual = QStyle::visualRect(opt.direction, btnRect, QRect(btnRect.topLeft(), btnSize));
+ if (!actual.contains(pos))
+ return;
+
if (indx.flags() & Qt::ItemIsEnabled) {
slotAddFolder();
} else {
diff --git a/src/gui/activityitemdelegate.cpp b/src/gui/activityitemdelegate.cpp
index ae2a17e60..01b5fe1b8 100644
--- a/src/gui/activityitemdelegate.cpp
+++ b/src/gui/activityitemdelegate.cpp
@@ -104,7 +104,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
int textTopOffset = qRound((iconHeight - fm.height()) / 2.0);
// time rect
QRect timeBox;
- int timeBoxWidth = fm.boundingRect(QLatin1String("4 hour(s) ago on longlongdomain.org")).width(); // FIXME.
+ int timeBoxWidth = fm.boundingRect(QLatin1String("4 hour(s) ago on longlongdomain.org (username)")).width(); // FIXME.
timeBox.setTop(actionIconRect.top() + textTopOffset);
timeBox.setLeft(option.rect.right() - timeBoxWidth - margin);
timeBox.setWidth(timeBoxWidth);
diff --git a/src/gui/activitylistmodel.cpp b/src/gui/activitylistmodel.cpp
index 33e57690d..906cebe2a 100644
--- a/src/gui/activitylistmodel.cpp
+++ b/src/gui/activitylistmodel.cpp
@@ -71,6 +71,8 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
return QIcon(QLatin1String(":/client/resources/account.png"));
break;
case Qt::ToolTipRole:
+ return tr("%1 %2 on %3").arg(a._subject, Utility::timeAgoInWords(a._dateTime), a._accName);
+ break;
case ActivityItemDelegate::ActionTextRole:
return a._subject;
break;
diff --git a/src/gui/application.cpp b/src/gui/application.cpp
index 213780c88..1b94417c6 100644
--- a/src/gui/application.cpp
+++ b/src/gui/application.cpp
@@ -68,6 +68,8 @@ namespace {
static const char optionsC[] =
"Options:\n"
" -h --help : show this help screen.\n"
+ " -s --showsettings : show the settings dialog while starting.\n"
+ " -q --quit : quit the running instance\n"
" --logwindow : open a window to show log output.\n"
" --logfile <filename> : write log output to file <filename>.\n"
" --logfile - : write log output to stdout.\n"
@@ -187,7 +189,6 @@ Application::Application(int &argc, char **argv)
setOrganizationDomain(QLatin1String(APPLICATION_REV_DOMAIN));
setApplicationName(_theme->appName());
setWindowIcon(_theme->applicationIcon());
- setAttribute(Qt::AA_UseHighDpiPixmaps, true);
if (!ConfigFile().exists()) {
// Migrate from version <= 2.4
@@ -235,6 +236,11 @@ Application::Application(int &argc, char **argv)
if (_helpOnly || _versionOnly)
return;
+ if (_quitInstance) {
+ QTimer::singleShot(0, qApp, &QApplication::quit);
+ return;
+ }
+
if (isRunning())
return;
@@ -311,6 +317,9 @@ Application::Application(int &argc, char **argv)
if (_showLogWindow) {
_gui->slotToggleLogBrowser(); // _showLogWindow is set in parseOptions.
}
+ if (_showSettings) {
+ _gui->slotShowSettings();
+ }
FolderMan::instance()->setupFolders();
_proxy.setupQtProxyFromConfig(); // folders have to be defined first, than we set up the Qt proxy.
@@ -515,11 +524,19 @@ void Application::slotParseMessage(const QString &msg, QObject *)
const int lengthOfMsgPrefix = 17;
QStringList options = msg.mid(lengthOfMsgPrefix).split(QLatin1Char('|'));
_showLogWindow = false;
+ _showSettings = false;
parseOptions(options);
setupLogging();
if (_showLogWindow) {
_gui->slotToggleLogBrowser(); // _showLogWindow is set in parseOptions.
}
+ if (_showSettings) {
+ _gui->slotShowSettings();
+ }
+ if (_quitInstance) {
+ qApp->quit();
+ }
+
} else if (msg.startsWith(QLatin1String("MSG_SHOWSETTINGS"))) {
qCInfo(lcApplication) << "Running for" << _startedAt.elapsed() / 1000.0 << "sec";
if (_startedAt.elapsed() < 10 * 1000) {
@@ -544,6 +561,10 @@ void Application::parseOptions(const QStringList &options)
if (option == QLatin1String("--help") || option == QLatin1String("-h")) {
setHelp();
break;
+ } else if (option == QLatin1String("--showsettings") || option == QLatin1String("-s")) {
+ _showSettings = true;
+ } else if (option == QLatin1String("--quit") || option == QLatin1String("-q")) {
+ _quitInstance = true;
} else if (option == QLatin1String("--logwindow") || option == QLatin1String("-l")) {
_showLogWindow = true;
} else if (option == QLatin1String("--logfile")) {
diff --git a/src/gui/application.h b/src/gui/application.h
index 72667ad49..9dc1a92d0 100644
--- a/src/gui/application.h
+++ b/src/gui/application.h
@@ -122,6 +122,8 @@ private:
// options from command line:
bool _showLogWindow;
+ bool _showSettings = false;
+ bool _quitInstance = false;
QString _logFile;
QString _logDir;
std::chrono::hours _logExpire;
diff --git a/src/gui/networksettings.cpp b/src/gui/networksettings.cpp
index d2436396d..2c9aa3c48 100644
--- a/src/gui/networksettings.cpp
+++ b/src/gui/networksettings.cpp
@@ -55,6 +55,8 @@ NetworkSettings::NetworkSettings(QWidget *parent)
_ui->manualSettings, &QWidget::setEnabled);
connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled,
_ui->typeComboBox, &QWidget::setEnabled);
+ connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled,
+ this, &NetworkSettings::checkAccountLocalhost);
loadProxySettings();
loadBWLimitSettings();
@@ -80,6 +82,7 @@ NetworkSettings::NetworkSettings(QWidget *parent)
// Warn about empty proxy host
connect(_ui->hostLineEdit, &QLineEdit::textChanged, this, &NetworkSettings::checkEmptyProxyHost);
checkEmptyProxyHost();
+ checkAccountLocalhost();
}
NetworkSettings::~NetworkSettings()
@@ -229,8 +232,27 @@ void NetworkSettings::showEvent(QShowEvent *event)
checkEmptyProxyHost();
saveProxySettings();
}
+ checkAccountLocalhost();
QWidget::showEvent(event);
}
+
+void NetworkSettings::checkAccountLocalhost()
+{
+ bool visible = false;
+ if (_ui->manualProxyRadioButton->isChecked()) {
+ // Check if at least one account is using localhost, because Qt proxy settings have no
+ // effect for localhost (#7169)
+ for (const auto &account : AccountManager::instance()->accounts()) {
+ const auto host = account->account()->url().host();
+ // Some typical url for localhost
+ if (host == "localhost" || host.startsWith("127.") || host == "[::1]")
+ visible = true;
+ }
+ }
+ _ui->labelLocalhost->setVisible(visible);
+}
+
+
} // namespace OCC
diff --git a/src/gui/networksettings.h b/src/gui/networksettings.h
index 8d35b14dc..cc0d7a562 100644
--- a/src/gui/networksettings.h
+++ b/src/gui/networksettings.h
@@ -44,6 +44,8 @@ private slots:
/// Red marking of host field if empty and enabled
void checkEmptyProxyHost();
+ void checkAccountLocalhost();
+
protected:
void showEvent(QShowEvent *event) override;
diff --git a/src/gui/networksettings.ui b/src/gui/networksettings.ui
index 60c5ae9c2..476079832 100644
--- a/src/gui/networksettings.ui
+++ b/src/gui/networksettings.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>542</width>
- <height>396</height>
+ <width>623</width>
+ <height>581</height>
</rect>
</property>
<property name="windowTitle">
@@ -23,6 +23,13 @@
<string>Proxy Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1">
+ <widget class="QComboBox" name="typeComboBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
<item row="0" column="0">
<widget class="QRadioButton" name="noProxyRadioButton">
<property name="text">
@@ -56,13 +63,6 @@
</attribute>
</widget>
</item>
- <item row="2" column="1">
- <widget class="QComboBox" name="typeComboBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
<item row="3" column="0" colspan="2">
<widget class="QWidget" name="manualSettings" native="true">
<property name="enabled">
@@ -170,6 +170,13 @@
</layout>
</widget>
</item>
+ <item>
+ <widget class="QLabel" name="labelLocalhost">
+ <property name="text">
+ <string>Note: proxy settings have no effects for accounts on localhost</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp
index 05f0cb879..1a834ad3c 100644
--- a/src/gui/owncloudgui.cpp
+++ b/src/gui/owncloudgui.cpp
@@ -1118,10 +1118,7 @@ void ownCloudGui::slotShowShareDialog(const QString &sharePath, const QString &l
//
// The correct value will be found with a propfind from ShareDialog.
// (we want to show the dialog directly, not wait for the propfind first)
- SharePermissions maxSharingPermissions =
- SharePermissionRead
- | SharePermissionUpdate | SharePermissionCreate | SharePermissionDelete
- | SharePermissionShare;
+ SharePermissions maxSharingPermissions = static_cast<SharePermissions>(accountState->account()->capabilities().defaultPermissions());
if (!resharingAllowed) {
maxSharingPermissions = SharePermission(0);
}
@@ -1170,9 +1167,15 @@ void ownCloudGui::slotAbout()
msgBox->setInformativeText("<qt>"+about+"</qt>");
msgBox->setStandardButtons(QMessageBox::Ok);
QIcon appIcon = Theme::instance()->applicationIcon();
- // Assume icon is always small enough to fit an about dialog?
- qDebug() << appIcon.availableSizes().last();
- QPixmap iconPixmap = appIcon.pixmap(appIcon.availableSizes().last());
+ const auto sizes = appIcon.availableSizes();
+ QSize size;
+ for (auto it = sizes.crbegin(); it != sizes.crend(); ++it) {
+ if (it->width() > 600)
+ continue;
+ size = *it;
+ break;
+ }
+ QPixmap iconPixmap = appIcon.pixmap(size);
iconPixmap.setDevicePixelRatio(2);
msgBox->setIconPixmap(iconPixmap);
msgBox->show();
diff --git a/src/gui/settingsdialog.cpp b/src/gui/settingsdialog.cpp
index a444a4a25..963e885d4 100644
--- a/src/gui/settingsdialog.cpp
+++ b/src/gui/settingsdialog.cpp
@@ -41,22 +41,48 @@
#include <QWidgetAction>
#include <QPainter>
#include <QPainterPath>
+#include <QMessageBox>
namespace {
-const char TOOLBAR_CSS[] =
- "QToolBar { background: %1; margin: 0; padding: 0; border: none; border-bottom: 1px solid %2; spacing: 0; } "
- "QToolBar QToolButton { background: %1; border: none; border-bottom: 1px solid %2; margin: 0; padding: 5px; } "
- "QToolBar QToolBarExtension { padding:0; } "
- "QToolBar QToolButton:checked { background: %3; color: %4; }";
+const QString TOOLBAR_CSS()
+{
+ return QStringLiteral("QToolBar { background: %1; margin: 0; padding: 0; border: none; border-bottom: 1px solid %2; spacing: 0; } "
+ "QToolBar QToolButton { background: %1; border: none; border-bottom: 1px solid %2; margin: 0; padding: 5px; } "
+ "QToolBar QToolBarExtension { padding:0; } "
+ "QToolBar QToolButton:checked { background: %3; color: %4; }");
+}
+
+const float buttonSizeRatio = 1.618f; // golden ratio
+
-static const float buttonSizeRatio = 1.618; // golden ratio
+/** display name with two lines that is displayed in the settings
+ * If width is bigger than 0, the string will be ellided so it does not exceed that width
+ */
+QString shortDisplayNameForSettings(OCC::Account *account, int width)
+{
+ QString user = account->davDisplayName();
+ if (user.isEmpty()) {
+ user = account->credentials()->user();
+ }
+ QString host = account->url().host();
+ int port = account->url().port();
+ if (port > 0 && port != 80 && port != 443) {
+ host.append(QLatin1Char(':'));
+ host.append(QString::number(port));
+ }
+ if (width > 0) {
+ QFont f;
+ QFontMetrics fm(f);
+ host = fm.elidedText(host, Qt::ElideMiddle, width);
+ user = fm.elidedText(user, Qt::ElideRight, width);
+ }
+ return QStringLiteral("%1\n%2").arg(user, host);
+}
}
namespace OCC {
-#include "settingsdialogcommon.cpp"
-
SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent)
: QDialog(parent)
, _ui(new Ui::SettingsDialog)
@@ -107,6 +133,22 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent)
NetworkSettings *networkSettings = new NetworkSettings;
_ui->stack->addWidget(networkSettings);
+ QWidget *spacer = new QWidget();
+ spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ _toolBar->addWidget(spacer);
+
+ QAction *quitAction = createColorAwareAction(QLatin1String(":/client/resources/quit.png"), tr("Quit %1").arg(qApp->applicationName()));
+ quitAction->setCheckable(false);
+ connect(quitAction, &QAction::triggered, this, [this] {
+ const auto reply = QMessageBox::question(this, tr("Quit %1").arg(qApp->applicationName()),
+ tr("Are you sure you want to quit %1?").arg(qApp->applicationName()),
+ QMessageBox::Yes | QMessageBox::No);
+ if (reply == QMessageBox::Yes) {
+ qApp->quit();
+ }
+ });
+ _toolBar->addAction(quitAction);
+
_actionGroupWidgets.insert(_activityAction, _activitySettings);
_actionGroupWidgets.insert(generalAction, generalSettings);
_actionGroupWidgets.insert(networkAction, networkSettings);
@@ -228,7 +270,7 @@ void SettingsDialog::accountAdded(AccountState *s)
if (!brandingSingleAccount) {
accountAction->setToolTip(s->account()->displayName());
- accountAction->setIconText(SettingsDialogCommon::shortDisplayNameForSettings(s->account().data(), height * buttonSizeRatio));
+ accountAction->setIconText(shortDisplayNameForSettings(s->account().data(), height * buttonSizeRatio));
}
_toolBar->insertAction(_toolBar->actions().at(0), accountAction);
auto accountSettings = new AccountSettings(s, this);
@@ -278,7 +320,7 @@ void SettingsDialog::slotAccountDisplayNameChanged()
QString displayName = account->displayName();
action->setText(displayName);
auto height = _toolBar->sizeHint().height();
- action->setIconText(SettingsDialogCommon::shortDisplayNameForSettings(account, height * buttonSizeRatio));
+ action->setIconText(shortDisplayNameForSettings(account, height * buttonSizeRatio));
}
}
}
@@ -323,7 +365,7 @@ void SettingsDialog::customizeStyle()
QString highlightTextColor(palette().highlightedText().color().name());
QString dark(palette().dark().color().name());
QString background(palette().base().color().name());
- _toolBar->setStyleSheet(QString::fromLatin1(TOOLBAR_CSS).arg(background, dark, highlightColor, highlightTextColor));
+ _toolBar->setStyleSheet(TOOLBAR_CSS().arg(background, dark, highlightColor, highlightTextColor));
Q_FOREACH (QAction *a, _actionGroup->actions()) {
QIcon icon = createColorAwareIcon(a->property("iconPath").toString());
diff --git a/src/gui/settingsdialogcommon.cpp b/src/gui/settingsdialogcommon.cpp
deleted file mode 100644
index de6f820c8..000000000
--- a/src/gui/settingsdialogcommon.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-namespace SettingsDialogCommon
-{
-
-/** display name with two lines that is displayed in the settings
- * If width is bigger than 0, the string will be ellided so it does not exceed that width
- */
-QString shortDisplayNameForSettings(Account* account, int width)
-{
- QString user = account->davDisplayName();
- if (user.isEmpty()) {
- user = account->credentials()->user();
- }
- QString host = account->url().host();
- int port = account->url().port();
- if (port > 0 && port != 80 && port != 443) {
- host.append(QLatin1Char(':'));
- host.append(QString::number(port));
- }
- if (width > 0) {
- QFont f;
- QFontMetrics fm(f);
- host = fm.elidedText(host, Qt::ElideMiddle, width);
- user = fm.elidedText(user, Qt::ElideRight, width);
- }
- return user + QLatin1String("\n") + host;
-}
-
-} \ No newline at end of file
diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp
index 5fb27aac4..9d02f8eea 100644
--- a/src/gui/socketapi.cpp
+++ b/src/gui/socketapi.cpp
@@ -1003,8 +1003,8 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe
QFileInfo fileInfo(fileData.localPath);
auto parentDir = fileData.parentFolder();
auto parentRecord = parentDir.journalRecord();
- bool canAddToDir =
- (fileInfo.isFile() && !parentRecord._remotePerm.hasPermission(RemotePermissions::CanAddFile))
+ bool canAddToDir = parentRecord._remotePerm.isNull()
+ || (fileInfo.isFile() && !parentRecord._remotePerm.hasPermission(RemotePermissions::CanAddFile))
|| (fileInfo.isDir() && !parentRecord._remotePerm.hasPermission(RemotePermissions::CanAddSubDirectories));
bool canChangeFile =
!isOnTheServer
diff --git a/src/libsync/accessmanager.cpp b/src/libsync/accessmanager.cpp
index 212d0edeb..3e6435fda 100644
--- a/src/libsync/accessmanager.cpp
+++ b/src/libsync/accessmanager.cpp
@@ -95,16 +95,10 @@ QNetworkReply *AccessManager::createRequest(QNetworkAccessManager::Operation op,
newRequest.setRawHeader("X-Request-ID", requestId);
if (newRequest.url().scheme() == "https") { // Not for "http": QTBUG-61397
- // Qt 5.12.4 fixed QTBUG-73947 - http2 should be usable after that
- bool http2Allowed = QLibraryInfo::version() >= QVersionNumber(5, 12, 4);
+ // http2 seems to cause issues, as with our recommended server setup we don't support http2, disable it by default for now
+ static const bool http2EnabledEnv = qEnvironmentVariableIntValue("OWNCLOUD_HTTP2_ENABLED") == 1;
- static auto http2EnabledEnv = qgetenv("OWNCLOUD_HTTP2_ENABLED");
- if (http2EnabledEnv == "1")
- http2Allowed = true;
- if (http2EnabledEnv == "0")
- http2Allowed = false;
-
- newRequest.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, http2Allowed);
+ newRequest.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, http2EnabledEnv);
}
return QNetworkAccessManager::createRequest(op, newRequest, outgoingData);
diff --git a/src/libsync/account.cpp b/src/libsync/account.cpp
index 80ace0280..6286e2188 100644
--- a/src/libsync/account.cpp
+++ b/src/libsync/account.cpp
@@ -110,12 +110,16 @@ void Account::setAvatar(const QImage &img)
QString Account::displayName() const
{
- QString dn = QString("%1@%2").arg(davUser(), _url.host());
+ QString user = davDisplayName();
+ if (user.isEmpty())
+ user = davUser();
+ QString host = _url.host();
int port = url().port();
if (port > 0 && port != 80 && port != 443) {
- dn.append(QLatin1Char(':'));
- dn.append(QString::number(port));
+ host.append(QLatin1Char(':'));
+ host.append(QString::number(port));
}
+ QString dn = QString("%1 (%2)").arg(host, user);
return dn;
}
diff --git a/src/libsync/capabilities.cpp b/src/libsync/capabilities.cpp
index 7a68af71c..5043171ec 100644
--- a/src/libsync/capabilities.cpp
+++ b/src/libsync/capabilities.cpp
@@ -17,6 +17,13 @@
#include <QVariantMap>
#include <QDebug>
+namespace {
+ QString FileSharingKey()
+ {
+ return QStringLiteral("files_sharing");
+ }
+}
+
namespace OCC {
@@ -85,6 +92,11 @@ bool Capabilities::shareResharing() const
return _capabilities["files_sharing"].toMap()["resharing"].toBool();
}
+int Capabilities::defaultPermissions() const
+{
+ return _capabilities.value(FileSharingKey()).toMap().value("default_permissions", 1).toInt();
+}
+
bool Capabilities::notificationsAvailable() const
{
// We require the OCS style API in 9.x, can't deal with the REST one only found in 8.2
diff --git a/src/libsync/capabilities.h b/src/libsync/capabilities.h
index b49008f52..e39ac43a1 100644
--- a/src/libsync/capabilities.h
+++ b/src/libsync/capabilities.h
@@ -43,6 +43,10 @@ public:
bool sharePublicLinkEnforceExpireDate() const;
bool sharePublicLinkMultiple() const;
bool shareResharing() const;
+
+ // TODO: return SharePermission
+ int defaultPermissions() const;
+
bool chunkingNg() const;
QString zsyncSupportedVersion() const;
diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp
index 539451f14..b9c77c80d 100644
--- a/src/libsync/discovery.cpp
+++ b/src/libsync/discovery.cpp
@@ -1161,6 +1161,7 @@ void ProcessDirectoryJob::processBlacklisted(const PathTuple &path, const OCC::L
item->_file = path._target;
item->_originalFile = path._original;
item->_inode = localEntry.inode;
+ item->_isSelectiveSync = true;
if (dbEntry.isValid() && ((dbEntry._modtime == localEntry.modtime && dbEntry._fileSize == localEntry.size) || (localEntry.isDirectory && dbEntry.isDirectory()))) {
item->_instruction = CSYNC_INSTRUCTION_REMOVE;
item->_direction = SyncFileItem::Down;
@@ -1409,34 +1410,24 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery()
if (_localQueryDone)
this->process();
} else {
- auto fatalError = [&] {
- emit _discoveryData->fatalError(tr("Server replied with an error while reading directory '%1' : %2")
- .arg(_currentFolder._server, results.error().message));
- };
- auto ignoreOrFatal = [&] {
- if (_dirItem) {
- _dirItem->_instruction = CSYNC_INSTRUCTION_IGNORE;
- _dirItem->_errorString = results.error().message;
- emit this->finished();
- } else {
- // Fatal for the root job since it has no SyncFileItem
- fatalError();
- }
- };
-
auto code = results.error().code;
qCWarning(lcDisco) << "Server error in directory" << _currentFolder._server << code;
- if (code == 403 || code == 404 || code == 500 || code == 503) {
+ if (_dirItem && code >= 403) {
+ // In case of an HTTP error, we ignore that directory
// 403 Forbidden can be sent by the server if the file firewall is active.
// A file or directory should be ignored and sync must continue. See #3490
// The server usually replies with the custom "503 Storage not available"
// if some path is temporarily unavailable. But in some cases a standard 503
// is returned too. Thus we can't distinguish the two and will treat any
// 503 as request to ignore the folder. See #3113 #2884.
- // Similarly, the server might also return 404 or 500 in case of bugs. #7199
- ignoreOrFatal();
+ // Similarly, the server might also return 404 or 50x in case of bugs. #7199 #7586
+ _dirItem->_instruction = CSYNC_INSTRUCTION_IGNORE;
+ _dirItem->_errorString = results.error().message;
+ emit this->finished();
} else {
- fatalError();
+ // Fatal for the root job since it has no SyncFileItem, or for the network errors
+ emit _discoveryData->fatalError(tr("Server replied with an error while reading directory '%1' : %2")
+ .arg(_currentFolder._server, results.error().message));
}
}
});
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp
index d26ff6d71..130238266 100644
--- a/src/libsync/syncengine.cpp
+++ b/src/libsync/syncengine.cpp
@@ -375,7 +375,7 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
item->_status = SyncFileItem::Conflict;
}
return;
- } else if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) {
+ } else if (item->_instruction == CSYNC_INSTRUCTION_REMOVE && !item->_isSelectiveSync) {
_hasRemoveFile = true;
} else if (item->_instruction == CSYNC_INSTRUCTION_RENAME) {
_hasNoneFiles = true; // If a file (or every file) has been renamed, it means not al files where deleted
diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h
index 667341be3..f6740c5c8 100644
--- a/src/libsync/syncfileitem.h
+++ b/src/libsync/syncfileitem.h
@@ -105,6 +105,7 @@ public:
, _errorMayBeBlacklisted(false)
, _status(NoStatus)
, _isRestoration(false)
+ , _isSelectiveSync(false)
, _httpErrorCode(0)
, _affectedItems(1)
, _instruction(CSYNC_INSTRUCTION_NONE)
@@ -241,6 +242,7 @@ public:
// Variables useful to report to the user
Status _status BITFIELD(4);
bool _isRestoration BITFIELD(1); // The original operation was forbidden, and this is a restoration
+ bool _isSelectiveSync BITFIELD(1); // The file is removed or ignored because it is in the selective sync list
quint16 _httpErrorCode;
RemotePermissions _remotePerm;
QString _errorString; // Contains a string only in case of error