1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2026-04-04 20:34:17 +02:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Markus Goetz
67b9fb09d5 VERSION.cmake: 2.4.1 rc1 2018-02-20 12:15:43 +01:00
57 changed files with 423 additions and 1011 deletions

View File

@@ -1,91 +0,0 @@
#
# We are building GCC with make and Clang with ninja, the combinations are more
# or less arbitrarily chosen. We just want to check that both compilers and both
# CMake generators work. It's unlikely that a specific generator only breaks
# with a specific compiler.
#
workspace:
base: /drone
path: src/github.com/owncloud/client
branches:
- master
- 2.4
clone:
git:
image: plugins/git
pull: true
tags: false
pipeline:
prepare-clang:
image: owncloudci/client:latest
pull: true
environment:
- LC_ALL=C.UTF-8
commands:
- mkdir clang-build
- cd clang-build
- cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 ..
building-clang:
image: owncloudci/client:latest
pull: true
environment:
- LC_ALL=C.UTF-8
commands:
- cd clang-build
- ninja -j4
testing-clang:
image: owncloudci/client:latest
pull: true
environment:
- LC_ALL=C.UTF-8
commands:
- cd clang-build
- useradd -m -s /bin/bash tester
- chown -R tester:tester .
- su-exec tester ctest --output-on-failure
prepare-gcc:
image: owncloudci/client:latest
pull: true
environment:
- LC_ALL=C.UTF-8
commands:
- mkdir gcc-build
- cd gcc-build
- cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 ..
building-gcc:
image: owncloudci/client:latest
pull: true
environment:
- LC_ALL=C.UTF-8
commands:
- cd gcc-build
- make -j4
testing-gcc:
image: owncloudci/client:latest
pull: true
environment:
- LC_ALL=C.UTF-8
commands:
- cd gcc-build
- useradd -m -s /bin/bash tester
- chown -R tester:tester .
- su-exec tester ctest --output-on-failure
notify-slack:
image: plugins/slack
pull: true
secrets: [ slack_webhook ]
channel: desktop
when:
local: false
status: [ changed, failure ]
event: [ push ]

37
.travis.yml Normal file
View File

@@ -0,0 +1,37 @@
sudo: required
language: cpp
services:
- docker
branches:
only:
- coverity_scan
before_install:
- sudo sh -c "echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Ubuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
- sudo sh -c "echo 'deb-src http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Ubuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
- wget http://download.opensuse.org/repositories/isv:ownCloud:desktop/Ubuntu_14.04/Release.key
- sudo apt-key add - < Release.key
- sudo apt-get update
- sudo apt-get -y build-dep owncloud-client
- checkout=$(git show-ref --head --hash head)
- cd ../
- wget https://scan.coverity.com/download/linux-64 --post-data "token=$token&project=owncloud%2Fmirall" -O coverity_tool.tgz
- mkdir coverity
- tar -xvf coverity_tool.tgz -C coverity --strip-components=1
- export PATH=$PATH:$PWD/coverity/bin/
- cd $TRAVIS_BUILD_DIR
install:
- cd ../
- mkdir client-build
- cd client-build
- cmake -DCMAKE_BUILD_TYPE="Debug" $TRAVIS_BUILD_DIR
- cov-build --dir cov-int make
- tar czvf client.tgz cov-int
- curl --form token=$token --form email=lukas@statuscode.ch --form file=@$PWD/client.tgz --form version="$checkout" --form description="$checkout" https://scan.coverity.com/builds?project=owncloud%2Fmirall
# Hack to stop processing
script: true

View File

@@ -1,29 +1,6 @@
ChangeLog
=========
version 2.4.3 (2018-08-xx)
* Windows: Don't ignore files with FILE_ATTRIBUTE_TEMPORARY (#6696, #6610)
* OAuth2: Fix infinite loop when the refresh token is expired
* Windows MSI: Fix crash in the auto updater
* Nautilus: Guard against None state (#6643)
version 2.4.2 (2018-07-18)
* Linux: Tray workarounds (#6545)
* Fix nautilus/nemo shell issues (#6393, #6406)
* Updater: Add update channel feature (#6259)
* Updater: Support EXE->MSI upgrade
* SyncJournal: Fixes for sync folders on removable media (#6049, #6049)
* SslButton: Add HTTP/2 info (#3146)
* Fix assert when using ownCloud server 5 (which you should not) (#6403)
* Normalize local path (#4424)
* Blacklisting must prevent parent etag updates (#6411)
* macdeployqt: Adjust minimum version based on our Qt (#5932)
* macOS: Unload the Finder extension on exit (#5382, #3819)
* Upload: Adjust timeout for final job based on file size (#6527)
* Sync: When detecting a local move, keep the local mtime (#6629)
* Credentials: Retry fetching from the keychain in case the keychain is still starting (#4274, #6522)
* OAuth2: Try to refresh the token even if the credentials weren't ready (#6522)
version 2.4.1 (2018-02-xx)
* Ignore files with file names that can't be encoded for the filesystem (#6287, #5676, #5719)
* Issues: Speed up insertion and add hard upper limit (#6272)

51
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,51 @@
#!groovy
//
// We now run the tests in Debug mode so that ASSERTs are triggered.
// Ideally we should run the tests in both Debug and Release so we catch
// all possible error combinations.
// See also the top comment in syncenginetestutils.h
//
node('CLIENT') {
stage 'Checkout'
checkout scm
sh '''git submodule update --init'''
stage 'Qt5'
sh '''rm -rf build
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 -DWITH_TESTING=1 -DCMAKE_PREFIX_PATH=/var/lib/jenkins/qt/5.6.2 ..
make -j4
ctest -V --output-on-failure'''
stage 'Qt5 - clang'
sh '''rm -rf build
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DWITH_TESTING=1 -DCMAKE_PREFIX_PATH=/var/lib/jenkins/qt/5.6.2 ..
make -j4
ctest -V --output-on-failure'''
stage 'Win32'
def win32 = docker.image('guruz/docker-owncloud-client-win32:latest')
win32.pull() // make sure we have the latest available from Docker Hub
win32.inside {
sh '''
rm -rf build-win32
mkdir build-win32
cd build-win32
../admin/win/download_runtimes.sh
cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON
make -j4
make package
ctest .
'''
}
// Stage 'macOS' TODO
}

View File

@@ -19,4 +19,4 @@ set( MAC_INSTALLER_BACKGROUND_FILE "${CMAKE_SOURCE_DIR}/admin/osx/installer-back
option( WITH_CRASHREPORTER "Build crashreporter" OFF )
set( CRASHREPORTER_SUBMIT_URL "https://crash-reports.owncloud.com/submit" CACHE string "URL for crash reporter" )
set( CRASHREPORTER_ICON ":/owncloud-icon.png" )

View File

@@ -1,6 +1,6 @@
# ownCloud Desktop Client
[![Build Status](https://drone.owncloud.com/api/badges/owncloud/client/status.svg)](https://drone.owncloud.com/owncloud/client)
[![Build Status](https://jenkins.owncloud.org/buildStatus/icon?job=owncloud-client/client/master)](https://jenkins.owncloud.org/job/owncloud-client/job/client/job/master/)
## Introduction

View File

@@ -1,11 +1,11 @@
set( MIRALL_VERSION_MAJOR 2 )
set( MIRALL_VERSION_MINOR 4 )
set( MIRALL_VERSION_PATCH 3 )
set( MIRALL_VERSION_PATCH 1 )
set( MIRALL_VERSION_YEAR 2018 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
set( MIRALL_VERSION_SUFFIX "rc1") #e.g. beta1, beta2, rc1
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
if( NOT DEFINED MIRALL_VERSION_BUILD )

View File

@@ -11,7 +11,6 @@ else()
set(MAC_INSTALLER_DO_CUSTOM_BACKGROUND "0")
endif()
find_package(Qt5 5.6 COMPONENTS Core REQUIRED)
configure_file(create_mac_pkg.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/create_mac.sh)
configure_file(macosx.pkgproj ${CMAKE_CURRENT_BINARY_DIR}/macosx.pkgproj)
configure_file(pre_install.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh)

View File

@@ -23,7 +23,7 @@ identity="$3"
prjfile=$build_path/admin/osx/macosx.pkgproj
# The name of the installer package
installer="@APPLICATION_SHORTNAME@-qt@Qt5Core_VERSION@-@MIRALL_VERSION_FULL@@MIRALL_VERSION_SUFFIX@"
installer="@APPLICATION_SHORTNAME@-@MIRALL_VERSION_FULL@@MIRALL_VERSION_SUFFIX@"
installer_file="$installer.pkg"
installer_file_tar="$installer.pkg.tar"
installer_file_tar_bz2="$installer.pkg.tar.bz2"

View File

@@ -22,7 +22,6 @@ import subprocess
import commands
import sys
from glob import glob
from distutils.version import LooseVersion
def QueryQMake(attrib):
return subprocess.check_output([qmake_path, '-query', attrib]).rstrip('\n')
@@ -93,8 +92,6 @@ commands.append(['mkdir', '-p', resources_dir])
plugins_dir = os.path.join(bundle_dir, 'Contents', 'PlugIns')
binaries = [i for i in glob(os.path.join(bundle_dir, 'Contents', 'MacOS', "*")) if is_exe(i)];
qt_version = QueryQMake('QT_VERSION')
print "Using Qt", qt_version
fixed_libraries = []
fixed_frameworks = []
@@ -337,19 +334,9 @@ def FindQtPlugin(name):
for binary in binaries:
FixBinary(binary)
if LooseVersion(qt_version) >= LooseVersion("5.10.0"):
QT_PLUGINS.append('styles/libqmacstyle.dylib')
for plugin in QT_PLUGINS:
FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin))
if LooseVersion(qt_version) >= LooseVersion("5.10.0"):
args = ['plutil', '-insert', 'LSMinimumSystemVersion', '-string', '10.10.0', os.path.join(bundle_dir, 'Contents', 'Info.plist')]
commands.append(args)
else:
args = ['plutil', '-insert', 'LSMinimumSystemVersion', '-string', '10.7.0', os.path.join(bundle_dir, 'Contents', 'Info.plist')]
commands.append(args)
if len(sys.argv) <= 2:
print 'Will run %d commands:' % len(commands)
for command in commands:

View File

@@ -27,9 +27,11 @@
<key>CFBundleShortVersionString</key>
<string>@MIRALL_VERSION_STRING@</string>
<key>NSHumanReadableCopyright</key>
<string>(C) 2014-2018 @APPLICATION_VENDOR@</string>
<string>(C) 2014-2016 @APPLICATION_VENDOR@</string>
<key>SUShowReleaseNotes</key>
<false/>
<key>LSMinimumBundleVersion</key>
<string>10.7.0</string>
<key>SUPublicDSAKeyFile</key>
<string>dsa_pub.pem</string>
</dict>

View File

@@ -278,90 +278,6 @@ X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
GenericName[oc]=Dorsièr de Sincronizacion
@@ -446,10 +362,6 @@ Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
GenericName[ko]=폴더 동기화
Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
Icon[ko]=@APPLICATION_EXECUTABLE@
Comment[lo]=@APPLICATION_NAME@ ການປະສານຂໍ້ມູນຄອມພິວເຕີລູກຂ່າຍ
GenericName[lo]=ໂຟນເດີຊິງ
Name[lo]=@APPLICATION_NAME@ ຊິງຄອມພິວເຕີລູກຂ່າຍ
Icon[lo]=@APPLICATION_EXECUTABLE@
Comment[hu_HU]=@APPLICATION_NAME@ asztali szinkronizációs kliens
GenericName[hu_HU]=Könyvtár szinkronizálás
Name[hu_HU]=@APPLICATION_NAME@ asztali szinkr. kliens

View File

@@ -34,15 +34,12 @@ from gi.repository import GObject, Nautilus
appname = 'ownCloud'
print("Initializing "+appname+"-client-nautilus extension")
print("Using python version {}".format(sys.version_info))
def get_local_path(url):
if url[0:7] == 'file://':
url = url[7:]
if python3:
return urllib.parse.unquote(url)
else:
return urllib.unquote(url).decode('utf-8')
unquote = urllib.parse.unquote if python3 else urllib.unquote
return unquote(url)
def get_runtime_dir():
"""Returns the value of $XDG_RUNTIME_DIR, a directory path.
@@ -64,7 +61,7 @@ class SocketConnect(GObject.GObject):
self._watch_id = 0
self._sock = None
self._listeners = [self._update_registered_paths]
self._remainder = ''.encode('utf-8')
self._remainder = ''.encode()
self.nautilusVFSFile_table = {} # not needed in this object actually but shared
# all over the other objects.
@@ -82,7 +79,7 @@ class SocketConnect(GObject.GObject):
# print("Server command: " + cmd)
if self.connected:
try:
self._sock.send(cmd.encode('utf-8'))
self._sock.send(cmd.encode())
except:
print("Sending failed.")
self.reconnect()
@@ -97,15 +94,18 @@ class SocketConnect(GObject.GObject):
self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock_file = os.path.join(get_runtime_dir(), appname, "socket")
try:
print("Socket File: " + sock_file)
self._sock.connect(sock_file) # fails if sock_file doesn't exist
self.connected = True
print("Setting connected to %r." % self.connected )
self._watch_id = GObject.io_add_watch(self._sock, GObject.IO_IN, self._handle_notify)
print("Socket watch id: " + str(self._watch_id))
self.sendCommand('GET_STRINGS:\n')
return False # Don't run again
except Exception as e:
print("Could not connect to unix socket " + sock_file + ". " + str(e))
print("Could not connect to unix socket. " + str(e))
except Exception as e: # Bad habbit
print("Connect could not be established, try again later.")
self._sock.close()
@@ -118,24 +118,24 @@ class SocketConnect(GObject.GObject):
# Prepend the remaining data from last call
if len(self._remainder) > 0:
data = self._remainder + data
self._remainder = ''.encode('utf-8')
self._remainder = ''.encode()
if len(data) > 0:
# Remember the remainder for next round
lastNL = data.rfind('\n'.encode('utf-8'));
lastNL = data.rfind('\n'.encode());
if lastNL > -1 and lastNL < len(data):
self._remainder = data[lastNL+1:]
data = data[:lastNL]
for l in data.split('\n'.encode('utf-8')):
self._handle_server_response(l.decode('utf-8'))
for l in data.split('\n'.encode()):
self._handle_server_response(l.decode())
else:
return False
return True # Run again
def _handle_server_response(self, line):
# print("Server response: " + line)
print("Server response: " + line)
parts = line.split(':')
action = parts[0]
args = parts[1:]
@@ -214,8 +214,8 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
# and we definitely don't want to show them for IGNORED.
shareable = False
state = entry['state']
state_ok = state and state.startswith('OK')
state_sync = state and state.startswith('SYNC')
state_ok = state.startswith('OK')
state_sync = state.startswith('SYNC')
if state_ok:
shareable = True
elif state_sync and isDir:
@@ -262,11 +262,11 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
def context_menu_action(self, menu, action, file):
filename = get_local_path(file.get_uri())
# print("Context menu: " + action + ' ' + filename)
print("Context menu: " + action + ' ' + filename)
socketConnect.sendCommand(action + ":" + filename + "\n")
class SyncStateExtension(GObject.GObject, Nautilus.InfoProvider):
class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
def __init__(self):
GObject.GObject.__init__(self)

View File

@@ -65,7 +65,7 @@ static void fillFileRecordFromGetQuery(SyncJournalFileRecord &rec, SqlQuery &que
static QString defaultJournalMode(const QString &dbPath)
{
#if defined(Q_OS_WIN)
#ifdef Q_OS_WIN
// See #2693: Some exFAT file systems seem unable to cope with the
// WAL journaling mode. They work fine with DELETE.
QString fileSystem = FileSystem::fileSystemForPath(dbPath);
@@ -74,11 +74,6 @@ static QString defaultJournalMode(const QString &dbPath)
qCInfo(lcDb) << "Filesystem contains FAT - using DELETE journal mode";
return "DELETE";
}
#elif defined(Q_OS_MAC)
if (dbPath.startsWith("/Volumes/")) {
qCInfo(lcDb) << "Mounted sync dir, do not use WAL for" << dbPath;
return "DELETE";
}
#else
Q_UNUSED(dbPath)
#endif
@@ -276,11 +271,6 @@ bool SyncJournalDb::sqlFail(const QString &log, const SqlQuery &query)
bool SyncJournalDb::checkConnect()
{
if (_db.isOpen()) {
if (!QFile::exists(_dbFile)) {
qCWarning(lcDb) << "Database open, but file file" + _dbFile + " does not exist";
close();
return false;
}
return true;
}

View File

@@ -1,6 +1,13 @@
PROJECT( CrashReporter )
cmake_policy(SET CMP0017 NEW)
list(APPEND crashreporter_SOURCES main.cpp)
list(APPEND crashreporter_RC resources.qrc)
qt_wrap_ui( crashreporter_UI_HEADERS ${crashreporter_UI} )
qt_add_resources( crashreporter_RC_RCC ${crashreporter_RC} )
# TODO: differentiate release channel
# if(BUILD_RELEASE)
# set(CRASHREPORTER_RELEASE_CHANNEL "release")
@@ -8,30 +15,9 @@ cmake_policy(SET CMP0017 NEW)
set(CRASHREPORTER_RELEASE_CHANNEL "nightly")
# endif()
# Theme
if(DEFINED OEM_THEME_DIR AND EXISTS "${OEM_THEME_DIR}/theme/colored")
set(CRASHREPORTER_ICON_DIR "${OEM_THEME_DIR}/theme/colored")
else()
set(CRASHREPORTER_ICON_DIR "${CMAKE_SOURCE_DIR}/theme/colored")
endif()
set(CRASHREPORTER_ICON_FILENAME "${APPLICATION_ICON_NAME}-icon.png")
set(CRASHREPORTER_ICON ":/${CRASHREPORTER_ICON_FILENAME}")
set(CRASHREPORTER_ICON_SIZE "128")
set(CRASHREPORTER_ICON_PATH "${CRASHREPORTER_ICON_DIR}/${APPLICATION_ICON_NAME}-icon-${CRASHREPORTER_ICON_SIZE}.png")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources.qrc.in
${CMAKE_CURRENT_BINARY_DIR}/resources.qrc)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CrashReporterConfig.h.in
${CMAKE_CURRENT_BINARY_DIR}/CrashReporterConfig.h)
# Sources
list(APPEND crashreporter_SOURCES main.cpp)
list(APPEND crashreporter_RC "${CMAKE_CURRENT_BINARY_DIR}/resources.qrc")
qt_wrap_ui( crashreporter_UI_HEADERS ${crashreporter_UI} )
qt_add_resources( crashreporter_RC_RCC ${crashreporter_RC} )
include_directories(${CMAKE_CURRENT_BINARY_DIR}
"../3rdparty/libcrashreporter-qt/src/"

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file alias="owncloud-icon.png">../../theme/colored/owncloud-icon-128.png</file>
</qresource>
</RCC>

View File

@@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/">
<file alias="@CRASHREPORTER_ICON_FILENAME@">@CRASHREPORTER_ICON_PATH@</file>
</qresource>
</RCC>

View File

@@ -156,7 +156,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
/* First, check that the file is NOT in our tree (another file with the same name was added) */
if (our_tree->findFile(basePath)) {
other = nullptr;
qCInfo(lcReconcile, "Origin found in our tree : %s", basePath.constData());
qCDebug(lcReconcile, "Origin found in our tree : %s", basePath.constData());
} else {
/* Find the potential rename source file in the other tree.
* If the renamed file could not be found in the opposite tree, that is because it
@@ -164,7 +164,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
* The journal is cleaned up later after propagation.
*/
other = other_tree->findFile(basePath);
qCInfo(lcReconcile, "Rename origin in other tree (%s) %s",
qCDebug(lcReconcile, "Rename origin in other tree (%s) %s",
basePath.constData(), other ? "found" : "not found");
}
@@ -175,7 +175,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
// Some other EVAL_RENAME already claimed other.
// We do nothing: maybe a different candidate for
// other is found as well?
qCInfo(lcReconcile, "Other has already been renamed to %s",
qCDebug(lcReconcile, "Other has already been renamed to %s",
other->rename_path.constData());
} else if (cur->type == CSYNC_FTW_TYPE_DIR
// The local replica is reconciled first, so the remote tree would
@@ -187,17 +187,13 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
|| other->instruction == CSYNC_INSTRUCTION_NONE
|| other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|| other->instruction == CSYNC_INSTRUCTION_REMOVE) {
qCInfo(lcReconcile, "Switching %s to RENAME to %s",
qCDebug(lcReconcile, "Switching %s to RENAME to %s",
other->path.constData(), cur->path.constData());
other->instruction = CSYNC_INSTRUCTION_RENAME;
other->rename_path = cur->path;
if( !cur->file_id.isEmpty() ) {
other->file_id = cur->file_id;
}
if (ctx->current == LOCAL_REPLICA) {
// Keep the local mtime.
other->modtime = cur->modtime;
}
other->inode = cur->inode;
cur->instruction = CSYNC_INSTRUCTION_NONE;
// We have consumed 'other': exit this loop to not consume another one.
@@ -211,7 +207,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
// Local: The remote reconcile will be able to deal with this.
// Remote: The local replica has already dealt with this.
// See the EVAL_RENAME case when other was found directly.
qCInfo(lcReconcile, "File in a renamed directory, other side's instruction: %d",
qCDebug(lcReconcile, "File in a renamed directory, other side's instruction: %d",
other->instruction);
cur->instruction = CSYNC_INSTRUCTION_NONE;
} else {
@@ -219,7 +215,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
// and the instruction in the local tree is NEW while cur has EVAL_RENAME
// due to a remote move of the same file. In these scenarios we just
// want the instruction to stay NEW.
qCInfo(lcReconcile, "Other already has instruction %d",
qCDebug(lcReconcile, "Other already has instruction %d",
other->instruction);
}
};
@@ -227,7 +223,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
if (ctx->current == LOCAL_REPLICA) {
/* use the old name to find the "other" node */
OCC::SyncJournalFileRecord base;
qCInfo(lcReconcile, "Finding rename origin through inode %" PRIu64 "",
qCDebug(lcReconcile, "Finding rename origin through inode %" PRIu64 "",
cur->inode);
ctx->statedb->getFileRecordByInode(cur->inode, &base);
renameCandidateProcessing(base._path);
@@ -240,7 +236,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
// line.
auto basePath = csync_rename_adjust_full_path_source(ctx, cur->path);
if (basePath != cur->path) {
qCInfo(lcReconcile, "Trying rename origin by csync_rename mapping %s",
qCDebug(lcReconcile, "Trying rename origin by csync_rename mapping %s",
basePath.constData());
// We go through getFileRecordsByFileId to ensure the basePath
// computed in this way also has the expected fileid.
@@ -253,7 +249,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
// Also feed all the other files with the same fileid if necessary
if (!processedRename) {
qCInfo(lcReconcile, "Finding rename origin through file ID %s",
qCDebug(lcReconcile, "Finding rename origin through file ID %s",
cur->file_id.constData());
ctx->statedb->getFileRecordsByFileId(cur->file_id,
[&](const OCC::SyncJournalFileRecord &base) { renameCandidateProcessing(base._path); });

View File

@@ -130,12 +130,12 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
* This code should probably be in csync_exclude, but it does not have the fs parameter.
* Keep it here for now */
if (ctx->ignore_hidden_files && (fs->is_hidden)) {
qCInfo(lcUpdate, "file excluded because it is a hidden file: %s", fs->path.constData());
qCDebug(lcUpdate, "file excluded because it is a hidden file: %s", fs->path.constData());
excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
}
} else {
/* File is ignored because it's matched by a user- or system exclude pattern. */
qCInfo(lcUpdate, "%s excluded (%d)", fs->path.constData(), excluded);
qCDebug(lcUpdate, "%s excluded (%d)", fs->path.constData(), excluded);
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
return 1;
}
@@ -160,7 +160,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
*/
QTextEncoder encoder(localCodec, QTextCodec::ConvertInvalidToNull);
if (encoder.fromUnicode(QString::fromUtf8(fs->path)).contains('\0')) {
qCInfo(lcUpdate, "cannot encode %s to local encoding %d",
qCDebug(lcUpdate, "cannot encode %s to local encoding %d",
fs->path.constData(), localCodec->mibEnum());
excluded = CSYNC_FILE_EXCLUDE_CANNOT_ENCODE;
}
@@ -168,7 +168,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
if (fs->type == CSYNC_FTW_TYPE_FILE ) {
if (fs->modtime == 0) {
qCInfo(lcUpdate, "file: %s - mtime is zero!", fs->path.constData());
qCDebug(lcUpdate, "file: %s - mtime is zero!", fs->path.constData());
}
}
@@ -195,12 +195,10 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
/* we have an update! */
qCInfo(lcUpdate, "Database entry found, compare: %" PRId64 " <-> %" PRId64
", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
", size: %" PRId64 " <-> %" PRId64 ", perms: %x <-> %x"
", checksum: %s <-> %s , ignore: %d",
", size: %" PRId64 " <-> %" PRId64 ", perms: %x <-> %x, ignore: %d",
((int64_t) fs->modtime), ((int64_t) base._modtime),
fs->etag.constData(), base._etag.constData(), (uint64_t) fs->inode, (uint64_t) base._inode,
(uint64_t) fs->size, (uint64_t) base._fileSize, *reinterpret_cast<short*>(&fs->remotePerm), *reinterpret_cast<short*>(&base._remotePerm), fs->checksumHeader.constData(),
base._checksumHeader.constData(), base._serverHasIgnoredFiles);
(uint64_t) fs->size, (uint64_t) base._fileSize, *reinterpret_cast<short*>(&fs->remotePerm), *reinterpret_cast<short*>(&base._remotePerm), base._serverHasIgnoredFiles );
if (ctx->current == REMOTE_REPLICA && fs->etag != base._etag) {
fs->instruction = CSYNC_INSTRUCTION_EVAL;
@@ -230,7 +228,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
checksumIdentical = fs->checksumHeader == base._checksumHeader;
}
if (checksumIdentical) {
qCInfo(lcUpdate, "NOTE: Checksums are identical, file did not actually change: %s", fs->path.constData());
qCDebug(lcUpdate, "NOTE: Checksums are identical, file did not actually change: %s", fs->path.constData());
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
goto out;
}
@@ -254,7 +252,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
* The metadata comparison ensure that we fetch all the file id or permission when
* upgrading owncloud
*/
qCInfo(lcUpdate, "Reading from database: %s", fs->path.constData());
qCDebug(lcUpdate, "Reading from database: %s", fs->path.constData());
ctx->remote.read_from_db = true;
}
/* If it was remembered in the db that the remote dir has ignored files, store
@@ -265,7 +263,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
}
if (metadata_differ) {
/* file id or permissions has changed. Which means we need to update them in the DB. */
qCInfo(lcUpdate, "Need to update metadata for: %s", fs->path.constData());
qCDebug(lcUpdate, "Need to update metadata for: %s", fs->path.constData());
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
} else {
fs->instruction = CSYNC_INSTRUCTION_NONE;
@@ -273,7 +271,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
} else {
/* check if it's a file and has been renamed */
if (ctx->current == LOCAL_REPLICA) {
qCInfo(lcUpdate, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
qCDebug(lcUpdate, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
OCC::SyncJournalFileRecord base;
if(!ctx->statedb->getFileRecordByInode(fs->inode, &base)) {
@@ -300,13 +298,13 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
_rel_to_abs(ctx, fs->path), base._checksumHeader,
ctx->callbacks.checksum_userdata);
if (!fs->checksumHeader.isEmpty()) {
qCInfo(lcUpdate, "checking checksum of potential rename %s %s <-> %s", fs->path.constData(), fs->checksumHeader.constData(), base._checksumHeader.constData());
qCDebug(lcUpdate, "checking checksum of potential rename %s %s <-> %s", fs->path.constData(), fs->checksumHeader.constData(), base._checksumHeader.constData());
isRename = fs->checksumHeader == base._checksumHeader;
}
}
if (isRename) {
qCInfo(lcUpdate, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
qCDebug(lcUpdate, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
/* inode found so the file has been renamed */
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
if (fs->type == CSYNC_FTW_TYPE_DIR) {
@@ -316,8 +314,6 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
goto out;
} else {
qCInfo(lcUpdate, "Checking for rename based on fileid %s", fs->file_id.constData());
/* Remote Replica Rename check */
fs->instruction = CSYNC_INSTRUCTION_NEW;
@@ -354,7 +350,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
csync_rename_record(ctx, base._path, fs->path);
}
qCInfo(lcUpdate, "remote rename detected based on fileid %s --> %s", base._path.constData(), fs->path.constData());
qCDebug(lcUpdate, "remote rename detected based on fileid %s --> %s", base._path.constData(), fs->path.constData());
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
done = true;
};
@@ -462,11 +458,11 @@ int csync_walker(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> fs) {
}
break;
case CSYNC_FTW_TYPE_SLINK:
qCInfo(lcUpdate, "symlink: %s - not supported", fs->path.constData());
qCDebug(lcUpdate, "symlink: %s - not supported", fs->path.constData());
break;
default:
qCInfo(lcUpdate, "item: %s - item type %d not iterated", fs->path.constData(), fs->type);
return 0;
break;
}
rc = _csync_detect_update(ctx, std::move(fs));
@@ -487,7 +483,7 @@ static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
* their correct etags again and we don't run into this case.
*/
if( rec._etag == "_invalid_") {
qCInfo(lcUpdate, "%s selective sync excluded", rec._path.constData());
qCDebug(lcUpdate, "%s selective sync excluded", rec._path.constData());
skipbase = rec._path;
skipbase += '/';
return;
@@ -724,7 +720,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
}
csync_vio_closedir(ctx, dh);
qCInfo(lcUpdate, " <= Closing walk for %s with read_from_db %d", uri, read_from_db);
qCDebug(lcUpdate, " <= Closing walk for %s with read_from_db %d", uri, read_from_db);
return rc;

View File

@@ -181,7 +181,7 @@ std::unique_ptr<csync_file_stat_t> csync_vio_local_readdir(csync_vio_handle_t *d
}
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
) {
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
file_stat->type = CSYNC_FTW_TYPE_SKIP;
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
file_stat->type = CSYNC_FTW_TYPE_DIR;

View File

@@ -136,7 +136,7 @@ IF( APPLE )
if(SPARKLE_FOUND)
# Define this, we need to check in updater.cpp
add_definitions( -DHAVE_SPARKLE )
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm updater/sparkleupdater.h)
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm)
endif()
ENDIF()

View File

@@ -312,10 +312,10 @@ void AccountState::slotInvalidCredentials()
if (account()->credentials()->ready()) {
account()->credentials()->invalidateToken();
}
if (auto creds = qobject_cast<HttpCredentials *>(account()->credentials())) {
if (creds->refreshAccessToken())
return;
if (auto creds = qobject_cast<HttpCredentials *>(account()->credentials())) {
if (creds->refreshAccessToken())
return;
}
}
account()->credentials()->askFromUser();
}

View File

@@ -121,10 +121,6 @@ void Folder::checkLocalPath()
{
const QFileInfo fi(_definition.localPath);
_canonicalLocalPath = fi.canonicalFilePath();
#ifdef Q_OS_MAC
// Workaround QTBUG-55896 (Should be fixed in Qt 5.8)
_canonicalLocalPath = _canonicalLocalPath.normalized(QString::NormalizationForm_C);
#endif
if (_canonicalLocalPath.isEmpty()) {
qCWarning(lcFolder) << "Broken symlink:" << _definition.localPath;
_canonicalLocalPath = _definition.localPath;

View File

@@ -25,10 +25,6 @@
#include "updater/updater.h"
#include "updater/ocupdater.h"
#ifdef Q_OS_MAC
// FIXME We should unify those, but Sparkle does everything behind the scene transparently
#include "updater/sparkleupdater.h"
#endif
#include "ignorelisteditor.h"
#include "config.h"
@@ -36,7 +32,6 @@
#include <QNetworkProxy>
#include <QDir>
#include <QScopedValueRollback>
#include <QMessageBox>
namespace OCC {
@@ -93,18 +88,6 @@ GeneralSettings::GeneralSettings(QWidget *parent)
// accountAdded means the wizard was finished and the wizard might change some options.
connect(AccountManager::instance(), &AccountManager::accountAdded, this, &GeneralSettings::loadMiscSettings);
// Only our standard brandings currently support beta channel
Theme *theme = Theme::instance();
if (theme->appName() != QLatin1String("ownCloud") && theme->appName() != QLatin1String("testpilotcloud") ) {
#ifdef Q_OS_MAC
// Because we don't have any statusString from the SparkleUpdater anyway we can hide the whole thing
_ui->updatesGroupBox->hide();
#else
_ui->updateChannelLabel->hide();
_ui->updateChannel->hide();
#endif
}
}
GeneralSettings::~GeneralSettings()
@@ -134,79 +117,22 @@ void GeneralSettings::loadMiscSettings()
void GeneralSettings::slotUpdateInfo()
{
if (ConfigFile().skipUpdateCheck() || !Updater::instance()) {
// updater disabled on compile
_ui->updatesGroupBox->setVisible(false);
return;
}
// Note: the sparkle-updater is not an OCUpdater
OCUpdater *ocupdater = qobject_cast<OCUpdater *>(Updater::instance());
if (ocupdater) {
connect(ocupdater, &OCUpdater::downloadStateChanged, this, &GeneralSettings::slotUpdateInfo, Qt::UniqueConnection);
connect(_ui->restartButton, &QAbstractButton::clicked, ocupdater, &OCUpdater::slotStartInstaller, Qt::UniqueConnection);
OCUpdater *updater = qobject_cast<OCUpdater *>(Updater::instance());
if (ConfigFile().skipUpdateCheck()) {
updater = 0; // don't show update info if updates are disabled
}
if (updater) {
connect(updater, &OCUpdater::downloadStateChanged, this, &GeneralSettings::slotUpdateInfo, Qt::UniqueConnection);
connect(_ui->restartButton, &QAbstractButton::clicked, updater, &OCUpdater::slotStartInstaller, Qt::UniqueConnection);
connect(_ui->restartButton, &QAbstractButton::clicked, qApp, &QApplication::quit, Qt::UniqueConnection);
_ui->updateStateLabel->setText(ocupdater->statusString());
_ui->restartButton->setVisible(ocupdater->downloadState() == OCUpdater::DownloadComplete);
_ui->updateStateLabel->setText(updater->statusString());
_ui->restartButton->setVisible(updater->downloadState() == OCUpdater::DownloadComplete);
} else {
// can't have those infos from sparkle currently
_ui->updatesGroupBox->setVisible(false);
}
#ifdef Q_OS_MAC
else if (SparkleUpdater *sparkleUpdater = qobject_cast<SparkleUpdater *>(Updater::instance())) {
_ui->updateStateLabel->setText(sparkleUpdater->statusString());
_ui->restartButton->setVisible(false);
}
#endif
// Channel selection
_ui->updateChannel->setCurrentIndex(ConfigFile().updateChannel() == "beta" ? 1 : 0);
connect(_ui->updateChannel, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &GeneralSettings::slotUpdateChannelChanged, Qt::UniqueConnection);
}
void GeneralSettings::slotUpdateChannelChanged(int index)
{
QString channel = index == 0 ? QStringLiteral("stable") : QStringLiteral("beta");
if (channel == ConfigFile().updateChannel())
return;
auto msgBox = new QMessageBox(
QMessageBox::Warning,
tr("Change update channel?"),
tr("The update channel determines which client updates will be offered "
"for installation. The \"stable\" channel contains only upgrades that "
"are considered reliable, while the versions in the \"beta\" channel "
"may contain newer features and bugfixes, but have not yet been tested "
"thoroughly."
"\n\n"
"Note that this selects only what pool upgrades are taken from, and that "
"there are no downgrades: So going back from the beta channel to "
"the stable channel usually cannot be done immediately and means waiting "
"for a stable version that is newer than the currently installed beta "
"version."),
QMessageBox::NoButton,
this);
msgBox->addButton(tr("Change update channel"), QMessageBox::AcceptRole);
msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
connect(msgBox, &QMessageBox::finished, msgBox, [this, channel, msgBox](int result) {
msgBox->deleteLater();
if (result == QMessageBox::AcceptRole) {
ConfigFile().setUpdateChannel(channel);
if (OCUpdater *updater = qobject_cast<OCUpdater *>(Updater::instance())) {
updater->setUpdateUrl(Updater::updateUrl());
updater->checkForUpdate();
}
#ifdef Q_OS_MAC
else if (SparkleUpdater *updater = qobject_cast<SparkleUpdater *>(Updater::instance())) {
updater->setUpdateUrl(Updater::updateUrl());
updater->checkForUpdate();
}
#endif
} else {
_ui->updateChannel->setCurrentText(ConfigFile().updateChannel());
}
});
msgBox->open();
}
void GeneralSettings::saveMiscSettings()

View File

@@ -44,7 +44,6 @@ private slots:
void slotToggleLaunchOnStartup(bool);
void slotToggleOptionalDesktopNotifications(bool);
void slotUpdateInfo();
void slotUpdateChannelChanged(int index);
void slotIgnoreFilesEditor();
void loadMiscSettings();

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>785</width>
<height>533</height>
<height>523</height>
</rect>
</property>
<property name="windowTitle">
@@ -74,88 +74,48 @@
<property name="title">
<string>Updates</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="updateChannelLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Channel</string>
</property>
<property name="buddy">
<cstring>updateChannel</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="updateChannel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>stable</string>
</property>
</item>
<item>
<property name="text">
<string>beta</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="updateStateLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="restartButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Restart &amp;&amp; Update</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
<widget class="QLabel" name="updateStateLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="restartButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Restart &amp;&amp; Update</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
@@ -287,10 +247,7 @@
<tabstop>ignoredFilesButton</tabstop>
<tabstop>newFolderLimitCheckBox</tabstop>
<tabstop>newFolderLimitSpinBox</tabstop>
<tabstop>newExternalStorage</tabstop>
<tabstop>showInExplorerNavigationPaneCheckBox</tabstop>
<tabstop>crashreporterCheckBox</tabstop>
<tabstop>updateChannel</tabstop>
<tabstop>restartButton</tabstop>
</tabstops>
<resources/>

View File

@@ -50,13 +50,18 @@ const char propertyAccountC[] = "oc_account";
ownCloudGui::ownCloudGui(Application *parent)
: QObject(parent)
, _tray(0)
,
#if defined(Q_OS_MAC)
, _settingsDialog(new SettingsDialogMac(this))
_settingsDialog(new SettingsDialogMac(this))
,
#else
, _settingsDialog(new SettingsDialog(this))
_settingsDialog(new SettingsDialog(this))
,
#endif
, _logBrowser(0)
_logBrowser(0)
, _contextMenuVisibleOsx(false)
, _recentActionsMenu(0)
, _qdbusmenuWorkaround(false)
, _app(parent)
{
_tray = new Systray();
@@ -112,7 +117,7 @@ void ownCloudGui::slotOpenSettingsDialog()
void ownCloudGui::slotTrayClicked(QSystemTrayIcon::ActivationReason reason)
{
if (_workaroundFakeDoubleClick) {
if (_qdbusmenuWorkaround) {
static QElapsedTimer last_click;
if (last_click.isValid() && last_click.elapsed() < 200) {
return;
@@ -376,19 +381,17 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
void ownCloudGui::slotContextMenuAboutToShow()
{
_contextMenuVisibleManual = true;
// For some reason on OS X _contextMenu->isVisible returns always false
_contextMenuVisibleOsx = true;
// Update icon in sys tray, as it might change depending on the context menu state
slotComputeOverallSyncStatus();
if (!_workaroundNoAboutToShowUpdate) {
updateContextMenu();
}
}
void ownCloudGui::slotContextMenuAboutToHide()
{
_contextMenuVisibleManual = false;
// For some reason on OS X _contextMenu->isVisible returns always false
_contextMenuVisibleOsx = false;
// Update icon in sys tray, as it might change depending on the context menu state
slotComputeOverallSyncStatus();
@@ -396,11 +399,11 @@ void ownCloudGui::slotContextMenuAboutToHide()
bool ownCloudGui::contextMenuVisible() const
{
// On some platforms isVisible doesn't work and always returns false,
// elsewhere aboutToHide is unreliable.
if (_workaroundManualVisibility)
return _contextMenuVisibleManual;
#ifdef Q_OS_MAC
return _contextMenuVisibleOsx;
#else
return _contextMenu->isVisible();
#endif
}
static bool minimalTrayMenu()
@@ -423,36 +426,12 @@ static bool updateWhileVisible()
}
}
static QByteArray envForceQDBusTrayWorkaround()
static QByteArray forceQDBusTrayWorkaround()
{
static QByteArray var = qgetenv("OWNCLOUD_FORCE_QDBUS_TRAY_WORKAROUND");
return var;
}
static QByteArray envForceWorkaroundShowAndHideTray()
{
static QByteArray var = qgetenv("OWNCLOUD_FORCE_TRAY_SHOW_HIDE");
return var;
}
static QByteArray envForceWorkaroundNoAboutToShowUpdate()
{
static QByteArray var = qgetenv("OWNCLOUD_FORCE_TRAY_NO_ABOUT_TO_SHOW");
return var;
}
static QByteArray envForceWorkaroundFakeDoubleClick()
{
static QByteArray var = qgetenv("OWNCLOUD_FORCE_TRAY_FAKE_DOUBLE_CLICK");
return var;
}
static QByteArray envForceWorkaroundManualVisibility()
{
static QByteArray var = qgetenv("OWNCLOUD_FORCE_TRAY_MANUAL_VISIBILITY");
return var;
}
void ownCloudGui::setupContextMenu()
{
if (_contextMenu) {
@@ -475,65 +454,51 @@ void ownCloudGui::setupContextMenu()
return;
}
auto applyEnvVariable = [](bool *sw, const QByteArray &value) {
if (value == "1")
*sw = true;
if (value == "0")
*sw = false;
};
// This is an old compound flag that people might still depend on
bool qdbusmenuWorkarounds = false;
applyEnvVariable(&qdbusmenuWorkarounds, envForceQDBusTrayWorkaround());
if (qdbusmenuWorkarounds) {
_workaroundFakeDoubleClick = true;
_workaroundNoAboutToShowUpdate = true;
_workaroundShowAndHideTray = true;
}
#ifdef Q_OS_MAC
// https://bugreports.qt.io/browse/QTBUG-54633
_workaroundNoAboutToShowUpdate = true;
_workaroundManualVisibility = true;
#endif
// Enables workarounds for bugs introduced in Qt 5.5.0
// In particular QTBUG-47863 #3672 (tray menu fails to update and
// becomes unresponsive) and QTBUG-48068 #3722 (click signal is
// emitted several times)
// The Qt version check intentionally uses 5.0.0 (where platformMenu()
// was introduced) instead of 5.5.0 to avoid issues where the Qt
// version used to build is different from the one used at runtime.
// If we build with 5.6.1 or newer, we can skip this because the
// bugs should be fixed there.
#ifdef Q_OS_LINUX
// For KDE sessions if the platform plugin is missing,
// neither aboutToShow() updates nor the isVisible() call
// work. At least aboutToHide is reliable.
// https://github.com/owncloud/client/issues/6545
static QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
static QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
bool isKde =
xdgCurrentDesktop.contains("KDE")
|| desktopSession.contains("plasma")
|| desktopSession.contains("kde");
QObject *platformMenu = reinterpret_cast<QObject *>(_tray->contextMenu()->platformMenu());
if (isKde && platformMenu && platformMenu->metaObject()->className() == QLatin1String("QDBusPlatformMenu")) {
_workaroundManualVisibility = true;
_workaroundNoAboutToShowUpdate = true;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
if (qVersion() == QByteArray("5.5.0")) {
QObject *platformMenu = reinterpret_cast<QObject *>(_tray->contextMenu()->platformMenu());
if (platformMenu
&& platformMenu->metaObject()->className() == QLatin1String("QDBusPlatformMenu")) {
_qdbusmenuWorkaround = true;
qCWarning(lcApplication) << "Enabled QDBusPlatformMenu workaround";
}
}
#endif
#endif
applyEnvVariable(&_workaroundNoAboutToShowUpdate, envForceWorkaroundNoAboutToShowUpdate());
applyEnvVariable(&_workaroundFakeDoubleClick, envForceWorkaroundFakeDoubleClick());
applyEnvVariable(&_workaroundShowAndHideTray, envForceWorkaroundShowAndHideTray());
applyEnvVariable(&_workaroundManualVisibility, envForceWorkaroundManualVisibility());
if (forceQDBusTrayWorkaround() == "1") {
_qdbusmenuWorkaround = true;
} else if (forceQDBusTrayWorkaround() == "0") {
_qdbusmenuWorkaround = false;
}
qCInfo(lcApplication) << "Tray menu workarounds:"
<< "noabouttoshow:" << _workaroundNoAboutToShowUpdate
<< "fakedoubleclick:" << _workaroundFakeDoubleClick
<< "showhide:" << _workaroundShowAndHideTray
<< "manualvisibility:" << _workaroundManualVisibility;
connect(&_delayedTrayUpdateTimer, &QTimer::timeout, this, &ownCloudGui::updateContextMenu);
_delayedTrayUpdateTimer.setInterval(2 * 1000);
_delayedTrayUpdateTimer.setSingleShot(true);
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(slotContextMenuAboutToShow()));
// unfortunately aboutToHide is unreliable, it seems to work on OSX though
connect(_contextMenu.data(), SIGNAL(aboutToHide()), SLOT(slotContextMenuAboutToHide()));
// When the qdbusmenuWorkaround is necessary, we can't do on-demand updates
// because the workaround is to hide and show the tray icon.
if (_qdbusmenuWorkaround) {
connect(&_workaroundBatchTrayUpdate, &QTimer::timeout, this, &ownCloudGui::updateContextMenu);
_workaroundBatchTrayUpdate.setInterval(30 * 1000);
_workaroundBatchTrayUpdate.setSingleShot(true);
} else {
// Update the context menu whenever we're about to show it
// to the user.
#ifdef Q_OS_MAC
// https://bugreports.qt.io/browse/QTBUG-54633
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(slotContextMenuAboutToShow()));
connect(_contextMenu.data(), SIGNAL(aboutToHide()), SLOT(slotContextMenuAboutToHide()));
#else
connect(_contextMenu.data(), &QMenu::aboutToShow, this, &ownCloudGui::updateContextMenu);
#endif
}
// Populate the context menu now.
updateContextMenu();
@@ -545,21 +510,13 @@ void ownCloudGui::updateContextMenu()
return;
}
// If it's visible, we can't update live, and it won't be updated lazily: reschedule
if (contextMenuVisible() && !updateWhileVisible() && _workaroundNoAboutToShowUpdate) {
if (!_delayedTrayUpdateTimer.isActive()) {
_delayedTrayUpdateTimer.start();
}
return;
}
if (_workaroundShowAndHideTray) {
if (_qdbusmenuWorkaround) {
// To make tray menu updates work with these bugs (see setupContextMenu)
// we need to hide and show the tray icon. We don't want to do that
// while it's visible!
if (contextMenuVisible()) {
if (!_delayedTrayUpdateTimer.isActive()) {
_delayedTrayUpdateTimer.start();
if (!_workaroundBatchTrayUpdate.isActive()) {
_workaroundBatchTrayUpdate.start();
}
return;
}
@@ -674,30 +631,35 @@ void ownCloudGui::updateContextMenu()
}
_contextMenu->addAction(_actionQuit);
if (_workaroundShowAndHideTray) {
if (_qdbusmenuWorkaround) {
_tray->show();
}
}
void ownCloudGui::updateContextMenuNeeded()
{
// if it's visible and we can update live: update now
if (contextMenuVisible() && updateWhileVisible()) {
// Note: don't update while visible on OSX
// https://bugreports.qt.io/browse/QTBUG-54845
updateContextMenu();
return;
}
// if we can't lazily update: update later
if (_workaroundNoAboutToShowUpdate) {
// Note: don't update immediately even in the invisible case
// as that can lead to extremely frequent menu updates
if (!_delayedTrayUpdateTimer.isActive()) {
_delayedTrayUpdateTimer.start();
// For the workaround case updating while visible is impossible. Instead
// occasionally update the menu when it's invisible.
if (_qdbusmenuWorkaround) {
if (!_workaroundBatchTrayUpdate.isActive()) {
_workaroundBatchTrayUpdate.start();
}
return;
}
#ifdef Q_OS_MAC
// https://bugreports.qt.io/browse/QTBUG-54845
// We cannot update on demand or while visible -> update when invisible.
if (!contextMenuVisible()) {
updateContextMenu();
}
#else
if (updateWhileVisible() && contextMenuVisible())
updateContextMenu();
#endif
// If no update was done here, we might update it on-demand due to
// the aboutToShow() signal.
}
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)

View File

@@ -119,19 +119,14 @@ private:
// tray's menu
QScopedPointer<QMenu> _contextMenu;
// Manually tracking whether the context menu is visible via aboutToShow
// and aboutToHide. Unfortunately aboutToHide isn't reliable everywhere
// so this only gets used with _workaroundManualVisibility (when the tray's
// isVisible() is unreliable)
bool _contextMenuVisibleManual = false;
// Manually tracking whether the context menu is visible, but only works
// on OSX because aboutToHide is not reliable everywhere.
bool _contextMenuVisibleOsx;
QMenu *_recentActionsMenu;
QVector<QMenu *> _accountMenus;
bool _workaroundShowAndHideTray = false;
bool _workaroundNoAboutToShowUpdate = false;
bool _workaroundFakeDoubleClick = false;
bool _workaroundManualVisibility = false;
QTimer _delayedTrayUpdateTimer;
bool _qdbusmenuWorkaround;
QTimer _workaroundBatchTrayUpdate;
QMap<QString, QPointer<ShareDialog>> _shareDialogs;
QAction *_actionLogin;

View File

@@ -183,10 +183,6 @@ SocketApi::SocketApi(QObject *parent)
// Example for developer builds (with ad-hoc signing identity): "" "com.owncloud.desktopclient" ".socketApi"
// Example for official signed packages: "9B5WD74GWJ." "com.owncloud.desktopclient" ".socketApi"
socketPath = SOCKETAPI_TEAM_IDENTIFIER_PREFIX APPLICATION_REV_DOMAIN ".socketApi";
#ifdef Q_OS_MAC
// Tell Finder to use the Extension (checking it from System Preferences -> Extensions)
system("pluginkit -e use -i " APPLICATION_REV_DOMAIN ".FinderSyncExt &");
#endif
} else if (Utility::isLinux() || Utility::isBSD()) {
QString runtimeDir;
runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
@@ -224,11 +220,6 @@ SocketApi::~SocketApi()
// All remaining sockets will be destroyed with _localServer, their parent
ASSERT(_listeners.isEmpty() || _listeners.first().socket->parent() == &_localServer);
_listeners.clear();
#ifdef Q_OS_MAC
// Unload the extension (uncheck from System Preferences -> Extensions)
system("pluginkit -e ignore -i " APPLICATION_REV_DOMAIN ".FinderSyncExt &");
#endif
}
void SocketApi::slotNewConnection()

View File

@@ -204,10 +204,6 @@ void SslButton::slotUpdateMenu()
AccountPtr account = _accountState->account();
if (account->isHttp2Supported()) {
_menu->addAction("HTTP/2")->setEnabled(false);
}
if (account->url().scheme() == QLatin1String("https")) {
QString sslVersion = account->_sessionCipher.protocolString()
+ ", " + account->_sessionCipher.authenticationMethod()

View File

@@ -92,11 +92,6 @@ OCUpdater::OCUpdater(const QUrl &url)
{
}
void OCUpdater::setUpdateUrl(const QUrl &url)
{
_updateUrl = url;
}
bool OCUpdater::performUpdate()
{
ConfigFile cfg;
@@ -184,81 +179,6 @@ void OCUpdater::setDownloadState(DownloadState state)
}
}
#if defined(Q_OS_WIN)
// Following functions are taken from https://github.com/qt/qtbase/blob/5.8/src/corelib/io/qprocess_win.cpp
// to make use of this fix https://github.com/qt/qtbase/commit/bec2fc19fd18768b16925597871c77a61e716abd
// for QTBUG-53833: Without this we get an ugly powershell window on update. In 2.5/master we use Qt 5.10
// which obviously already has the fix.
static QString qt_create_commandline(const QString &program, const QStringList &arguments)
{
QString args;
if (!program.isEmpty()) {
QString programName = program;
if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(QLatin1Char(' ')))
programName = QLatin1Char('\"') + programName + QLatin1Char('\"');
programName.replace(QLatin1Char('/'), QLatin1Char('\\'));
// add the prgram as the first arg ... it works better
args = programName + QLatin1Char(' ');
}
for (int i=0; i<arguments.size(); ++i) {
QString tmp = arguments.at(i);
// Quotes are escaped and their preceding backslashes are doubled.
tmp.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) {
// The argument must not end with a \ since this would be interpreted
// as escaping the quote -- rather put the \ behind the quote: e.g.
// rather use "foo"\ than "foo\"
int i = tmp.length();
while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\'))
--i;
tmp.insert(i, QLatin1Char('"'));
tmp.prepend(QLatin1Char('"'));
}
args += QLatin1Char(' ') + tmp;
}
return args;
}
bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDir = QString(), qint64 *pid = 0)
{
// static const DWORD errorElevationRequired = 740;
QString args = qt_create_commandline(program, arguments);
bool success = false;
PROCESS_INFORMATION pinfo;
DWORD dwCreationFlags = (GetConsoleWindow() ? 0 : CREATE_NO_WINDOW);
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
success = CreateProcess(0, (wchar_t*)args.utf16(),
0, 0, FALSE, dwCreationFlags, 0,
workingDir.isEmpty() ? 0 : (wchar_t*)workingDir.utf16(),
&startupInfo, &pinfo);
// if (success) {
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
if (pid)
*pid = pinfo.dwProcessId;
// } else if (GetLastError() == errorElevationRequired) {
// success = startDetachedUacPrompt(program, arguments, workingDir, pid);
// }
return success;
}
#else
bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDir = QString(), qint64 *pid = 0)
{
return QProcess::startDetached(program, arguments, workingDir, pid);
}
#endif
void OCUpdater::slotStartInstaller()
{
ConfigFile cfg;
@@ -267,30 +187,8 @@ void OCUpdater::slotStartInstaller()
settings.setValue(autoUpdateAttemptedC, true);
settings.sync();
qCInfo(lcUpdater) << "Running updater" << updateFile;
if(updateFile.endsWith(".exe")) {
QProcess::startDetached(updateFile, QStringList() << "/S"
<< "/launch");
} else if(updateFile.endsWith(".msi")) {
// When MSIs are installed without gui they cannot launch applications
// as they lack the user context. That is why we need to run the client
// manually here. We wrap the msiexec and client invocation in a powershell
// script because owncloud.exe will be shut down for installation.
// | Out-Null forces powershell to wait for msiexec to finish.
auto preparePathForPowershell = [](QString path) {
path.replace("'", "''");
return QDir::toNativeSeparators(path);
};
QString msiLogFile = cfg.configPath() + "msi.log";
QString command = QString("&{msiexec /norestart /passive /i '%1' /L*V '%2'| Out-Null ; &'%3'}")
.arg(preparePathForPowershell(updateFile))
.arg(preparePathForPowershell(msiLogFile))
.arg(preparePathForPowershell(QCoreApplication::applicationFilePath()));
startDetached("powershell.exe", QStringList{"-Command", command});
}
QProcess::startDetached(updateFile, QStringList() << "/S"
<< "/launch");
}
void OCUpdater::checkForUpdate()
@@ -400,7 +298,7 @@ void NSISUpdater::versionInfoArrived(const UpdateInfo &info)
showDialog(info);
}
if (!url.isEmpty()) {
_targetFile = cfg.configPath() + url.mid(url.lastIndexOf('/')+1);
_targetFile = cfg.configPath() + url.mid(url.lastIndexOf('/'));
if (QFile(_targetFile).exists()) {
setDownloadState(DownloadComplete);
} else {

View File

@@ -99,8 +99,6 @@ public:
UpdateOnlyAvailableThroughSystem };
explicit OCUpdater(const QUrl &url);
void setUpdateUrl(const QUrl &url);
bool performUpdate();
void checkForUpdate() Q_DECL_OVERRIDE;

View File

@@ -23,20 +23,15 @@ namespace OCC {
class SparkleUpdater : public Updater
{
Q_OBJECT
public:
SparkleUpdater(const QUrl &appCastUrl);
SparkleUpdater(const QString &appCastUrl);
~SparkleUpdater();
void setUpdateUrl(const QUrl &url);
// unused in this updater
void checkForUpdate() Q_DECL_OVERRIDE;
void backgroundCheckForUpdate() Q_DECL_OVERRIDE;
bool handleStartup() Q_DECL_OVERRIDE { return false; }
QString statusString();
private:
class Private;
Private *d;

View File

@@ -73,7 +73,7 @@ class SparkleUpdater::Private
};
// Delete ~/Library//Preferences/com.owncloud.desktopclient.plist to re-test
SparkleUpdater::SparkleUpdater(const QUrl& appCastUrl)
SparkleUpdater::SparkleUpdater(const QString& appCastUrl)
: Updater()
{
d = new Private;
@@ -89,7 +89,9 @@ SparkleUpdater::SparkleUpdater(const QUrl& appCastUrl)
[d->updater resetUpdateCycle];
[d->updater retain];
setUpdateUrl(appCastUrl);
NSURL* url = [NSURL URLWithString:
[NSString stringWithUTF8String: appCastUrl.toUtf8().data()]];
[d->updater setFeedURL: url];
// Sparkle 1.8 required
NSString *userAgent = [NSString stringWithUTF8String: Utility::userAgentString().data()];
@@ -102,14 +104,7 @@ SparkleUpdater::~SparkleUpdater()
delete d;
}
void SparkleUpdater::setUpdateUrl(const QUrl &url)
{
NSURL* nsurl = [NSURL URLWithString:
[NSString stringWithUTF8String: url.toString().toUtf8().data()]];
[d->updater setFeedURL: nsurl];
}
// FIXME: Should be changed to not instanicate the SparkleUpdater at all in this case
bool autoUpdaterAllowed()
{
// See https://github.com/owncloud/client/issues/2931
@@ -138,10 +133,4 @@ void SparkleUpdater::backgroundCheckForUpdate()
}
}
QString SparkleUpdater::statusString()
{
// FIXME Show the real state depending on the callbacks
return QString();
}
} // namespace OCC

View File

@@ -22,7 +22,6 @@
#include "theme.h"
#include "common/utility.h"
#include "version.h"
#include "configfile.h"
#include "config.h"
@@ -40,29 +39,6 @@ Updater *Updater::instance()
return _instance;
}
QUrl Updater::updateUrl()
{
QUrl updateBaseUrl(QString::fromLocal8Bit(qgetenv("OCC_UPDATE_URL")));
if (updateBaseUrl.isEmpty()) {
updateBaseUrl = QUrl(QLatin1String(APPLICATION_UPDATE_URL));
}
if (!updateBaseUrl.isValid() || updateBaseUrl.host() == ".") {
return QUrl();
}
auto url = addQueryParams(updateBaseUrl);
#if defined(Q_OS_MAC) && defined(HAVE_SPARKLE)
url.addQueryItem(QLatin1String("sparkle"), QLatin1String("true"));
#endif
#if defined(Q_OS_WIN)
url.addQueryItem(QLatin1String("msi"), QLatin1String("true"));
#endif
return url;
}
QUrl Updater::addQueryParams(const QUrl &url)
{
QUrl paramUrl = url;
@@ -88,10 +64,14 @@ QUrl Updater::addQueryParams(const QUrl &url)
QString suffix = QString::fromLatin1(MIRALL_STRINGIFY(MIRALL_VERSION_SUFFIX));
paramUrl.addQueryItem(QLatin1String("versionsuffix"), suffix);
auto channel = ConfigFile().updateChannel();
if (channel != "stable") {
paramUrl.addQueryItem(QLatin1String("channel"), channel);
if (suffix.startsWith("daily")
|| suffix.startsWith("nightly")
|| suffix.startsWith("alpha")
|| suffix.startsWith("rc")
|| suffix.startsWith("beta")) {
paramUrl.addQueryItem(QLatin1String("channel"), "beta");
// FIXME: Provide a checkbox in UI to enable regular versions to switch
// to beta channel
}
return paramUrl;
@@ -118,18 +98,23 @@ QString Updater::getSystemInfo()
// To test, cmake with -DAPPLICATION_UPDATE_URL="http://127.0.0.1:8080/test.rss"
Updater *Updater::create()
{
auto url = updateUrl();
if (url.isEmpty()) {
QUrl updateBaseUrl(QString::fromLocal8Bit(qgetenv("OCC_UPDATE_URL")));
if (updateBaseUrl.isEmpty()) {
updateBaseUrl = QUrl(QLatin1String(APPLICATION_UPDATE_URL));
}
if (!updateBaseUrl.isValid() || updateBaseUrl.host() == ".") {
qCWarning(lcUpdater) << "Not a valid updater URL, will not do update check";
return 0;
}
updateBaseUrl = addQueryParams(updateBaseUrl);
#if defined(Q_OS_MAC) && defined(HAVE_SPARKLE)
return new SparkleUpdater(url);
updateBaseUrl.addQueryItem(QLatin1String("sparkle"), QLatin1String("true"));
return new SparkleUpdater(updateBaseUrl.toString());
#elif defined(Q_OS_WIN32)
// the best we can do is notify about updates
return new NSISUpdater(url);
return new NSISUpdater(updateBaseUrl);
#else
return new PassiveUpdateNotifier(url);
return new PassiveUpdateNotifier(QUrl(updateBaseUrl));
#endif
}

View File

@@ -36,7 +36,6 @@ public:
};
static Updater *instance();
static QUrl updateUrl();
virtual void checkForUpdate() = 0;
virtual void backgroundCheckForUpdate() = 0;

View File

@@ -218,7 +218,7 @@ public:
/** Detects a specific bug in older server versions */
bool rootEtagChangesNotOnlySubFolderEtags();
/** True when the server connection is using HTTP2 */
/** True when the server supports HTTP2 */
bool isHttp2Supported() { return _http2Supported; }
void setHttp2Supported(bool value) { _http2Supported = value; }

View File

@@ -18,7 +18,6 @@
#include "theme.h"
#include "common/utility.h"
#include "common/asserts.h"
#include "version.h"
#include "creds/abstractcredentials.h"
@@ -53,7 +52,6 @@ static const char crashReporterC[] = "crashReporter";
static const char optionalDesktopNoficationsC[] = "optionalDesktopNotifications";
static const char skipUpdateCheckC[] = "skipUpdateCheck";
static const char updateCheckIntervalC[] = "updateCheckInterval";
static const char updateChannelC[] = "updateChannel";
static const char geometryC[] = "geometry";
static const char timeoutC[] = "timeout";
static const char chunkSizeC[] = "chunkSize";
@@ -470,28 +468,6 @@ void ConfigFile::setSkipUpdateCheck(bool skip, const QString &connection)
settings.sync();
}
QString ConfigFile::updateChannel() const
{
QString defaultUpdateChannel = QStringLiteral("stable");
QString suffix = QString::fromLatin1(MIRALL_STRINGIFY(MIRALL_VERSION_SUFFIX));
if (suffix.startsWith("daily")
|| suffix.startsWith("nightly")
|| suffix.startsWith("alpha")
|| suffix.startsWith("rc")
|| suffix.startsWith("beta")) {
defaultUpdateChannel = QStringLiteral("beta");
}
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(updateChannelC), defaultUpdateChannel).toString();
}
void ConfigFile::setUpdateChannel(const QString &channel)
{
QSettings settings(configFile(), QSettings::IniFormat);
settings.setValue(QLatin1String(updateChannelC), channel);
}
int ConfigFile::maxLogLines() const
{
QSettings settings(configFile(), QSettings::IniFormat);

View File

@@ -131,9 +131,6 @@ public:
bool skipUpdateCheck(const QString &connection = QString()) const;
void setSkipUpdateCheck(bool, const QString &);
QString updateChannel() const;
void setUpdateChannel(const QString &channel);
void saveGeometryHeader(QHeaderView *header);
void restoreGeometryHeader(QHeaderView *header);

View File

@@ -117,7 +117,6 @@ HttpCredentials::HttpCredentials(const QString &user, const QString &password, c
, _clientSslKey(key)
, _clientSslCertificate(certificate)
, _keychainMigration(false)
, _retryOnKeyChainError(false)
{
}
@@ -220,21 +219,6 @@ void HttpCredentials::deleteOldKeychainEntries()
void HttpCredentials::slotReadClientCertPEMJobDone(QKeychain::Job *incoming)
{
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
Q_ASSERT(!incoming->insecureFallback()); // If insecureFallback is set, the next test would be pointless
if (_retryOnKeyChainError && (incoming->error() == QKeychain::NoBackendAvailable
|| incoming->error() == QKeychain::OtherError)) {
// Could be that the backend was not yet available. Wait some extra seconds.
// (Issues #4274 and #6522)
// (For kwallet, the error is OtherError instead of NoBackendAvailable, maybe a bug in QtKeychain)
qCInfo(lcHttpCredentials) << "Backend unavailable (yet?) Retrying in a few seconds." << incoming->errorString();
QTimer::singleShot(10000, this, &HttpCredentials::fetchFromKeychainHelper);
_retryOnKeyChainError = false;
return;
}
_retryOnKeyChainError = false;
#endif
// Store PEM in memory
ReadPasswordJob *readJob = static_cast<ReadPasswordJob *>(incoming);
if (readJob->error() == NoError && readJob->binaryData().length() > 0) {
@@ -379,12 +363,11 @@ bool HttpCredentials::refreshAccessToken()
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
QString accessToken = json["access_token"].toString();
if (jsonParseError.error != QJsonParseError::NoError || json.isEmpty()) {
// Invalid or empty JSON: Network error maybe?
if (reply->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError || json.isEmpty()) {
// Network error maybe?
qCWarning(lcHttpCredentials) << "Error while refreshing the token" << reply->errorString() << jsonData << jsonParseError.errorString();
} else if (accessToken.isEmpty()) {
// 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)
// The token is no longer valid.
qCDebug(lcHttpCredentials) << "Expired refresh token. Logging out";
_refreshToken.clear();
} else {

View File

@@ -141,7 +141,6 @@ protected:
QSslKey _clientSslKey;
QSslCertificate _clientSslCertificate;
bool _keychainMigration;
bool _retryOnKeyChainError = true; // true if we haven't done yet any reading from keychain
};

View File

@@ -579,7 +579,8 @@ bool OwncloudPropagator::localFileNameClash(const QString &relFile)
re = false;
qCWarning(lcPropagator) << "No valid fileinfo";
} else {
// Need to normalize to composited form because of QTBUG-39622/QTBUG-55896
// Need to normalize to composited form because of
// https://bugreports.qt-project.org/browse/QTBUG-39622
const QString cName = fileInfo.canonicalFilePath().normalized(QString::NormalizationForm_C);
bool equal = (file == cName);
re = (!equal && !cName.endsWith(relFile, Qt::CaseSensitive));
@@ -820,13 +821,10 @@ void PropagatorCompositeJob::slotSubJobFinished(SyncFileItem::Status status)
ASSERT(i >= 0);
_runningJobs.remove(i);
// Any sub job error will cause the whole composite to fail. This is important
// for knowing whether to update the etag in PropagateDirectory, for example.
if (status == SyncFileItem::FatalError
|| status == SyncFileItem::NormalError
|| status == SyncFileItem::SoftError
|| status == SyncFileItem::DetailError
|| status == SyncFileItem::BlacklistedError) {
|| status == SyncFileItem::DetailError) {
_hasError = status;
}

View File

@@ -553,16 +553,6 @@ void PropagateUploadFileCommon::commonErrorHandling(AbstractNetworkJob *job)
abortWithError(status, errorString);
}
void PropagateUploadFileCommon::adjustLastJobTimeout(AbstractNetworkJob *job, quint64 fileSize)
{
job->setTimeout(qBound(
job->timeoutMsec(),
// Calculate 3 minutes for each gigabyte of data
qint64((3 * 60 * 1000) * fileSize / 1e9),
// Maximum of 30 minutes
qint64(30 * 60 * 1000)));
}
void PropagateUploadFileCommon::slotJobDestroyed(QObject *job)
{
_jobs.erase(std::remove(_jobs.begin(), _jobs.end(), job), _jobs.end());

View File

@@ -281,17 +281,6 @@ protected:
*/
void commonErrorHandling(AbstractNetworkJob *job);
/**
* Increases the timeout for the final MOVE/PUT for large files.
*
* This is an unfortunate workaround since the drawback is not being able to
* detect real disconnects in a timely manner. Shall go away when the server
* response starts coming quicker, or there is some sort of async api.
*
* See #6527, enterprise#2480
*/
static void adjustLastJobTimeout(AbstractNetworkJob *job, quint64 fileSize);
// Bases headers that need to be sent with every chunk
QMap<QByteArray, QByteArray> headers();
};

View File

@@ -295,7 +295,6 @@ void PropagateUploadFileNG::startNextChunk()
connect(job, &MoveJob::finishedSignal, this, &PropagateUploadFileNG::slotMoveJobFinished);
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
propagator()->_activeJobList.append(this);
adjustLastJobTimeout(job, fileSize);
job->start();
return;
}

View File

@@ -130,8 +130,6 @@ void PropagateUploadFileV1::startNextChunk()
connect(job, &PUTFileJob::uploadProgress, this, &PropagateUploadFileV1::slotUploadProgress);
connect(job, &PUTFileJob::uploadProgress, device, &UploadDevice::slotJobUploadProgress);
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
if (isFinalChunk)
adjustLastJobTimeout(job, fileSize);
job->start();
propagator()->_activeJobList.append(this);
_currentChunk++;
@@ -303,7 +301,6 @@ void PropagateUploadFileV1::slotPutFinished()
qCWarning(lcPropagateUpload) << "Server does not support X-OC-MTime" << job->reply()->rawHeader("X-OC-MTime");
// Well, the mtime was not set
done(SyncFileItem::SoftError, "Server does not support X-OC-MTime");
return;
}
#ifdef WITH_TESTING

View File

@@ -82,9 +82,10 @@ public:
/** For files whose errors were blacklisted
*
* If an file is blacklisted due to an error it isn't even reattempted. These
* errors should appear in the issues tab but should be silent otherwise.
* errors should appear in the issues tab, but not on the account settings and
* should not cause the sync run to fail.
*
* A SoftError caused by blacklisting.
* A DetailError that doesn't cause sync failure.
*/
BlacklistedError
};

View File

@@ -576,51 +576,6 @@ private slots:
//QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
}
// https://github.com/owncloud/client/issues/6629#issuecomment-402450691
// When a file is moved and the server mtime was not in sync, the local mtime should be kept
void testMoveAndMTimeChange()
{
FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
int nPUT = 0;
int nDELETE = 0;
int nGET = 0;
int nMOVE = 0;
fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &req) {
if (op == QNetworkAccessManager::PutOperation)
++nPUT;
if (op == QNetworkAccessManager::DeleteOperation)
++nDELETE;
if (op == QNetworkAccessManager::GetOperation)
++nGET;
if (req.attribute(QNetworkRequest::CustomVerbAttribute) == "MOVE")
++nMOVE;
return nullptr;
});
// Changing the mtime on the server (without invalidating the etag)
fakeFolder.remoteModifier().find("A/a1")->lastModified = QDateTime::currentDateTimeUtc().addSecs(-50000);
fakeFolder.remoteModifier().find("A/a2")->lastModified = QDateTime::currentDateTimeUtc().addSecs(-40000);
// Move a few files
fakeFolder.remoteModifier().rename("A/a1", "A/a1_server_renamed");
fakeFolder.localModifier().rename("A/a2", "A/a2_local_renamed");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nGET, 0);
QCOMPARE(nPUT, 0);
QCOMPARE(nMOVE, 1);
QCOMPARE(nDELETE, 0);
// Another sync should do nothing
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nGET, 0);
QCOMPARE(nPUT, 0);
QCOMPARE(nMOVE, 1);
QCOMPARE(nDELETE, 0);
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
};
QTEST_GUILESS_MAIN(TestSyncMove)

View File

@@ -373,7 +373,7 @@
<message>
<location filename="../src/gui/accountstate.cpp" line="132"/>
<source>Maintenance mode</source>
<translation>Mode de manteniment</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/accountstate.cpp" line="134"/>
@@ -1415,12 +1415,12 @@ Els elements que poden ser eliminats s&apos;eliminaran si impedeixen que una car
<message>
<location filename="../src/gui/issueswidget.ui" line="73"/>
<source>Show warnings</source>
<translation>Mostra avisos</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="83"/>
<source>Show ignored files</source>
<translation>Mostra arxius descartats</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="133"/>
@@ -2507,7 +2507,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/servernotificationhandler.cpp" line="103"/>
<source>Dismiss</source>
<translation>Ignora</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -2622,12 +2622,12 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/sharedialog.cpp" line="211"/>
<source>Users and Groups</source>
<translation>Usuaris i Grups</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharedialog.cpp" line="218"/>
<source>Public Links</source>
<translation>Enllaços públics</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -2650,7 +2650,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="35"/>
<source>Enter a name to create a new public link...</source>
<translation>Escriu un nom per crear un enllaç públic...</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="42"/>
@@ -2670,12 +2670,12 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="178"/>
<source>Link properties:</source>
<translation>Propietats de l&apos;enllaç:</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="220"/>
<source>Show file listing</source>
<translation>Motra el llistat de fitxers</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="200"/>
@@ -2685,7 +2685,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="20"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Qualsevol podrà accedir a l&apos;arxiu o carpeta amb aquest link</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="117"/>
@@ -2727,7 +2727,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
<source>Copy link to clipboard</source>
<translation>Copiar al portadocuments</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
@@ -2763,7 +2763,7 @@ No és aconsellada usar-la.</translation>
<location filename="../src/gui/sharelinkwidget.cpp" line="63"/>
<location filename="../src/gui/sharelinkwidget.cpp" line="543"/>
<source>Public link</source>
<translation>Enllaç públic</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="253"/>
@@ -2811,7 +2811,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
<source>Copy link to clipboard</source>
<translation>Copiar al portadocuments</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
@@ -2826,7 +2826,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="337"/>
<source>I shared something with you</source>
<translation>He compartit amb tu</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -2919,7 +2919,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/socketapi.cpp" line="557"/>
<source>I shared something with you</source>
<translation>He compartit amb tu</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/socketapi.cpp" line="565"/>
@@ -3850,7 +3850,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="56"/>
<source>Re-open Browser</source>
<translation>Reobrir navegador</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -4177,7 +4177,7 @@ No és aconsellada usar-la.</translation>
<message>
<location filename="../src/gui/guiutility.cpp" line="33"/>
<source>Could not open browser</source>
<translation>No es pot obrir el navegador</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/guiutility.cpp" line="34"/>

View File

@@ -83,12 +83,12 @@
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
<source>Unknown error: network reply was deleted</source>
<translation>Neznámá chyba: odpověď sítě byla smazána</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
<source>Server replied &quot;%1 %2&quot; to &quot;%3 %4&quot;</source>
<translation>Odpověď serveru &quot;%1 %2&quot; do &quot;%3 %4&quot;</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -388,7 +388,7 @@
<message>
<location filename="../src/gui/accountstate.cpp" line="138"/>
<source>Asking Credentials</source>
<translation>Požádat o pověření</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/accountstate.cpp" line="140"/>
@@ -988,7 +988,7 @@ Pokračováním v synchronizaci způsobí přepsání všech vašich souborů st
<message>
<location filename="../src/gui/folderstatusmodel.cpp" line="209"/>
<source>There are unresolved conflicts. Click for details.</source>
<translation>Jsou zde nevyřešené konflikty. Klikněte pro detaily.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderstatusmodel.cpp" line="878"/>
@@ -1396,7 +1396,7 @@ Položky u kterých je povoleno smazání budou vymazány, pokud by bránily ods
<message>
<location filename="../src/gui/issueswidget.ui" line="20"/>
<source>List of issues</source>
<translation>Seznam problémů</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="34"/>
@@ -3628,12 +3628,12 @@ Nedoporučuje se jí používat.</translation>
<location filename="../src/gui/owncloudgui.cpp" line="273"/>
<location filename="../src/gui/owncloudgui.cpp" line="304"/>
<source>Synchronization is paused</source>
<translation>Synchronizace je pozastavena</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/owncloudgui.cpp" line="306"/>
<source>Error during synchronization</source>
<translation>Chyba při synchronizaci</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/owncloudgui.cpp" line="314"/>
@@ -3843,17 +3843,17 @@ Nedoporučuje se jí používat.</translation>
<message>
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="36"/>
<source>Please switch to your browser to proceed.</source>
<translation>Chcete-li pokračovat, přepněte prosím do svého prohlížeče.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="46"/>
<source>An error occured while connecting. Please try again.</source>
<translation>Při připojování došlo k chybě. Prosím zkuste to znovu.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="56"/>
<source>Re-open Browser</source>
<translation>Znovu otevřít prohlížeč</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -4180,7 +4180,7 @@ Nedoporučuje se jí používat.</translation>
<message>
<location filename="../src/gui/guiutility.cpp" line="33"/>
<source>Could not open browser</source>
<translation>Nemohu otevřít prohlížeč</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/guiutility.cpp" line="34"/>

View File

@@ -60,12 +60,12 @@
<message>
<location filename="../src/gui/notificationwidget.ui" line="56"/>
<source>Lorem ipsum dolor sit amet</source>
<translation>Lorem ipsum dolor sit amet</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/notificationwidget.ui" line="69"/>
<source>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod temporm </source>
<translation>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod temporm</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/notificationwidget.ui" line="89"/>
@@ -83,7 +83,7 @@
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
<source>Unknown error: network reply was deleted</source>
<translation>Error desconocido: la respuesta de la red fue eliminada</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>

View File

@@ -83,12 +83,12 @@
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
<source>Unknown error: network reply was deleted</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
<source>Server replied &quot;%1 %2&quot; to &quot;%3 %4&quot;</source>
<translation> &quot;%1 %2&quot; &quot;%3 %4&quot;</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -253,7 +253,7 @@
<message>
<location filename="../src/gui/accountsettings.cpp" line="667"/>
<source>Obtaining authorization from the browser. &lt;a href=&apos;%1&apos;&gt;Click here&lt;/a&gt; to re-open the browser.</source>
<translation>&lt;a href=&apos;%1&apos;&gt;&lt;/a&gt; </translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/accountsettings.cpp" line="671"/>
@@ -1428,12 +1428,12 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<message>
<location filename="../src/gui/issueswidget.ui" line="133"/>
<source>There were too many issues. Not all will be visible here.</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="155"/>
<source>Copy the issues list to the clipboard.</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="158"/>
@@ -1693,7 +1693,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<message>
<location filename="../src/gui/creds/oauth.cpp" line="112"/>
<source>Error returned from the server: &lt;em&gt;%1&lt;/em&gt;</source>
<translation>: &lt;em&gt;%1&lt;/em&gt; </translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/oauth.cpp" line="115"/>
@@ -1708,17 +1708,17 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<message>
<location filename="../src/gui/creds/oauth.cpp" line="121"/>
<source>The reply from the server did not contain all expected fields</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/oauth.cpp" line="125"/>
<source>&lt;h1&gt;Login Error&lt;/h1&gt;&lt;p&gt;%1&lt;/p&gt;</source>
<translation>&lt;h1&gt;&lt;/h1&gt;&lt;p&gt;%1&lt;/p&gt; </translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
<source>&lt;h1&gt;Wrong user&lt;/h1&gt;&lt;p&gt;You logged-in with user &lt;em&gt;%1&lt;/em&gt;, but must login with user &lt;em&gt;%2&lt;/em&gt;.&lt;br&gt;Please log out of %3 in another tab, then &lt;a href=&apos;%4&apos;&gt;click here&lt;/a&gt; and log in as user %2&lt;/p&gt;</source>
<translation>&lt;h1&gt;&lt;/h1&gt;&lt;p&gt;&lt;em&gt;%1&lt;/em&gt;&lt;em&gt;%2&lt;/em&gt;&lt;br&gt; %3 &lt;a href=&apos;%4&apos;&gt;&lt;/a&gt; %2 &lt;/p&gt; </translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -1885,7 +1885,7 @@ for additional privileges during the process.</source>
<message>
<location filename="../src/gui/wizard/owncloudoauthcredspage.cpp" line="44"/>
<source>Login in your browser</source>
<translation></translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -1962,7 +1962,7 @@ It is not advisable to use it.</source>
<message>
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
<source>The server reported the following error:</source>
<translation>:</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
@@ -2723,12 +2723,12 @@ It is not advisable to use it.</source>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="163"/>
<source>Open link in browser</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
<source>Copy link to clipboard</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
@@ -2807,12 +2807,12 @@ It is not advisable to use it.</source>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="235"/>
<source>Open link in browser</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
<source>Copy link to clipboard</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
@@ -4178,12 +4178,12 @@ It is not advisable to use it.</source>
<message>
<location filename="../src/gui/guiutility.cpp" line="33"/>
<source>Could not open browser</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/guiutility.cpp" line="34"/>
<source>There was an error when launching the browser to go to URL %1. Maybe no default browser is configured?</source>
<translation>URL %1 </translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/guiutility.cpp" line="55"/>

View File

@@ -1720,7 +1720,7 @@ Elementer hvor sletting er tillatt, vil bli slettet hvis de forhindrer fjerning
<message>
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
<source>&lt;h1&gt;Wrong user&lt;/h1&gt;&lt;p&gt;You logged-in with user &lt;em&gt;%1&lt;/em&gt;, but must login with user &lt;em&gt;%2&lt;/em&gt;.&lt;br&gt;Please log out of %3 in another tab, then &lt;a href=&apos;%4&apos;&gt;click here&lt;/a&gt; and log in as user %2&lt;/p&gt;</source>
<translation>&lt;h1&gt;Feil bruker&lt;/h1&gt;&lt;p&gt;Du logget inn med bruker &lt;em&gt;%1&lt;/em&gt;, men må logge inn med bruker &lt;em&gt;%2&lt;/em&gt;.&lt;br&gt;Logg ut av %3 i en annen tab, &lt;a href=&apos;%4&apos;&gt;klikk deretter her&lt;/a&gt; og logg inn som bruker %2&lt;/p&gt;</translation>
<translation type="unfinished"/>
</message>
</context>
<context>

View File

@@ -83,7 +83,7 @@
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
<source>Unknown error: network reply was deleted</source>
<translation>Onbekende fout: antwoord van het netwerk is verwijderd</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
@@ -243,7 +243,7 @@
<message>
<location filename="../src/gui/accountsettings.cpp" line="656"/>
<source>Server %1 is currently in maintenance mode.</source>
<translation>Server %1 is momenteel in onderhoudsmodus.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/accountsettings.cpp" line="658"/>
@@ -253,7 +253,7 @@
<message>
<location filename="../src/gui/accountsettings.cpp" line="667"/>
<source>Obtaining authorization from the browser. &lt;a href=&apos;%1&apos;&gt;Click here&lt;/a&gt; to re-open the browser.</source>
<translation>Probeert autorisatie te krijgen van de browser. 1 Klik hier 1 om de browser opnieuw te openen.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/accountsettings.cpp" line="671"/>
@@ -990,7 +990,7 @@ Doorgaan met deze synchronisatie overschrijft al uw bestanden door een eerdere v
<message>
<location filename="../src/gui/folderstatusmodel.cpp" line="209"/>
<source>There are unresolved conflicts. Click for details.</source>
<translation>Er zijn onopgeloste conflicten. Klik voor details.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderstatusmodel.cpp" line="878"/>
@@ -1000,7 +1000,7 @@ Doorgaan met deze synchronisatie overschrijft al uw bestanden door een eerdere v
<message>
<location filename="../src/gui/folderstatusmodel.cpp" line="884"/>
<source>Reconciling changes</source>
<translation>Wijzigingen doorvoeren</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderstatusmodel.cpp" line="919"/>
@@ -1434,12 +1434,12 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma
<message>
<location filename="../src/gui/issueswidget.ui" line="133"/>
<source>There were too many issues. Not all will be visible here.</source>
<translation>Er zijn teveel problemen. Niet alles zal worden vertoond.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="155"/>
<source>Copy the issues list to the clipboard.</source>
<translation>Kopieer de probleemlijst naar het klembord.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="158"/>
@@ -1482,7 +1482,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma
<message>
<location filename="../src/gui/logbrowser.cpp" line="89"/>
<source>&amp;Capture debug messages</source>
<translation>&amp;Capture berichten debuggen</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/logbrowser.cpp" line="101"/>
@@ -1704,17 +1704,17 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma
<message>
<location filename="../src/gui/creds/oauth.cpp" line="115"/>
<source>There was an error accessing the &apos;token&apos; endpoint: &lt;br&gt;&lt;em&gt;%1&lt;/em&gt;</source>
<translation>Er heeft zich een fout voorgedaan bij het verkrijgen van de &apos;token&apos; eindpunt: 1 2 %1 2</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/oauth.cpp" line="118"/>
<source>Could not parse the JSON returned from the server: &lt;br&gt;&lt;em&gt;%1&lt;/em&gt;</source>
<translation>Kon de JSON dat teruggekomen is van de server niet ontleden: 1 2 %1 2</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/oauth.cpp" line="121"/>
<source>The reply from the server did not contain all expected fields</source>
<translation>Het antwoord van de server bevat niet alle verwachte velden</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/oauth.cpp" line="125"/>
@@ -1724,7 +1724,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma
<message>
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
<source>&lt;h1&gt;Wrong user&lt;/h1&gt;&lt;p&gt;You logged-in with user &lt;em&gt;%1&lt;/em&gt;, but must login with user &lt;em&gt;%2&lt;/em&gt;.&lt;br&gt;Please log out of %3 in another tab, then &lt;a href=&apos;%4&apos;&gt;click here&lt;/a&gt; and log in as user %2&lt;/p&gt;</source>
<translation>1 Verkeerde gebruiker 1 2 U bent ingelogd met user 3 %1 3, maar dient ingelogd te zijn met user 4 %2 4. 5 Log %3 alstublieft uit in een andere tabblad, vervolgens 6 klikt u hier 6 en log-in als user %2 2</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -1892,7 +1892,7 @@ vragen om extra autorisaties tijdens installatie.</translation>
<message>
<location filename="../src/gui/wizard/owncloudoauthcredspage.cpp" line="44"/>
<source>Login in your browser</source>
<translation>Login in uw browser</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -1970,7 +1970,7 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
<source>The server reported the following error:</source>
<translation>De server rapporteerde de volgende fout:</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
@@ -2132,7 +2132,7 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="459"/>
<source>The download would reduce free local disk space below the limit</source>
<translation>De download zal de vrije lokale schijfruimte reduceren tot onder het limiet</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="463"/>
@@ -2319,7 +2319,7 @@ We adviseren deze site niet te gebruiken.</translation>
<location filename="../src/libsync/propagateupload.cpp" line="186"/>
<location filename="../src/libsync/propagateupload.cpp" line="549"/>
<source>Upload of %1 exceeds the quota for the folder</source>
<translation>Upload van %1 overtreft de quota van de folder</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagateupload.cpp" line="622"/>
@@ -2659,12 +2659,12 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="35"/>
<source>Enter a name to create a new public link...</source>
<translation>Voer een naam in om een nieuwe publieke link aan te maken</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="42"/>
<source>&amp;Create new</source>
<translation>&amp;Create nieuw</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="105"/>
@@ -2715,12 +2715,12 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="93"/>
<source>Link shares have been disabled</source>
<translation>Link delen zijn uitgeschakeld</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="107"/>
<source>Create public link share</source>
<translation>Maak een verdeelbare publieke link aan</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="168"/>
@@ -2741,7 +2741,7 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
<source>Copy link to clipboard (direct download)</source>
<translation>Kopieer de link naar het klembord (directe download)</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="166"/>
@@ -2751,17 +2751,17 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="167"/>
<source>Send link by email (direct download)</source>
<translation>Verzend link met email (directe download)</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="519"/>
<source>Confirm Link Share Deletion</source>
<translation>Bevestig Gedeelde Link Verwijdering</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="520"/>
<source>&lt;p&gt;Do you really want to delete the public link share &lt;i&gt;%1&lt;/i&gt;?&lt;/p&gt;&lt;p&gt;Note: This action cannot be undone.&lt;/p&gt;</source>
<translation>1 Wilt u echt de verdeelbare publieke link verwijderen 2 %1 2 ? 1 3 Let op: deze actie kan niet ongedaan gemaakt worden. 3</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="527"/>
@@ -2777,7 +2777,7 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="253"/>
<source>Delete link share</source>
<translation>Verwijder verdeelbare link</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="458"/>
@@ -4186,7 +4186,7 @@ We adviseren deze site niet te gebruiken.</translation>
<message>
<location filename="../src/gui/guiutility.cpp" line="33"/>
<source>Could not open browser</source>
<translation>Kon het browser niet openen</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/guiutility.cpp" line="34"/>

View File

@@ -1966,7 +1966,7 @@ Não é aconselhada a sua utilização.</translation>
<message>
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
<source>The server reported the following error:</source>
<translation>O servidor retornou o seguinte erro:</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
@@ -2727,7 +2727,7 @@ Não é aconselhada a sua utilização.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="163"/>
<source>Open link in browser</source>
<translation>Abrir ligação no navegador</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
@@ -2742,7 +2742,7 @@ Não é aconselhada a sua utilização.</translation>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="166"/>
<source>Send link by email</source>
<translation>Enviar hiperligação por correio eletrónico</translation>
<translation>Enviar hiperligação por e-mail</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="167"/>
@@ -2811,7 +2811,7 @@ Não é aconselhada a sua utilização.</translation>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="235"/>
<source>Open link in browser</source>
<translation>Abrir ligação no navegador</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
@@ -2821,7 +2821,7 @@ Não é aconselhada a sua utilização.</translation>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
<source>Send link by email</source>
<translation>Enviar hiperligação por correio eletrónico</translation>
<translation>Enviar hiperligação por e-mail</translation>
</message>
<message>
<location filename="../src/gui/shareusergroupwidget.cpp" line="249"/>
@@ -2939,7 +2939,7 @@ Não é aconselhada a sua utilização.</translation>
<message>
<location filename="../src/gui/socketapi.cpp" line="568"/>
<source>Send private link by email...</source>
<translation>Enviar hiperligação privada por correio eletrónico...</translation>
<translation type="unfinished"/>
</message>
</context>
<context>

View File

@@ -83,12 +83,12 @@
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
<source>Unknown error: network reply was deleted</source>
<translation>Незнайома помилка: відповідь мережі була видалена</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
<source>Server replied &quot;%1 %2&quot; to &quot;%3 %4&quot;</source>
<translation>Сервер відповів &quot;%1 %2&quot; на &quot;%3 %4&quot;</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -228,7 +228,7 @@
<message>
<location filename="../src/gui/accountsettings.cpp" line="650"/>
<source>The server version %1 is old and unsupported! Proceed at your own risk.</source>
<translation>Версія на вашому сервері %1 застаріла та вже не підтримується! Продовжуйте на свій ризик та розсуд.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/accountsettings.cpp" line="652"/>
@@ -258,7 +258,7 @@
<message>
<location filename="../src/gui/accountsettings.cpp" line="671"/>
<source>Connecting to %1...</source>
<translation>З&apos;єднання з %1...</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/accountsettings.cpp" line="674"/>
@@ -567,7 +567,7 @@
<message>
<location filename="../src/gui/application.cpp" line="168"/>
<source>Quit ownCloud</source>
<translation>Вийти з ownCloud</translation>
<translation type="unfinished"/>
</message>
</context>
<context>
@@ -1387,7 +1387,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<message>
<location filename="../src/gui/issueswidget.ui" line="20"/>
<source>List of issues</source>
<translation>Перелік проблем</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/issueswidget.ui" line="34"/>

View File

@@ -2671,7 +2671,7 @@ It is not advisable to use it.</source>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="220"/>
<source>Show file listing</source>
<translation></translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="200"/>