mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2026-04-07 01:34:16 +02:00
Compare commits
72 Commits
v2.4.1
...
v2.4.2-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d38703898 | ||
|
|
f283c0c59c | ||
|
|
0d83d7cb68 | ||
|
|
2e10cec2cb | ||
|
|
3802131bad | ||
|
|
5467950f62 | ||
|
|
3ba5bb52f3 | ||
|
|
5c011c5c21 | ||
|
|
532e975687 | ||
|
|
7efc3220f4 | ||
|
|
b5444def55 | ||
|
|
c7ba898fe0 | ||
|
|
7a8c8b19c2 | ||
|
|
72c9d207a0 | ||
|
|
1e4727cfec | ||
|
|
8237c5be69 | ||
|
|
63877d5293 | ||
|
|
737353a017 | ||
|
|
528b5e3108 | ||
|
|
5d098140e7 | ||
|
|
aeb4eed7b5 | ||
|
|
c68b112858 | ||
|
|
b4f2c3c369 | ||
|
|
084f522de1 | ||
|
|
5d5e0220b4 | ||
|
|
7b5ce24302 | ||
|
|
19e33d0924 | ||
|
|
f8a4994307 | ||
|
|
04fb952814 | ||
|
|
8d6e9523bb | ||
|
|
b317cc18d0 | ||
|
|
03a5833e29 | ||
|
|
91a9c65173 | ||
|
|
edabed9594 | ||
|
|
838beded20 | ||
|
|
7dcfe9993c | ||
|
|
b73e2fbdab | ||
|
|
d49771b43a | ||
|
|
928cdf4f4f | ||
|
|
8da6fc40a1 | ||
|
|
6e84a8d420 | ||
|
|
29557ea550 | ||
|
|
37a93dca63 | ||
|
|
b632b7e0fa | ||
|
|
fc8e3b0914 | ||
|
|
861d777899 | ||
|
|
ff3e3ce886 | ||
|
|
567f7eb205 | ||
|
|
c3c8ab85ec | ||
|
|
d1c887d754 | ||
|
|
991f4faafb | ||
|
|
371acb296d | ||
|
|
1119bcf539 | ||
|
|
d67018311f | ||
|
|
eaecec418e | ||
|
|
ab27bcacdf | ||
|
|
536a051460 | ||
|
|
259a117db5 | ||
|
|
167939a8c9 | ||
|
|
41ebfb635e | ||
|
|
017b8e9de3 | ||
|
|
6453c57979 | ||
|
|
a01c73be19 | ||
|
|
f63737ecb0 | ||
|
|
dd87799a82 | ||
|
|
da6b515bfc | ||
|
|
f9a03fa288 | ||
|
|
a5c66cf289 | ||
|
|
41b908e293 | ||
|
|
6ffed87b08 | ||
|
|
bd5ea43547 | ||
|
|
8ba27cb0f1 |
91
.drone.yml
Normal file
91
.drone.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#
|
||||||
|
# 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
37
.travis.yml
@@ -1,37 +0,0 @@
|
|||||||
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
|
|
||||||
17
ChangeLog
17
ChangeLog
@@ -1,6 +1,23 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
version 2.4.2 (2018-06-xx)
|
||||||
|
* 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)
|
version 2.4.1 (2018-02-xx)
|
||||||
* Ignore files with file names that can't be encoded for the filesystem (#6287, #5676, #5719)
|
* 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)
|
* Issues: Speed up insertion and add hard upper limit (#6272)
|
||||||
|
|||||||
51
Jenkinsfile
vendored
51
Jenkinsfile
vendored
@@ -1,51 +0,0 @@
|
|||||||
#!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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -19,4 +19,4 @@ set( MAC_INSTALLER_BACKGROUND_FILE "${CMAKE_SOURCE_DIR}/admin/osx/installer-back
|
|||||||
|
|
||||||
option( WITH_CRASHREPORTER "Build crashreporter" OFF )
|
option( WITH_CRASHREPORTER "Build crashreporter" OFF )
|
||||||
set( CRASHREPORTER_SUBMIT_URL "https://crash-reports.owncloud.com/submit" CACHE string "URL for crash reporter" )
|
set( CRASHREPORTER_SUBMIT_URL "https://crash-reports.owncloud.com/submit" CACHE string "URL for crash reporter" )
|
||||||
set( CRASHREPORTER_ICON ":/owncloud-icon.png" )
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# ownCloud Desktop Client
|
# ownCloud Desktop Client
|
||||||
|
|
||||||
[](https://jenkins.owncloud.org/job/owncloud-client/job/client/job/master/)
|
[](https://drone.owncloud.com/owncloud/client)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
set( MIRALL_VERSION_MAJOR 2 )
|
set( MIRALL_VERSION_MAJOR 2 )
|
||||||
set( MIRALL_VERSION_MINOR 4 )
|
set( MIRALL_VERSION_MINOR 4 )
|
||||||
set( MIRALL_VERSION_PATCH 1 )
|
set( MIRALL_VERSION_PATCH 2 )
|
||||||
set( MIRALL_VERSION_YEAR 2017 )
|
set( MIRALL_VERSION_YEAR 2018 )
|
||||||
set( MIRALL_SOVERSION 0 )
|
set( MIRALL_SOVERSION 0 )
|
||||||
|
|
||||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||||
set( MIRALL_VERSION_SUFFIX "git") #e.g. beta1, beta2, rc1
|
set( MIRALL_VERSION_SUFFIX "rc1") #e.g. beta1, beta2, rc1
|
||||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||||
|
|
||||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ else()
|
|||||||
set(MAC_INSTALLER_DO_CUSTOM_BACKGROUND "0")
|
set(MAC_INSTALLER_DO_CUSTOM_BACKGROUND "0")
|
||||||
endif()
|
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(create_mac_pkg.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/create_mac.sh)
|
||||||
configure_file(macosx.pkgproj ${CMAKE_CURRENT_BINARY_DIR}/macosx.pkgproj)
|
configure_file(macosx.pkgproj ${CMAKE_CURRENT_BINARY_DIR}/macosx.pkgproj)
|
||||||
configure_file(pre_install.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh)
|
configure_file(pre_install.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ identity="$3"
|
|||||||
prjfile=$build_path/admin/osx/macosx.pkgproj
|
prjfile=$build_path/admin/osx/macosx.pkgproj
|
||||||
|
|
||||||
# The name of the installer package
|
# The name of the installer package
|
||||||
installer="@APPLICATION_SHORTNAME@-@MIRALL_VERSION_FULL@@MIRALL_VERSION_SUFFIX@"
|
installer="@APPLICATION_SHORTNAME@-qt@Qt5Core_VERSION@-@MIRALL_VERSION_FULL@@MIRALL_VERSION_SUFFIX@"
|
||||||
installer_file="$installer.pkg"
|
installer_file="$installer.pkg"
|
||||||
installer_file_tar="$installer.pkg.tar"
|
installer_file_tar="$installer.pkg.tar"
|
||||||
installer_file_tar_bz2="$installer.pkg.tar.bz2"
|
installer_file_tar_bz2="$installer.pkg.tar.bz2"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import subprocess
|
|||||||
import commands
|
import commands
|
||||||
import sys
|
import sys
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
def QueryQMake(attrib):
|
def QueryQMake(attrib):
|
||||||
return subprocess.check_output([qmake_path, '-query', attrib]).rstrip('\n')
|
return subprocess.check_output([qmake_path, '-query', attrib]).rstrip('\n')
|
||||||
@@ -92,6 +93,8 @@ commands.append(['mkdir', '-p', resources_dir])
|
|||||||
plugins_dir = os.path.join(bundle_dir, 'Contents', 'PlugIns')
|
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)];
|
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_libraries = []
|
||||||
fixed_frameworks = []
|
fixed_frameworks = []
|
||||||
@@ -334,9 +337,19 @@ def FindQtPlugin(name):
|
|||||||
for binary in binaries:
|
for binary in binaries:
|
||||||
FixBinary(binary)
|
FixBinary(binary)
|
||||||
|
|
||||||
|
|
||||||
|
if LooseVersion(qt_version) >= LooseVersion("5.10.0"):
|
||||||
|
QT_PLUGINS.append('styles/libqmacstyle.dylib')
|
||||||
for plugin in QT_PLUGINS:
|
for plugin in QT_PLUGINS:
|
||||||
FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin))
|
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:
|
if len(sys.argv) <= 2:
|
||||||
print 'Will run %d commands:' % len(commands)
|
print 'Will run %d commands:' % len(commands)
|
||||||
for command in commands:
|
for command in commands:
|
||||||
|
|||||||
@@ -27,11 +27,9 @@
|
|||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>@MIRALL_VERSION_STRING@</string>
|
<string>@MIRALL_VERSION_STRING@</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>(C) 2014-2016 @APPLICATION_VENDOR@</string>
|
<string>(C) 2014-2018 @APPLICATION_VENDOR@</string>
|
||||||
<key>SUShowReleaseNotes</key>
|
<key>SUShowReleaseNotes</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>LSMinimumBundleVersion</key>
|
|
||||||
<string>10.7.0</string>
|
|
||||||
<key>SUPublicDSAKeyFile</key>
|
<key>SUPublicDSAKeyFile</key>
|
||||||
<string>dsa_pub.pem</string>
|
<string>dsa_pub.pem</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|||||||
@@ -278,6 +278,90 @@ 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
|
||||||
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||||
GenericName[oc]=Dorsièr de Sincronizacion
|
GenericName[oc]=Dorsièr de Sincronizacion
|
||||||
@@ -362,6 +446,10 @@ Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
|||||||
GenericName[ko]=폴더 동기화
|
GenericName[ko]=폴더 동기화
|
||||||
Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
||||||
Icon[ko]=@APPLICATION_EXECUTABLE@
|
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
|
Comment[hu_HU]=@APPLICATION_NAME@ asztali szinkronizációs kliens
|
||||||
GenericName[hu_HU]=Könyvtár szinkronizálás
|
GenericName[hu_HU]=Könyvtár szinkronizálás
|
||||||
Name[hu_HU]=@APPLICATION_NAME@ asztali szinkr. kliens
|
Name[hu_HU]=@APPLICATION_NAME@ asztali szinkr. kliens
|
||||||
|
|||||||
@@ -34,12 +34,15 @@ from gi.repository import GObject, Nautilus
|
|||||||
appname = 'ownCloud'
|
appname = 'ownCloud'
|
||||||
|
|
||||||
print("Initializing "+appname+"-client-nautilus extension")
|
print("Initializing "+appname+"-client-nautilus extension")
|
||||||
|
print("Using python version {}".format(sys.version_info))
|
||||||
|
|
||||||
def get_local_path(url):
|
def get_local_path(url):
|
||||||
if url[0:7] == 'file://':
|
if url[0:7] == 'file://':
|
||||||
url = url[7:]
|
url = url[7:]
|
||||||
unquote = urllib.parse.unquote if python3 else urllib.unquote
|
if python3:
|
||||||
return unquote(url)
|
return urllib.parse.unquote(url)
|
||||||
|
else:
|
||||||
|
return urllib.unquote(url).decode('utf-8')
|
||||||
|
|
||||||
def get_runtime_dir():
|
def get_runtime_dir():
|
||||||
"""Returns the value of $XDG_RUNTIME_DIR, a directory path.
|
"""Returns the value of $XDG_RUNTIME_DIR, a directory path.
|
||||||
@@ -61,7 +64,7 @@ class SocketConnect(GObject.GObject):
|
|||||||
self._watch_id = 0
|
self._watch_id = 0
|
||||||
self._sock = None
|
self._sock = None
|
||||||
self._listeners = [self._update_registered_paths]
|
self._listeners = [self._update_registered_paths]
|
||||||
self._remainder = ''.encode()
|
self._remainder = ''.encode('utf-8')
|
||||||
self.nautilusVFSFile_table = {} # not needed in this object actually but shared
|
self.nautilusVFSFile_table = {} # not needed in this object actually but shared
|
||||||
# all over the other objects.
|
# all over the other objects.
|
||||||
|
|
||||||
@@ -79,7 +82,7 @@ class SocketConnect(GObject.GObject):
|
|||||||
# print("Server command: " + cmd)
|
# print("Server command: " + cmd)
|
||||||
if self.connected:
|
if self.connected:
|
||||||
try:
|
try:
|
||||||
self._sock.send(cmd.encode())
|
self._sock.send(cmd.encode('utf-8'))
|
||||||
except:
|
except:
|
||||||
print("Sending failed.")
|
print("Sending failed.")
|
||||||
self.reconnect()
|
self.reconnect()
|
||||||
@@ -94,18 +97,15 @@ class SocketConnect(GObject.GObject):
|
|||||||
self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
sock_file = os.path.join(get_runtime_dir(), appname, "socket")
|
sock_file = os.path.join(get_runtime_dir(), appname, "socket")
|
||||||
try:
|
try:
|
||||||
print("Socket File: " + sock_file)
|
|
||||||
self._sock.connect(sock_file) # fails if sock_file doesn't exist
|
self._sock.connect(sock_file) # fails if sock_file doesn't exist
|
||||||
self.connected = True
|
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)
|
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')
|
self.sendCommand('GET_STRINGS:\n')
|
||||||
|
|
||||||
return False # Don't run again
|
return False # Don't run again
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Could not connect to unix socket. " + str(e))
|
print("Could not connect to unix socket " + sock_file + ". " + str(e))
|
||||||
except Exception as e: # Bad habbit
|
except Exception as e: # Bad habbit
|
||||||
print("Connect could not be established, try again later.")
|
print("Connect could not be established, try again later.")
|
||||||
self._sock.close()
|
self._sock.close()
|
||||||
@@ -118,24 +118,24 @@ class SocketConnect(GObject.GObject):
|
|||||||
# Prepend the remaining data from last call
|
# Prepend the remaining data from last call
|
||||||
if len(self._remainder) > 0:
|
if len(self._remainder) > 0:
|
||||||
data = self._remainder + data
|
data = self._remainder + data
|
||||||
self._remainder = ''.encode()
|
self._remainder = ''.encode('utf-8')
|
||||||
|
|
||||||
if len(data) > 0:
|
if len(data) > 0:
|
||||||
# Remember the remainder for next round
|
# Remember the remainder for next round
|
||||||
lastNL = data.rfind('\n'.encode());
|
lastNL = data.rfind('\n'.encode('utf-8'));
|
||||||
if lastNL > -1 and lastNL < len(data):
|
if lastNL > -1 and lastNL < len(data):
|
||||||
self._remainder = data[lastNL+1:]
|
self._remainder = data[lastNL+1:]
|
||||||
data = data[:lastNL]
|
data = data[:lastNL]
|
||||||
|
|
||||||
for l in data.split('\n'.encode()):
|
for l in data.split('\n'.encode('utf-8')):
|
||||||
self._handle_server_response(l.decode())
|
self._handle_server_response(l.decode('utf-8'))
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True # Run again
|
return True # Run again
|
||||||
|
|
||||||
def _handle_server_response(self, line):
|
def _handle_server_response(self, line):
|
||||||
print("Server response: " + line)
|
# print("Server response: " + line)
|
||||||
parts = line.split(':')
|
parts = line.split(':')
|
||||||
action = parts[0]
|
action = parts[0]
|
||||||
args = parts[1:]
|
args = parts[1:]
|
||||||
@@ -262,11 +262,11 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
|
|||||||
|
|
||||||
def context_menu_action(self, menu, action, file):
|
def context_menu_action(self, menu, action, file):
|
||||||
filename = get_local_path(file.get_uri())
|
filename = get_local_path(file.get_uri())
|
||||||
print("Context menu: " + action + ' ' + filename)
|
# print("Context menu: " + action + ' ' + filename)
|
||||||
socketConnect.sendCommand(action + ":" + filename + "\n")
|
socketConnect.sendCommand(action + ":" + filename + "\n")
|
||||||
|
|
||||||
|
|
||||||
class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
|
class SyncStateExtension(GObject.GObject, Nautilus.InfoProvider):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
GObject.GObject.__init__(self)
|
GObject.GObject.__init__(self)
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static void fillFileRecordFromGetQuery(SyncJournalFileRecord &rec, SqlQuery &que
|
|||||||
|
|
||||||
static QString defaultJournalMode(const QString &dbPath)
|
static QString defaultJournalMode(const QString &dbPath)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#if defined(Q_OS_WIN)
|
||||||
// See #2693: Some exFAT file systems seem unable to cope with the
|
// See #2693: Some exFAT file systems seem unable to cope with the
|
||||||
// WAL journaling mode. They work fine with DELETE.
|
// WAL journaling mode. They work fine with DELETE.
|
||||||
QString fileSystem = FileSystem::fileSystemForPath(dbPath);
|
QString fileSystem = FileSystem::fileSystemForPath(dbPath);
|
||||||
@@ -74,6 +74,11 @@ static QString defaultJournalMode(const QString &dbPath)
|
|||||||
qCInfo(lcDb) << "Filesystem contains FAT - using DELETE journal mode";
|
qCInfo(lcDb) << "Filesystem contains FAT - using DELETE journal mode";
|
||||||
return "DELETE";
|
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
|
#else
|
||||||
Q_UNUSED(dbPath)
|
Q_UNUSED(dbPath)
|
||||||
#endif
|
#endif
|
||||||
@@ -271,6 +276,11 @@ bool SyncJournalDb::sqlFail(const QString &log, const SqlQuery &query)
|
|||||||
bool SyncJournalDb::checkConnect()
|
bool SyncJournalDb::checkConnect()
|
||||||
{
|
{
|
||||||
if (_db.isOpen()) {
|
if (_db.isOpen()) {
|
||||||
|
if (!QFile::exists(_dbFile)) {
|
||||||
|
qCWarning(lcDb) << "Database open, but file file" + _dbFile + " does not exist";
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
PROJECT( CrashReporter )
|
PROJECT( CrashReporter )
|
||||||
cmake_policy(SET CMP0017 NEW)
|
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
|
# TODO: differentiate release channel
|
||||||
# if(BUILD_RELEASE)
|
# if(BUILD_RELEASE)
|
||||||
# set(CRASHREPORTER_RELEASE_CHANNEL "release")
|
# set(CRASHREPORTER_RELEASE_CHANNEL "release")
|
||||||
@@ -15,9 +8,30 @@ qt_add_resources( crashreporter_RC_RCC ${crashreporter_RC} )
|
|||||||
set(CRASHREPORTER_RELEASE_CHANNEL "nightly")
|
set(CRASHREPORTER_RELEASE_CHANNEL "nightly")
|
||||||
# endif()
|
# 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
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CrashReporterConfig.h.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/CrashReporterConfig.h)
|
${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}
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}
|
||||||
"../3rdparty/libcrashreporter-qt/src/"
|
"../3rdparty/libcrashreporter-qt/src/"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<RCC>
|
|
||||||
<qresource prefix="/">
|
|
||||||
<file alias="owncloud-icon.png">../../theme/colored/owncloud-icon-128.png</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
||||||
5
src/crashreporter/resources.qrc.in
Normal file
5
src/crashreporter/resources.qrc.in
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file alias="@CRASHREPORTER_ICON_FILENAME@">@CRASHREPORTER_ICON_PATH@</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
@@ -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) */
|
/* First, check that the file is NOT in our tree (another file with the same name was added) */
|
||||||
if (our_tree->findFile(basePath)) {
|
if (our_tree->findFile(basePath)) {
|
||||||
other = nullptr;
|
other = nullptr;
|
||||||
qCDebug(lcReconcile, "Origin found in our tree : %s", basePath.constData());
|
qCInfo(lcReconcile, "Origin found in our tree : %s", basePath.constData());
|
||||||
} else {
|
} else {
|
||||||
/* Find the potential rename source file in the other tree.
|
/* 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
|
* 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.
|
* The journal is cleaned up later after propagation.
|
||||||
*/
|
*/
|
||||||
other = other_tree->findFile(basePath);
|
other = other_tree->findFile(basePath);
|
||||||
qCDebug(lcReconcile, "Rename origin in other tree (%s) %s",
|
qCInfo(lcReconcile, "Rename origin in other tree (%s) %s",
|
||||||
basePath.constData(), other ? "found" : "not found");
|
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.
|
// Some other EVAL_RENAME already claimed other.
|
||||||
// We do nothing: maybe a different candidate for
|
// We do nothing: maybe a different candidate for
|
||||||
// other is found as well?
|
// other is found as well?
|
||||||
qCDebug(lcReconcile, "Other has already been renamed to %s",
|
qCInfo(lcReconcile, "Other has already been renamed to %s",
|
||||||
other->rename_path.constData());
|
other->rename_path.constData());
|
||||||
} else if (cur->type == CSYNC_FTW_TYPE_DIR
|
} else if (cur->type == CSYNC_FTW_TYPE_DIR
|
||||||
// The local replica is reconciled first, so the remote tree would
|
// The local replica is reconciled first, so the remote tree would
|
||||||
@@ -187,13 +187,17 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
|
|||||||
|| other->instruction == CSYNC_INSTRUCTION_NONE
|
|| other->instruction == CSYNC_INSTRUCTION_NONE
|
||||||
|| other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|
|| other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||||
|| other->instruction == CSYNC_INSTRUCTION_REMOVE) {
|
|| other->instruction == CSYNC_INSTRUCTION_REMOVE) {
|
||||||
qCDebug(lcReconcile, "Switching %s to RENAME to %s",
|
qCInfo(lcReconcile, "Switching %s to RENAME to %s",
|
||||||
other->path.constData(), cur->path.constData());
|
other->path.constData(), cur->path.constData());
|
||||||
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
||||||
other->rename_path = cur->path;
|
other->rename_path = cur->path;
|
||||||
if( !cur->file_id.isEmpty() ) {
|
if( !cur->file_id.isEmpty() ) {
|
||||||
other->file_id = cur->file_id;
|
other->file_id = cur->file_id;
|
||||||
}
|
}
|
||||||
|
if (ctx->current == LOCAL_REPLICA) {
|
||||||
|
// Keep the local mtime.
|
||||||
|
other->modtime = cur->modtime;
|
||||||
|
}
|
||||||
other->inode = cur->inode;
|
other->inode = cur->inode;
|
||||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||||
// We have consumed 'other': exit this loop to not consume another one.
|
// We have consumed 'other': exit this loop to not consume another one.
|
||||||
@@ -207,7 +211,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.
|
// Local: The remote reconcile will be able to deal with this.
|
||||||
// Remote: The local replica has already dealt with this.
|
// Remote: The local replica has already dealt with this.
|
||||||
// See the EVAL_RENAME case when other was found directly.
|
// See the EVAL_RENAME case when other was found directly.
|
||||||
qCDebug(lcReconcile, "File in a renamed directory, other side's instruction: %d",
|
qCInfo(lcReconcile, "File in a renamed directory, other side's instruction: %d",
|
||||||
other->instruction);
|
other->instruction);
|
||||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||||
} else {
|
} else {
|
||||||
@@ -215,7 +219,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
|
// 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
|
// due to a remote move of the same file. In these scenarios we just
|
||||||
// want the instruction to stay NEW.
|
// want the instruction to stay NEW.
|
||||||
qCDebug(lcReconcile, "Other already has instruction %d",
|
qCInfo(lcReconcile, "Other already has instruction %d",
|
||||||
other->instruction);
|
other->instruction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -223,7 +227,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
|
|||||||
if (ctx->current == LOCAL_REPLICA) {
|
if (ctx->current == LOCAL_REPLICA) {
|
||||||
/* use the old name to find the "other" node */
|
/* use the old name to find the "other" node */
|
||||||
OCC::SyncJournalFileRecord base;
|
OCC::SyncJournalFileRecord base;
|
||||||
qCDebug(lcReconcile, "Finding rename origin through inode %" PRIu64 "",
|
qCInfo(lcReconcile, "Finding rename origin through inode %" PRIu64 "",
|
||||||
cur->inode);
|
cur->inode);
|
||||||
ctx->statedb->getFileRecordByInode(cur->inode, &base);
|
ctx->statedb->getFileRecordByInode(cur->inode, &base);
|
||||||
renameCandidateProcessing(base._path);
|
renameCandidateProcessing(base._path);
|
||||||
@@ -236,7 +240,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) {
|
|||||||
// line.
|
// line.
|
||||||
auto basePath = csync_rename_adjust_full_path_source(ctx, cur->path);
|
auto basePath = csync_rename_adjust_full_path_source(ctx, cur->path);
|
||||||
if (basePath != cur->path) {
|
if (basePath != cur->path) {
|
||||||
qCDebug(lcReconcile, "Trying rename origin by csync_rename mapping %s",
|
qCInfo(lcReconcile, "Trying rename origin by csync_rename mapping %s",
|
||||||
basePath.constData());
|
basePath.constData());
|
||||||
// We go through getFileRecordsByFileId to ensure the basePath
|
// We go through getFileRecordsByFileId to ensure the basePath
|
||||||
// computed in this way also has the expected fileid.
|
// computed in this way also has the expected fileid.
|
||||||
@@ -249,7 +253,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
|
// Also feed all the other files with the same fileid if necessary
|
||||||
if (!processedRename) {
|
if (!processedRename) {
|
||||||
qCDebug(lcReconcile, "Finding rename origin through file ID %s",
|
qCInfo(lcReconcile, "Finding rename origin through file ID %s",
|
||||||
cur->file_id.constData());
|
cur->file_id.constData());
|
||||||
ctx->statedb->getFileRecordsByFileId(cur->file_id,
|
ctx->statedb->getFileRecordsByFileId(cur->file_id,
|
||||||
[&](const OCC::SyncJournalFileRecord &base) { renameCandidateProcessing(base._path); });
|
[&](const OCC::SyncJournalFileRecord &base) { renameCandidateProcessing(base._path); });
|
||||||
|
|||||||
@@ -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.
|
* This code should probably be in csync_exclude, but it does not have the fs parameter.
|
||||||
* Keep it here for now */
|
* Keep it here for now */
|
||||||
if (ctx->ignore_hidden_files && (fs->is_hidden)) {
|
if (ctx->ignore_hidden_files && (fs->is_hidden)) {
|
||||||
qCDebug(lcUpdate, "file excluded because it is a hidden file: %s", fs->path.constData());
|
qCInfo(lcUpdate, "file excluded because it is a hidden file: %s", fs->path.constData());
|
||||||
excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
|
excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* File is ignored because it's matched by a user- or system exclude pattern. */
|
/* File is ignored because it's matched by a user- or system exclude pattern. */
|
||||||
qCDebug(lcUpdate, "%s excluded (%d)", fs->path.constData(), excluded);
|
qCInfo(lcUpdate, "%s excluded (%d)", fs->path.constData(), excluded);
|
||||||
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
|
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
|
||||||
return 1;
|
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);
|
QTextEncoder encoder(localCodec, QTextCodec::ConvertInvalidToNull);
|
||||||
if (encoder.fromUnicode(QString::fromUtf8(fs->path)).contains('\0')) {
|
if (encoder.fromUnicode(QString::fromUtf8(fs->path)).contains('\0')) {
|
||||||
qCDebug(lcUpdate, "cannot encode %s to local encoding %d",
|
qCInfo(lcUpdate, "cannot encode %s to local encoding %d",
|
||||||
fs->path.constData(), localCodec->mibEnum());
|
fs->path.constData(), localCodec->mibEnum());
|
||||||
excluded = CSYNC_FILE_EXCLUDE_CANNOT_ENCODE;
|
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->type == CSYNC_FTW_TYPE_FILE ) {
|
||||||
if (fs->modtime == 0) {
|
if (fs->modtime == 0) {
|
||||||
qCDebug(lcUpdate, "file: %s - mtime is zero!", fs->path.constData());
|
qCInfo(lcUpdate, "file: %s - mtime is zero!", fs->path.constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,10 +195,12 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||||||
/* we have an update! */
|
/* we have an update! */
|
||||||
qCInfo(lcUpdate, "Database entry found, compare: %" PRId64 " <-> %" PRId64
|
qCInfo(lcUpdate, "Database entry found, compare: %" PRId64 " <-> %" PRId64
|
||||||
", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
|
", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
|
||||||
", size: %" PRId64 " <-> %" PRId64 ", perms: %x <-> %x, ignore: %d",
|
", size: %" PRId64 " <-> %" PRId64 ", perms: %x <-> %x"
|
||||||
|
", checksum: %s <-> %s , ignore: %d",
|
||||||
((int64_t) fs->modtime), ((int64_t) base._modtime),
|
((int64_t) fs->modtime), ((int64_t) base._modtime),
|
||||||
fs->etag.constData(), base._etag.constData(), (uint64_t) fs->inode, (uint64_t) base._inode,
|
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), base._serverHasIgnoredFiles );
|
(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);
|
||||||
if (ctx->current == REMOTE_REPLICA && fs->etag != base._etag) {
|
if (ctx->current == REMOTE_REPLICA && fs->etag != base._etag) {
|
||||||
fs->instruction = CSYNC_INSTRUCTION_EVAL;
|
fs->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||||
|
|
||||||
@@ -228,7 +230,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||||||
checksumIdentical = fs->checksumHeader == base._checksumHeader;
|
checksumIdentical = fs->checksumHeader == base._checksumHeader;
|
||||||
}
|
}
|
||||||
if (checksumIdentical) {
|
if (checksumIdentical) {
|
||||||
qCDebug(lcUpdate, "NOTE: Checksums are identical, file did not actually change: %s", fs->path.constData());
|
qCInfo(lcUpdate, "NOTE: Checksums are identical, file did not actually change: %s", fs->path.constData());
|
||||||
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -252,7 +254,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
|
* The metadata comparison ensure that we fetch all the file id or permission when
|
||||||
* upgrading owncloud
|
* upgrading owncloud
|
||||||
*/
|
*/
|
||||||
qCDebug(lcUpdate, "Reading from database: %s", fs->path.constData());
|
qCInfo(lcUpdate, "Reading from database: %s", fs->path.constData());
|
||||||
ctx->remote.read_from_db = true;
|
ctx->remote.read_from_db = true;
|
||||||
}
|
}
|
||||||
/* If it was remembered in the db that the remote dir has ignored files, store
|
/* If it was remembered in the db that the remote dir has ignored files, store
|
||||||
@@ -263,7 +265,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||||||
}
|
}
|
||||||
if (metadata_differ) {
|
if (metadata_differ) {
|
||||||
/* file id or permissions has changed. Which means we need to update them in the DB. */
|
/* file id or permissions has changed. Which means we need to update them in the DB. */
|
||||||
qCDebug(lcUpdate, "Need to update metadata for: %s", fs->path.constData());
|
qCInfo(lcUpdate, "Need to update metadata for: %s", fs->path.constData());
|
||||||
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||||
} else {
|
} else {
|
||||||
fs->instruction = CSYNC_INSTRUCTION_NONE;
|
fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||||
@@ -271,7 +273,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||||||
} else {
|
} else {
|
||||||
/* check if it's a file and has been renamed */
|
/* check if it's a file and has been renamed */
|
||||||
if (ctx->current == LOCAL_REPLICA) {
|
if (ctx->current == LOCAL_REPLICA) {
|
||||||
qCDebug(lcUpdate, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
qCInfo(lcUpdate, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||||
|
|
||||||
OCC::SyncJournalFileRecord base;
|
OCC::SyncJournalFileRecord base;
|
||||||
if(!ctx->statedb->getFileRecordByInode(fs->inode, &base)) {
|
if(!ctx->statedb->getFileRecordByInode(fs->inode, &base)) {
|
||||||
@@ -298,13 +300,13 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||||||
_rel_to_abs(ctx, fs->path), base._checksumHeader,
|
_rel_to_abs(ctx, fs->path), base._checksumHeader,
|
||||||
ctx->callbacks.checksum_userdata);
|
ctx->callbacks.checksum_userdata);
|
||||||
if (!fs->checksumHeader.isEmpty()) {
|
if (!fs->checksumHeader.isEmpty()) {
|
||||||
qCDebug(lcUpdate, "checking checksum of potential rename %s %s <-> %s", fs->path.constData(), fs->checksumHeader.constData(), base._checksumHeader.constData());
|
qCInfo(lcUpdate, "checking checksum of potential rename %s %s <-> %s", fs->path.constData(), fs->checksumHeader.constData(), base._checksumHeader.constData());
|
||||||
isRename = fs->checksumHeader == base._checksumHeader;
|
isRename = fs->checksumHeader == base._checksumHeader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRename) {
|
if (isRename) {
|
||||||
qCDebug(lcUpdate, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
qCInfo(lcUpdate, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||||
/* inode found so the file has been renamed */
|
/* inode found so the file has been renamed */
|
||||||
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||||
if (fs->type == CSYNC_FTW_TYPE_DIR) {
|
if (fs->type == CSYNC_FTW_TYPE_DIR) {
|
||||||
@@ -314,6 +316,8 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
qCInfo(lcUpdate, "Checking for rename based on fileid %s", fs->file_id.constData());
|
||||||
|
|
||||||
/* Remote Replica Rename check */
|
/* Remote Replica Rename check */
|
||||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||||
|
|
||||||
@@ -350,7 +354,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||||||
csync_rename_record(ctx, base._path, fs->path);
|
csync_rename_record(ctx, base._path, fs->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(lcUpdate, "remote rename detected based on fileid %s --> %s", base._path.constData(), fs->path.constData());
|
qCInfo(lcUpdate, "remote rename detected based on fileid %s --> %s", base._path.constData(), fs->path.constData());
|
||||||
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||||
done = true;
|
done = true;
|
||||||
};
|
};
|
||||||
@@ -458,11 +462,11 @@ int csync_walker(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> fs) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CSYNC_FTW_TYPE_SLINK:
|
case CSYNC_FTW_TYPE_SLINK:
|
||||||
qCDebug(lcUpdate, "symlink: %s - not supported", fs->path.constData());
|
qCInfo(lcUpdate, "symlink: %s - not supported", fs->path.constData());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
qCInfo(lcUpdate, "item: %s - item type %d not iterated", fs->path.constData(), fs->type);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = _csync_detect_update(ctx, std::move(fs));
|
rc = _csync_detect_update(ctx, std::move(fs));
|
||||||
@@ -483,7 +487,7 @@ static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
|||||||
* their correct etags again and we don't run into this case.
|
* their correct etags again and we don't run into this case.
|
||||||
*/
|
*/
|
||||||
if( rec._etag == "_invalid_") {
|
if( rec._etag == "_invalid_") {
|
||||||
qCDebug(lcUpdate, "%s selective sync excluded", rec._path.constData());
|
qCInfo(lcUpdate, "%s selective sync excluded", rec._path.constData());
|
||||||
skipbase = rec._path;
|
skipbase = rec._path;
|
||||||
skipbase += '/';
|
skipbase += '/';
|
||||||
return;
|
return;
|
||||||
@@ -720,7 +724,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
csync_vio_closedir(ctx, dh);
|
csync_vio_closedir(ctx, dh);
|
||||||
qCDebug(lcUpdate, " <= Closing walk for %s with read_from_db %d", uri, read_from_db);
|
qCInfo(lcUpdate, " <= Closing walk for %s with read_from_db %d", uri, read_from_db);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ IF( APPLE )
|
|||||||
if(SPARKLE_FOUND)
|
if(SPARKLE_FOUND)
|
||||||
# Define this, we need to check in updater.cpp
|
# Define this, we need to check in updater.cpp
|
||||||
add_definitions( -DHAVE_SPARKLE )
|
add_definitions( -DHAVE_SPARKLE )
|
||||||
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm)
|
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm updater/sparkleupdater.h)
|
||||||
endif()
|
endif()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|||||||
@@ -312,10 +312,10 @@ void AccountState::slotInvalidCredentials()
|
|||||||
|
|
||||||
if (account()->credentials()->ready()) {
|
if (account()->credentials()->ready()) {
|
||||||
account()->credentials()->invalidateToken();
|
account()->credentials()->invalidateToken();
|
||||||
if (auto creds = qobject_cast<HttpCredentials *>(account()->credentials())) {
|
}
|
||||||
if (creds->refreshAccessToken())
|
if (auto creds = qobject_cast<HttpCredentials *>(account()->credentials())) {
|
||||||
return;
|
if (creds->refreshAccessToken())
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
account()->credentials()->askFromUser();
|
account()->credentials()->askFromUser();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,10 @@ void Folder::checkLocalPath()
|
|||||||
{
|
{
|
||||||
const QFileInfo fi(_definition.localPath);
|
const QFileInfo fi(_definition.localPath);
|
||||||
_canonicalLocalPath = fi.canonicalFilePath();
|
_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()) {
|
if (_canonicalLocalPath.isEmpty()) {
|
||||||
qCWarning(lcFolder) << "Broken symlink:" << _definition.localPath;
|
qCWarning(lcFolder) << "Broken symlink:" << _definition.localPath;
|
||||||
_canonicalLocalPath = _definition.localPath;
|
_canonicalLocalPath = _definition.localPath;
|
||||||
|
|||||||
@@ -25,6 +25,10 @@
|
|||||||
|
|
||||||
#include "updater/updater.h"
|
#include "updater/updater.h"
|
||||||
#include "updater/ocupdater.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 "ignorelisteditor.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -32,6 +36,7 @@
|
|||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QScopedValueRollback>
|
#include <QScopedValueRollback>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
@@ -88,6 +93,18 @@ GeneralSettings::GeneralSettings(QWidget *parent)
|
|||||||
|
|
||||||
// accountAdded means the wizard was finished and the wizard might change some options.
|
// accountAdded means the wizard was finished and the wizard might change some options.
|
||||||
connect(AccountManager::instance(), &AccountManager::accountAdded, this, &GeneralSettings::loadMiscSettings);
|
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()
|
GeneralSettings::~GeneralSettings()
|
||||||
@@ -117,22 +134,79 @@ void GeneralSettings::loadMiscSettings()
|
|||||||
|
|
||||||
void GeneralSettings::slotUpdateInfo()
|
void GeneralSettings::slotUpdateInfo()
|
||||||
{
|
{
|
||||||
// Note: the sparkle-updater is not an OCUpdater
|
if (ConfigFile().skipUpdateCheck() || !Updater::instance()) {
|
||||||
OCUpdater *updater = qobject_cast<OCUpdater *>(Updater::instance());
|
// updater disabled on compile
|
||||||
if (ConfigFile().skipUpdateCheck()) {
|
_ui->updatesGroupBox->setVisible(false);
|
||||||
updater = 0; // don't show update info if updates are disabled
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updater) {
|
// Note: the sparkle-updater is not an OCUpdater
|
||||||
connect(updater, &OCUpdater::downloadStateChanged, this, &GeneralSettings::slotUpdateInfo, Qt::UniqueConnection);
|
OCUpdater *ocupdater = qobject_cast<OCUpdater *>(Updater::instance());
|
||||||
connect(_ui->restartButton, &QAbstractButton::clicked, updater, &OCUpdater::slotStartInstaller, Qt::UniqueConnection);
|
if (ocupdater) {
|
||||||
|
connect(ocupdater, &OCUpdater::downloadStateChanged, this, &GeneralSettings::slotUpdateInfo, Qt::UniqueConnection);
|
||||||
|
connect(_ui->restartButton, &QAbstractButton::clicked, ocupdater, &OCUpdater::slotStartInstaller, Qt::UniqueConnection);
|
||||||
connect(_ui->restartButton, &QAbstractButton::clicked, qApp, &QApplication::quit, Qt::UniqueConnection);
|
connect(_ui->restartButton, &QAbstractButton::clicked, qApp, &QApplication::quit, Qt::UniqueConnection);
|
||||||
_ui->updateStateLabel->setText(updater->statusString());
|
|
||||||
_ui->restartButton->setVisible(updater->downloadState() == OCUpdater::DownloadComplete);
|
_ui->updateStateLabel->setText(ocupdater->statusString());
|
||||||
} else {
|
_ui->restartButton->setVisible(ocupdater->downloadState() == OCUpdater::DownloadComplete);
|
||||||
// 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()
|
void GeneralSettings::saveMiscSettings()
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ private slots:
|
|||||||
void slotToggleLaunchOnStartup(bool);
|
void slotToggleLaunchOnStartup(bool);
|
||||||
void slotToggleOptionalDesktopNotifications(bool);
|
void slotToggleOptionalDesktopNotifications(bool);
|
||||||
void slotUpdateInfo();
|
void slotUpdateInfo();
|
||||||
|
void slotUpdateChannelChanged(int index);
|
||||||
void slotIgnoreFilesEditor();
|
void slotIgnoreFilesEditor();
|
||||||
void loadMiscSettings();
|
void loadMiscSettings();
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>785</width>
|
<width>785</width>
|
||||||
<height>523</height>
|
<height>533</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -74,48 +74,88 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Updates</string>
|
<string>Updates</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="updateStateLabel">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="text">
|
<item>
|
||||||
<string/>
|
<widget class="QLabel" name="updateChannelLabel">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
<property name="wordWrap">
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
<bool>true</bool>
|
<horstretch>0</horstretch>
|
||||||
</property>
|
<verstretch>0</verstretch>
|
||||||
<property name="openExternalLinks">
|
</sizepolicy>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>&Channel</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="buddy">
|
||||||
<widget class="QPushButton" name="restartButton">
|
<cstring>updateChannel</cstring>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
</widget>
|
||||||
<horstretch>0</horstretch>
|
</item>
|
||||||
<verstretch>0</verstretch>
|
<item>
|
||||||
</sizepolicy>
|
<widget class="QComboBox" name="updateChannel">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
<property name="text">
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
<string>&Restart && Update</string>
|
<horstretch>0</horstretch>
|
||||||
</property>
|
<verstretch>0</verstretch>
|
||||||
</widget>
|
</sizepolicy>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<property name="text">
|
||||||
<property name="orientation">
|
<string>stable</string>
|
||||||
<enum>Qt::Horizontal</enum>
|
</property>
|
||||||
</property>
|
</item>
|
||||||
<property name="sizeType">
|
<item>
|
||||||
<enum>QSizePolicy::Preferred</enum>
|
<property name="text">
|
||||||
</property>
|
<string>beta</string>
|
||||||
<property name="sizeHint" stdset="0">
|
</property>
|
||||||
<size>
|
</item>
|
||||||
<width>40</width>
|
</widget>
|
||||||
<height>20</height>
|
</item>
|
||||||
</size>
|
<item>
|
||||||
</property>
|
<widget class="QLabel" name="updateStateLabel">
|
||||||
</spacer>
|
<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>&Restart && 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>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -247,7 +287,10 @@
|
|||||||
<tabstop>ignoredFilesButton</tabstop>
|
<tabstop>ignoredFilesButton</tabstop>
|
||||||
<tabstop>newFolderLimitCheckBox</tabstop>
|
<tabstop>newFolderLimitCheckBox</tabstop>
|
||||||
<tabstop>newFolderLimitSpinBox</tabstop>
|
<tabstop>newFolderLimitSpinBox</tabstop>
|
||||||
|
<tabstop>newExternalStorage</tabstop>
|
||||||
|
<tabstop>showInExplorerNavigationPaneCheckBox</tabstop>
|
||||||
<tabstop>crashreporterCheckBox</tabstop>
|
<tabstop>crashreporterCheckBox</tabstop>
|
||||||
|
<tabstop>updateChannel</tabstop>
|
||||||
<tabstop>restartButton</tabstop>
|
<tabstop>restartButton</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|||||||
@@ -50,18 +50,13 @@ const char propertyAccountC[] = "oc_account";
|
|||||||
ownCloudGui::ownCloudGui(Application *parent)
|
ownCloudGui::ownCloudGui(Application *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, _tray(0)
|
, _tray(0)
|
||||||
,
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
_settingsDialog(new SettingsDialogMac(this))
|
, _settingsDialog(new SettingsDialogMac(this))
|
||||||
,
|
|
||||||
#else
|
#else
|
||||||
_settingsDialog(new SettingsDialog(this))
|
, _settingsDialog(new SettingsDialog(this))
|
||||||
,
|
|
||||||
#endif
|
#endif
|
||||||
_logBrowser(0)
|
, _logBrowser(0)
|
||||||
, _contextMenuVisibleOsx(false)
|
|
||||||
, _recentActionsMenu(0)
|
, _recentActionsMenu(0)
|
||||||
, _qdbusmenuWorkaround(false)
|
|
||||||
, _app(parent)
|
, _app(parent)
|
||||||
{
|
{
|
||||||
_tray = new Systray();
|
_tray = new Systray();
|
||||||
@@ -117,7 +112,7 @@ void ownCloudGui::slotOpenSettingsDialog()
|
|||||||
|
|
||||||
void ownCloudGui::slotTrayClicked(QSystemTrayIcon::ActivationReason reason)
|
void ownCloudGui::slotTrayClicked(QSystemTrayIcon::ActivationReason reason)
|
||||||
{
|
{
|
||||||
if (_qdbusmenuWorkaround) {
|
if (_workaroundFakeDoubleClick) {
|
||||||
static QElapsedTimer last_click;
|
static QElapsedTimer last_click;
|
||||||
if (last_click.isValid() && last_click.elapsed() < 200) {
|
if (last_click.isValid() && last_click.elapsed() < 200) {
|
||||||
return;
|
return;
|
||||||
@@ -381,17 +376,19 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
|
|||||||
|
|
||||||
void ownCloudGui::slotContextMenuAboutToShow()
|
void ownCloudGui::slotContextMenuAboutToShow()
|
||||||
{
|
{
|
||||||
// For some reason on OS X _contextMenu->isVisible returns always false
|
_contextMenuVisibleManual = true;
|
||||||
_contextMenuVisibleOsx = true;
|
|
||||||
|
|
||||||
// Update icon in sys tray, as it might change depending on the context menu state
|
// Update icon in sys tray, as it might change depending on the context menu state
|
||||||
slotComputeOverallSyncStatus();
|
slotComputeOverallSyncStatus();
|
||||||
|
|
||||||
|
if (!_workaroundNoAboutToShowUpdate) {
|
||||||
|
updateContextMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ownCloudGui::slotContextMenuAboutToHide()
|
void ownCloudGui::slotContextMenuAboutToHide()
|
||||||
{
|
{
|
||||||
// For some reason on OS X _contextMenu->isVisible returns always false
|
_contextMenuVisibleManual = false;
|
||||||
_contextMenuVisibleOsx = false;
|
|
||||||
|
|
||||||
// Update icon in sys tray, as it might change depending on the context menu state
|
// Update icon in sys tray, as it might change depending on the context menu state
|
||||||
slotComputeOverallSyncStatus();
|
slotComputeOverallSyncStatus();
|
||||||
@@ -399,11 +396,11 @@ void ownCloudGui::slotContextMenuAboutToHide()
|
|||||||
|
|
||||||
bool ownCloudGui::contextMenuVisible() const
|
bool ownCloudGui::contextMenuVisible() const
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_MAC
|
// On some platforms isVisible doesn't work and always returns false,
|
||||||
return _contextMenuVisibleOsx;
|
// elsewhere aboutToHide is unreliable.
|
||||||
#else
|
if (_workaroundManualVisibility)
|
||||||
|
return _contextMenuVisibleManual;
|
||||||
return _contextMenu->isVisible();
|
return _contextMenu->isVisible();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool minimalTrayMenu()
|
static bool minimalTrayMenu()
|
||||||
@@ -426,12 +423,36 @@ static bool updateWhileVisible()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray forceQDBusTrayWorkaround()
|
static QByteArray envForceQDBusTrayWorkaround()
|
||||||
{
|
{
|
||||||
static QByteArray var = qgetenv("OWNCLOUD_FORCE_QDBUS_TRAY_WORKAROUND");
|
static QByteArray var = qgetenv("OWNCLOUD_FORCE_QDBUS_TRAY_WORKAROUND");
|
||||||
return var;
|
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()
|
void ownCloudGui::setupContextMenu()
|
||||||
{
|
{
|
||||||
if (_contextMenu) {
|
if (_contextMenu) {
|
||||||
@@ -454,51 +475,65 @@ void ownCloudGui::setupContextMenu()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enables workarounds for bugs introduced in Qt 5.5.0
|
auto applyEnvVariable = [](bool *sw, const QByteArray &value) {
|
||||||
// In particular QTBUG-47863 #3672 (tray menu fails to update and
|
if (value == "1")
|
||||||
// becomes unresponsive) and QTBUG-48068 #3722 (click signal is
|
*sw = true;
|
||||||
// emitted several times)
|
if (value == "0")
|
||||||
// The Qt version check intentionally uses 5.0.0 (where platformMenu()
|
*sw = false;
|
||||||
// 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
|
|
||||||
#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
|
|
||||||
|
|
||||||
if (forceQDBusTrayWorkaround() == "1") {
|
// This is an old compound flag that people might still depend on
|
||||||
_qdbusmenuWorkaround = true;
|
bool qdbusmenuWorkarounds = false;
|
||||||
} else if (forceQDBusTrayWorkaround() == "0") {
|
applyEnvVariable(&qdbusmenuWorkarounds, envForceQDBusTrayWorkaround());
|
||||||
_qdbusmenuWorkaround = false;
|
if (qdbusmenuWorkarounds) {
|
||||||
|
_workaroundFakeDoubleClick = true;
|
||||||
|
_workaroundNoAboutToShowUpdate = true;
|
||||||
|
_workaroundShowAndHideTray = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
#ifdef Q_OS_MAC
|
||||||
// https://bugreports.qt.io/browse/QTBUG-54633
|
// https://bugreports.qt.io/browse/QTBUG-54633
|
||||||
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(slotContextMenuAboutToShow()));
|
_workaroundNoAboutToShowUpdate = true;
|
||||||
connect(_contextMenu.data(), SIGNAL(aboutToHide()), SLOT(slotContextMenuAboutToHide()));
|
_workaroundManualVisibility = true;
|
||||||
#else
|
|
||||||
connect(_contextMenu.data(), &QMenu::aboutToShow, this, &ownCloudGui::updateContextMenu);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#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;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
applyEnvVariable(&_workaroundNoAboutToShowUpdate, envForceWorkaroundNoAboutToShowUpdate());
|
||||||
|
applyEnvVariable(&_workaroundFakeDoubleClick, envForceWorkaroundFakeDoubleClick());
|
||||||
|
applyEnvVariable(&_workaroundShowAndHideTray, envForceWorkaroundShowAndHideTray());
|
||||||
|
applyEnvVariable(&_workaroundManualVisibility, envForceWorkaroundManualVisibility());
|
||||||
|
|
||||||
|
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()));
|
||||||
|
|
||||||
// Populate the context menu now.
|
// Populate the context menu now.
|
||||||
updateContextMenu();
|
updateContextMenu();
|
||||||
@@ -510,13 +545,21 @@ void ownCloudGui::updateContextMenu()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_qdbusmenuWorkaround) {
|
// 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) {
|
||||||
// To make tray menu updates work with these bugs (see setupContextMenu)
|
// 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
|
// we need to hide and show the tray icon. We don't want to do that
|
||||||
// while it's visible!
|
// while it's visible!
|
||||||
if (contextMenuVisible()) {
|
if (contextMenuVisible()) {
|
||||||
if (!_workaroundBatchTrayUpdate.isActive()) {
|
if (!_delayedTrayUpdateTimer.isActive()) {
|
||||||
_workaroundBatchTrayUpdate.start();
|
_delayedTrayUpdateTimer.start();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -631,35 +674,30 @@ void ownCloudGui::updateContextMenu()
|
|||||||
}
|
}
|
||||||
_contextMenu->addAction(_actionQuit);
|
_contextMenu->addAction(_actionQuit);
|
||||||
|
|
||||||
if (_qdbusmenuWorkaround) {
|
if (_workaroundShowAndHideTray) {
|
||||||
_tray->show();
|
_tray->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ownCloudGui::updateContextMenuNeeded()
|
void ownCloudGui::updateContextMenuNeeded()
|
||||||
{
|
{
|
||||||
// For the workaround case updating while visible is impossible. Instead
|
// if it's visible and we can update live: update now
|
||||||
// occasionally update the menu when it's invisible.
|
if (contextMenuVisible() && updateWhileVisible()) {
|
||||||
if (_qdbusmenuWorkaround) {
|
// Note: don't update while visible on OSX
|
||||||
if (!_workaroundBatchTrayUpdate.isActive()) {
|
// https://bugreports.qt.io/browse/QTBUG-54845
|
||||||
_workaroundBatchTrayUpdate.start();
|
updateContextMenu();
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
// if we can't lazily update: update later
|
||||||
// https://bugreports.qt.io/browse/QTBUG-54845
|
if (_workaroundNoAboutToShowUpdate) {
|
||||||
// We cannot update on demand or while visible -> update when invisible.
|
// Note: don't update immediately even in the invisible case
|
||||||
if (!contextMenuVisible()) {
|
// as that can lead to extremely frequent menu updates
|
||||||
updateContextMenu();
|
if (!_delayedTrayUpdateTimer.isActive()) {
|
||||||
|
_delayedTrayUpdateTimer.start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#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)
|
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
|
||||||
|
|||||||
@@ -119,14 +119,19 @@ private:
|
|||||||
// tray's menu
|
// tray's menu
|
||||||
QScopedPointer<QMenu> _contextMenu;
|
QScopedPointer<QMenu> _contextMenu;
|
||||||
|
|
||||||
// Manually tracking whether the context menu is visible, but only works
|
// Manually tracking whether the context menu is visible via aboutToShow
|
||||||
// on OSX because aboutToHide is not reliable everywhere.
|
// and aboutToHide. Unfortunately aboutToHide isn't reliable everywhere
|
||||||
bool _contextMenuVisibleOsx;
|
// so this only gets used with _workaroundManualVisibility (when the tray's
|
||||||
|
// isVisible() is unreliable)
|
||||||
|
bool _contextMenuVisibleManual = false;
|
||||||
|
|
||||||
QMenu *_recentActionsMenu;
|
QMenu *_recentActionsMenu;
|
||||||
QVector<QMenu *> _accountMenus;
|
QVector<QMenu *> _accountMenus;
|
||||||
bool _qdbusmenuWorkaround;
|
bool _workaroundShowAndHideTray = false;
|
||||||
QTimer _workaroundBatchTrayUpdate;
|
bool _workaroundNoAboutToShowUpdate = false;
|
||||||
|
bool _workaroundFakeDoubleClick = false;
|
||||||
|
bool _workaroundManualVisibility = false;
|
||||||
|
QTimer _delayedTrayUpdateTimer;
|
||||||
QMap<QString, QPointer<ShareDialog>> _shareDialogs;
|
QMap<QString, QPointer<ShareDialog>> _shareDialogs;
|
||||||
|
|
||||||
QAction *_actionLogin;
|
QAction *_actionLogin;
|
||||||
|
|||||||
@@ -183,6 +183,10 @@ SocketApi::SocketApi(QObject *parent)
|
|||||||
// Example for developer builds (with ad-hoc signing identity): "" "com.owncloud.desktopclient" ".socketApi"
|
// Example for developer builds (with ad-hoc signing identity): "" "com.owncloud.desktopclient" ".socketApi"
|
||||||
// Example for official signed packages: "9B5WD74GWJ." "com.owncloud.desktopclient" ".socketApi"
|
// Example for official signed packages: "9B5WD74GWJ." "com.owncloud.desktopclient" ".socketApi"
|
||||||
socketPath = SOCKETAPI_TEAM_IDENTIFIER_PREFIX APPLICATION_REV_DOMAIN ".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()) {
|
} else if (Utility::isLinux() || Utility::isBSD()) {
|
||||||
QString runtimeDir;
|
QString runtimeDir;
|
||||||
runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
||||||
@@ -220,6 +224,11 @@ SocketApi::~SocketApi()
|
|||||||
// All remaining sockets will be destroyed with _localServer, their parent
|
// All remaining sockets will be destroyed with _localServer, their parent
|
||||||
ASSERT(_listeners.isEmpty() || _listeners.first().socket->parent() == &_localServer);
|
ASSERT(_listeners.isEmpty() || _listeners.first().socket->parent() == &_localServer);
|
||||||
_listeners.clear();
|
_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()
|
void SocketApi::slotNewConnection()
|
||||||
|
|||||||
@@ -204,6 +204,10 @@ void SslButton::slotUpdateMenu()
|
|||||||
|
|
||||||
AccountPtr account = _accountState->account();
|
AccountPtr account = _accountState->account();
|
||||||
|
|
||||||
|
if (account->isHttp2Supported()) {
|
||||||
|
_menu->addAction("HTTP/2")->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (account->url().scheme() == QLatin1String("https")) {
|
if (account->url().scheme() == QLatin1String("https")) {
|
||||||
QString sslVersion = account->_sessionCipher.protocolString()
|
QString sslVersion = account->_sessionCipher.protocolString()
|
||||||
+ ", " + account->_sessionCipher.authenticationMethod()
|
+ ", " + account->_sessionCipher.authenticationMethod()
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ OCUpdater::OCUpdater(const QUrl &url)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OCUpdater::setUpdateUrl(const QUrl &url)
|
||||||
|
{
|
||||||
|
_updateUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
bool OCUpdater::performUpdate()
|
bool OCUpdater::performUpdate()
|
||||||
{
|
{
|
||||||
ConfigFile cfg;
|
ConfigFile cfg;
|
||||||
@@ -179,6 +184,81 @@ 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()
|
void OCUpdater::slotStartInstaller()
|
||||||
{
|
{
|
||||||
ConfigFile cfg;
|
ConfigFile cfg;
|
||||||
@@ -187,8 +267,30 @@ void OCUpdater::slotStartInstaller()
|
|||||||
settings.setValue(autoUpdateAttemptedC, true);
|
settings.setValue(autoUpdateAttemptedC, true);
|
||||||
settings.sync();
|
settings.sync();
|
||||||
qCInfo(lcUpdater) << "Running updater" << updateFile;
|
qCInfo(lcUpdater) << "Running updater" << updateFile;
|
||||||
QProcess::startDetached(updateFile, QStringList() << "/S"
|
|
||||||
<< "/launch");
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto 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});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OCUpdater::checkForUpdate()
|
void OCUpdater::checkForUpdate()
|
||||||
@@ -298,7 +400,7 @@ void NSISUpdater::versionInfoArrived(const UpdateInfo &info)
|
|||||||
showDialog(info);
|
showDialog(info);
|
||||||
}
|
}
|
||||||
if (!url.isEmpty()) {
|
if (!url.isEmpty()) {
|
||||||
_targetFile = cfg.configPath() + url.mid(url.lastIndexOf('/'));
|
_targetFile = cfg.configPath() + url.mid(url.lastIndexOf('/')+1);
|
||||||
if (QFile(_targetFile).exists()) {
|
if (QFile(_targetFile).exists()) {
|
||||||
setDownloadState(DownloadComplete);
|
setDownloadState(DownloadComplete);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ public:
|
|||||||
UpdateOnlyAvailableThroughSystem };
|
UpdateOnlyAvailableThroughSystem };
|
||||||
explicit OCUpdater(const QUrl &url);
|
explicit OCUpdater(const QUrl &url);
|
||||||
|
|
||||||
|
void setUpdateUrl(const QUrl &url);
|
||||||
|
|
||||||
bool performUpdate();
|
bool performUpdate();
|
||||||
|
|
||||||
void checkForUpdate() Q_DECL_OVERRIDE;
|
void checkForUpdate() Q_DECL_OVERRIDE;
|
||||||
|
|||||||
@@ -23,15 +23,20 @@ namespace OCC {
|
|||||||
|
|
||||||
class SparkleUpdater : public Updater
|
class SparkleUpdater : public Updater
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SparkleUpdater(const QString &appCastUrl);
|
SparkleUpdater(const QUrl &appCastUrl);
|
||||||
~SparkleUpdater();
|
~SparkleUpdater();
|
||||||
|
|
||||||
|
void setUpdateUrl(const QUrl &url);
|
||||||
|
|
||||||
// unused in this updater
|
// unused in this updater
|
||||||
void checkForUpdate() Q_DECL_OVERRIDE;
|
void checkForUpdate() Q_DECL_OVERRIDE;
|
||||||
void backgroundCheckForUpdate() Q_DECL_OVERRIDE;
|
void backgroundCheckForUpdate() Q_DECL_OVERRIDE;
|
||||||
bool handleStartup() Q_DECL_OVERRIDE { return false; }
|
bool handleStartup() Q_DECL_OVERRIDE { return false; }
|
||||||
|
|
||||||
|
QString statusString();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
Private *d;
|
Private *d;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class SparkleUpdater::Private
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Delete ~/Library//Preferences/com.owncloud.desktopclient.plist to re-test
|
// Delete ~/Library//Preferences/com.owncloud.desktopclient.plist to re-test
|
||||||
SparkleUpdater::SparkleUpdater(const QString& appCastUrl)
|
SparkleUpdater::SparkleUpdater(const QUrl& appCastUrl)
|
||||||
: Updater()
|
: Updater()
|
||||||
{
|
{
|
||||||
d = new Private;
|
d = new Private;
|
||||||
@@ -89,9 +89,7 @@ SparkleUpdater::SparkleUpdater(const QString& appCastUrl)
|
|||||||
[d->updater resetUpdateCycle];
|
[d->updater resetUpdateCycle];
|
||||||
[d->updater retain];
|
[d->updater retain];
|
||||||
|
|
||||||
NSURL* url = [NSURL URLWithString:
|
setUpdateUrl(appCastUrl);
|
||||||
[NSString stringWithUTF8String: appCastUrl.toUtf8().data()]];
|
|
||||||
[d->updater setFeedURL: url];
|
|
||||||
|
|
||||||
// Sparkle 1.8 required
|
// Sparkle 1.8 required
|
||||||
NSString *userAgent = [NSString stringWithUTF8String: Utility::userAgentString().data()];
|
NSString *userAgent = [NSString stringWithUTF8String: Utility::userAgentString().data()];
|
||||||
@@ -104,7 +102,14 @@ SparkleUpdater::~SparkleUpdater()
|
|||||||
delete d;
|
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()
|
bool autoUpdaterAllowed()
|
||||||
{
|
{
|
||||||
// See https://github.com/owncloud/client/issues/2931
|
// See https://github.com/owncloud/client/issues/2931
|
||||||
@@ -133,4 +138,10 @@ void SparkleUpdater::backgroundCheckForUpdate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SparkleUpdater::statusString()
|
||||||
|
{
|
||||||
|
// FIXME Show the real state depending on the callbacks
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace OCC
|
} // namespace OCC
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "common/utility.h"
|
#include "common/utility.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "configfile.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@@ -39,6 +40,29 @@ Updater *Updater::instance()
|
|||||||
return _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 Updater::addQueryParams(const QUrl &url)
|
||||||
{
|
{
|
||||||
QUrl paramUrl = url;
|
QUrl paramUrl = url;
|
||||||
@@ -64,14 +88,10 @@ QUrl Updater::addQueryParams(const QUrl &url)
|
|||||||
|
|
||||||
QString suffix = QString::fromLatin1(MIRALL_STRINGIFY(MIRALL_VERSION_SUFFIX));
|
QString suffix = QString::fromLatin1(MIRALL_STRINGIFY(MIRALL_VERSION_SUFFIX));
|
||||||
paramUrl.addQueryItem(QLatin1String("versionsuffix"), suffix);
|
paramUrl.addQueryItem(QLatin1String("versionsuffix"), suffix);
|
||||||
if (suffix.startsWith("daily")
|
|
||||||
|| suffix.startsWith("nightly")
|
auto channel = ConfigFile().updateChannel();
|
||||||
|| suffix.startsWith("alpha")
|
if (channel != "stable") {
|
||||||
|| suffix.startsWith("rc")
|
paramUrl.addQueryItem(QLatin1String("channel"), channel);
|
||||||
|| 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;
|
return paramUrl;
|
||||||
@@ -98,23 +118,18 @@ QString Updater::getSystemInfo()
|
|||||||
// To test, cmake with -DAPPLICATION_UPDATE_URL="http://127.0.0.1:8080/test.rss"
|
// To test, cmake with -DAPPLICATION_UPDATE_URL="http://127.0.0.1:8080/test.rss"
|
||||||
Updater *Updater::create()
|
Updater *Updater::create()
|
||||||
{
|
{
|
||||||
QUrl updateBaseUrl(QString::fromLocal8Bit(qgetenv("OCC_UPDATE_URL")));
|
auto url = updateUrl();
|
||||||
if (updateBaseUrl.isEmpty()) {
|
if (url.isEmpty()) {
|
||||||
updateBaseUrl = QUrl(QLatin1String(APPLICATION_UPDATE_URL));
|
|
||||||
}
|
|
||||||
if (!updateBaseUrl.isValid() || updateBaseUrl.host() == ".") {
|
|
||||||
qCWarning(lcUpdater) << "Not a valid updater URL, will not do update check";
|
qCWarning(lcUpdater) << "Not a valid updater URL, will not do update check";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
updateBaseUrl = addQueryParams(updateBaseUrl);
|
|
||||||
#if defined(Q_OS_MAC) && defined(HAVE_SPARKLE)
|
#if defined(Q_OS_MAC) && defined(HAVE_SPARKLE)
|
||||||
updateBaseUrl.addQueryItem(QLatin1String("sparkle"), QLatin1String("true"));
|
return new SparkleUpdater(url);
|
||||||
return new SparkleUpdater(updateBaseUrl.toString());
|
|
||||||
#elif defined(Q_OS_WIN32)
|
#elif defined(Q_OS_WIN32)
|
||||||
// the best we can do is notify about updates
|
// the best we can do is notify about updates
|
||||||
return new NSISUpdater(updateBaseUrl);
|
return new NSISUpdater(url);
|
||||||
#else
|
#else
|
||||||
return new PassiveUpdateNotifier(QUrl(updateBaseUrl));
|
return new PassiveUpdateNotifier(url);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static Updater *instance();
|
static Updater *instance();
|
||||||
|
static QUrl updateUrl();
|
||||||
|
|
||||||
virtual void checkForUpdate() = 0;
|
virtual void checkForUpdate() = 0;
|
||||||
virtual void backgroundCheckForUpdate() = 0;
|
virtual void backgroundCheckForUpdate() = 0;
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ public:
|
|||||||
/** Detects a specific bug in older server versions */
|
/** Detects a specific bug in older server versions */
|
||||||
bool rootEtagChangesNotOnlySubFolderEtags();
|
bool rootEtagChangesNotOnlySubFolderEtags();
|
||||||
|
|
||||||
/** True when the server supports HTTP2 */
|
/** True when the server connection is using HTTP2 */
|
||||||
bool isHttp2Supported() { return _http2Supported; }
|
bool isHttp2Supported() { return _http2Supported; }
|
||||||
void setHttp2Supported(bool value) { _http2Supported = value; }
|
void setHttp2Supported(bool value) { _http2Supported = value; }
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "common/utility.h"
|
#include "common/utility.h"
|
||||||
#include "common/asserts.h"
|
#include "common/asserts.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "creds/abstractcredentials.h"
|
#include "creds/abstractcredentials.h"
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ static const char crashReporterC[] = "crashReporter";
|
|||||||
static const char optionalDesktopNoficationsC[] = "optionalDesktopNotifications";
|
static const char optionalDesktopNoficationsC[] = "optionalDesktopNotifications";
|
||||||
static const char skipUpdateCheckC[] = "skipUpdateCheck";
|
static const char skipUpdateCheckC[] = "skipUpdateCheck";
|
||||||
static const char updateCheckIntervalC[] = "updateCheckInterval";
|
static const char updateCheckIntervalC[] = "updateCheckInterval";
|
||||||
|
static const char updateChannelC[] = "updateChannel";
|
||||||
static const char geometryC[] = "geometry";
|
static const char geometryC[] = "geometry";
|
||||||
static const char timeoutC[] = "timeout";
|
static const char timeoutC[] = "timeout";
|
||||||
static const char chunkSizeC[] = "chunkSize";
|
static const char chunkSizeC[] = "chunkSize";
|
||||||
@@ -468,6 +470,28 @@ void ConfigFile::setSkipUpdateCheck(bool skip, const QString &connection)
|
|||||||
settings.sync();
|
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
|
int ConfigFile::maxLogLines() const
|
||||||
{
|
{
|
||||||
QSettings settings(configFile(), QSettings::IniFormat);
|
QSettings settings(configFile(), QSettings::IniFormat);
|
||||||
|
|||||||
@@ -131,6 +131,9 @@ public:
|
|||||||
bool skipUpdateCheck(const QString &connection = QString()) const;
|
bool skipUpdateCheck(const QString &connection = QString()) const;
|
||||||
void setSkipUpdateCheck(bool, const QString &);
|
void setSkipUpdateCheck(bool, const QString &);
|
||||||
|
|
||||||
|
QString updateChannel() const;
|
||||||
|
void setUpdateChannel(const QString &channel);
|
||||||
|
|
||||||
void saveGeometryHeader(QHeaderView *header);
|
void saveGeometryHeader(QHeaderView *header);
|
||||||
void restoreGeometryHeader(QHeaderView *header);
|
void restoreGeometryHeader(QHeaderView *header);
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ HttpCredentials::HttpCredentials(const QString &user, const QString &password, c
|
|||||||
, _clientSslKey(key)
|
, _clientSslKey(key)
|
||||||
, _clientSslCertificate(certificate)
|
, _clientSslCertificate(certificate)
|
||||||
, _keychainMigration(false)
|
, _keychainMigration(false)
|
||||||
|
, _retryOnKeyChainError(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +220,21 @@ void HttpCredentials::deleteOldKeychainEntries()
|
|||||||
|
|
||||||
void HttpCredentials::slotReadClientCertPEMJobDone(QKeychain::Job *incoming)
|
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
|
// Store PEM in memory
|
||||||
ReadPasswordJob *readJob = static_cast<ReadPasswordJob *>(incoming);
|
ReadPasswordJob *readJob = static_cast<ReadPasswordJob *>(incoming);
|
||||||
if (readJob->error() == NoError && readJob->binaryData().length() > 0) {
|
if (readJob->error() == NoError && readJob->binaryData().length() > 0) {
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ protected:
|
|||||||
QSslKey _clientSslKey;
|
QSslKey _clientSslKey;
|
||||||
QSslCertificate _clientSslCertificate;
|
QSslCertificate _clientSslCertificate;
|
||||||
bool _keychainMigration;
|
bool _keychainMigration;
|
||||||
|
bool _retryOnKeyChainError = true; // true if we haven't done yet any reading from keychain
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -579,8 +579,7 @@ bool OwncloudPropagator::localFileNameClash(const QString &relFile)
|
|||||||
re = false;
|
re = false;
|
||||||
qCWarning(lcPropagator) << "No valid fileinfo";
|
qCWarning(lcPropagator) << "No valid fileinfo";
|
||||||
} else {
|
} else {
|
||||||
// Need to normalize to composited form because of
|
// Need to normalize to composited form because of QTBUG-39622/QTBUG-55896
|
||||||
// https://bugreports.qt-project.org/browse/QTBUG-39622
|
|
||||||
const QString cName = fileInfo.canonicalFilePath().normalized(QString::NormalizationForm_C);
|
const QString cName = fileInfo.canonicalFilePath().normalized(QString::NormalizationForm_C);
|
||||||
bool equal = (file == cName);
|
bool equal = (file == cName);
|
||||||
re = (!equal && !cName.endsWith(relFile, Qt::CaseSensitive));
|
re = (!equal && !cName.endsWith(relFile, Qt::CaseSensitive));
|
||||||
@@ -821,10 +820,13 @@ void PropagatorCompositeJob::slotSubJobFinished(SyncFileItem::Status status)
|
|||||||
ASSERT(i >= 0);
|
ASSERT(i >= 0);
|
||||||
_runningJobs.remove(i);
|
_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
|
if (status == SyncFileItem::FatalError
|
||||||
|| status == SyncFileItem::NormalError
|
|| status == SyncFileItem::NormalError
|
||||||
|| status == SyncFileItem::SoftError
|
|| status == SyncFileItem::SoftError
|
||||||
|| status == SyncFileItem::DetailError) {
|
|| status == SyncFileItem::DetailError
|
||||||
|
|| status == SyncFileItem::BlacklistedError) {
|
||||||
_hasError = status;
|
_hasError = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -553,6 +553,16 @@ void PropagateUploadFileCommon::commonErrorHandling(AbstractNetworkJob *job)
|
|||||||
abortWithError(status, errorString);
|
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)
|
void PropagateUploadFileCommon::slotJobDestroyed(QObject *job)
|
||||||
{
|
{
|
||||||
_jobs.erase(std::remove(_jobs.begin(), _jobs.end(), job), _jobs.end());
|
_jobs.erase(std::remove(_jobs.begin(), _jobs.end(), job), _jobs.end());
|
||||||
|
|||||||
@@ -281,6 +281,17 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void commonErrorHandling(AbstractNetworkJob *job);
|
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
|
// Bases headers that need to be sent with every chunk
|
||||||
QMap<QByteArray, QByteArray> headers();
|
QMap<QByteArray, QByteArray> headers();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -295,6 +295,7 @@ void PropagateUploadFileNG::startNextChunk()
|
|||||||
connect(job, &MoveJob::finishedSignal, this, &PropagateUploadFileNG::slotMoveJobFinished);
|
connect(job, &MoveJob::finishedSignal, this, &PropagateUploadFileNG::slotMoveJobFinished);
|
||||||
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
|
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
|
||||||
propagator()->_activeJobList.append(this);
|
propagator()->_activeJobList.append(this);
|
||||||
|
adjustLastJobTimeout(job, fileSize);
|
||||||
job->start();
|
job->start();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ void PropagateUploadFileV1::startNextChunk()
|
|||||||
connect(job, &PUTFileJob::uploadProgress, this, &PropagateUploadFileV1::slotUploadProgress);
|
connect(job, &PUTFileJob::uploadProgress, this, &PropagateUploadFileV1::slotUploadProgress);
|
||||||
connect(job, &PUTFileJob::uploadProgress, device, &UploadDevice::slotJobUploadProgress);
|
connect(job, &PUTFileJob::uploadProgress, device, &UploadDevice::slotJobUploadProgress);
|
||||||
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
|
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
|
||||||
|
if (isFinalChunk)
|
||||||
|
adjustLastJobTimeout(job, fileSize);
|
||||||
job->start();
|
job->start();
|
||||||
propagator()->_activeJobList.append(this);
|
propagator()->_activeJobList.append(this);
|
||||||
_currentChunk++;
|
_currentChunk++;
|
||||||
@@ -301,6 +303,7 @@ void PropagateUploadFileV1::slotPutFinished()
|
|||||||
qCWarning(lcPropagateUpload) << "Server does not support X-OC-MTime" << job->reply()->rawHeader("X-OC-MTime");
|
qCWarning(lcPropagateUpload) << "Server does not support X-OC-MTime" << job->reply()->rawHeader("X-OC-MTime");
|
||||||
// Well, the mtime was not set
|
// Well, the mtime was not set
|
||||||
done(SyncFileItem::SoftError, "Server does not support X-OC-MTime");
|
done(SyncFileItem::SoftError, "Server does not support X-OC-MTime");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_TESTING
|
#ifdef WITH_TESTING
|
||||||
|
|||||||
@@ -82,10 +82,9 @@ public:
|
|||||||
/** For files whose errors were blacklisted
|
/** For files whose errors were blacklisted
|
||||||
*
|
*
|
||||||
* If an file is blacklisted due to an error it isn't even reattempted. These
|
* If an file is blacklisted due to an error it isn't even reattempted. These
|
||||||
* errors should appear in the issues tab, but not on the account settings and
|
* errors should appear in the issues tab but should be silent otherwise.
|
||||||
* should not cause the sync run to fail.
|
|
||||||
*
|
*
|
||||||
* A DetailError that doesn't cause sync failure.
|
* A SoftError caused by blacklisting.
|
||||||
*/
|
*/
|
||||||
BlacklistedError
|
BlacklistedError
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -576,6 +576,51 @@ private slots:
|
|||||||
//QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
//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)
|
QTEST_GUILESS_MAIN(TestSyncMove)
|
||||||
|
|||||||
@@ -373,7 +373,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountstate.cpp" line="132"/>
|
<location filename="../src/gui/accountstate.cpp" line="132"/>
|
||||||
<source>Maintenance mode</source>
|
<source>Maintenance mode</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Mode de manteniment</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountstate.cpp" line="134"/>
|
<location filename="../src/gui/accountstate.cpp" line="134"/>
|
||||||
@@ -1415,12 +1415,12 @@ Els elements que poden ser eliminats s'eliminaran si impedeixen que una car
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="73"/>
|
<location filename="../src/gui/issueswidget.ui" line="73"/>
|
||||||
<source>Show warnings</source>
|
<source>Show warnings</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Mostra avisos</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="83"/>
|
<location filename="../src/gui/issueswidget.ui" line="83"/>
|
||||||
<source>Show ignored files</source>
|
<source>Show ignored files</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Mostra arxius descartats</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="133"/>
|
<location filename="../src/gui/issueswidget.ui" line="133"/>
|
||||||
@@ -2507,7 +2507,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/servernotificationhandler.cpp" line="103"/>
|
<location filename="../src/gui/servernotificationhandler.cpp" line="103"/>
|
||||||
<source>Dismiss</source>
|
<source>Dismiss</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Ignora</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -2622,12 +2622,12 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharedialog.cpp" line="211"/>
|
<location filename="../src/gui/sharedialog.cpp" line="211"/>
|
||||||
<source>Users and Groups</source>
|
<source>Users and Groups</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Usuaris i Grups</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharedialog.cpp" line="218"/>
|
<location filename="../src/gui/sharedialog.cpp" line="218"/>
|
||||||
<source>Public Links</source>
|
<source>Public Links</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Enllaços públics</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -2650,7 +2650,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="35"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="35"/>
|
||||||
<source>Enter a name to create a new public link...</source>
|
<source>Enter a name to create a new public link...</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Escriu un nom per crear un enllaç públic...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="42"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="42"/>
|
||||||
@@ -2670,12 +2670,12 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="178"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="178"/>
|
||||||
<source>Link properties:</source>
|
<source>Link properties:</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Propietats de l'enllaç:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="220"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="220"/>
|
||||||
<source>Show file listing</source>
|
<source>Show file listing</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Motra el llistat de fitxers</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="200"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="200"/>
|
||||||
@@ -2685,7 +2685,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="20"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="20"/>
|
||||||
<source>Anyone with the link has access to the file/folder</source>
|
<source>Anyone with the link has access to the file/folder</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Qualsevol podrà accedir a l'arxiu o carpeta amb aquest link</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="117"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="117"/>
|
||||||
@@ -2727,7 +2727,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
|
||||||
<source>Copy link to clipboard</source>
|
<source>Copy link to clipboard</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Copiar al portadocuments</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
|
<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="63"/>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="543"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="543"/>
|
||||||
<source>Public link</source>
|
<source>Public link</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Enllaç públic</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="253"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="253"/>
|
||||||
@@ -2811,7 +2811,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
|
||||||
<source>Copy link to clipboard</source>
|
<source>Copy link to clipboard</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Copiar al portadocuments</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
|
||||||
@@ -2826,7 +2826,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="337"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="337"/>
|
||||||
<source>I shared something with you</source>
|
<source>I shared something with you</source>
|
||||||
<translation type="unfinished"/>
|
<translation>He compartit amb tu</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -2919,7 +2919,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/socketapi.cpp" line="557"/>
|
<location filename="../src/gui/socketapi.cpp" line="557"/>
|
||||||
<source>I shared something with you</source>
|
<source>I shared something with you</source>
|
||||||
<translation type="unfinished"/>
|
<translation>He compartit amb tu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/socketapi.cpp" line="565"/>
|
<location filename="../src/gui/socketapi.cpp" line="565"/>
|
||||||
@@ -3850,7 +3850,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="56"/>
|
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="56"/>
|
||||||
<source>Re-open Browser</source>
|
<source>Re-open Browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Reobrir navegador</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -4177,7 +4177,7 @@ No és aconsellada usar-la.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
||||||
<source>Could not open browser</source>
|
<source>Could not open browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>No es pot obrir el navegador</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="34"/>
|
<location filename="../src/gui/guiutility.cpp" line="34"/>
|
||||||
|
|||||||
@@ -83,12 +83,12 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
||||||
<source>Unknown error: network reply was deleted</source>
|
<source>Unknown error: network reply was deleted</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Neznámá chyba: odpověď sítě byla smazána</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
||||||
<source>Server replied "%1 %2" to "%3 %4"</source>
|
<source>Server replied "%1 %2" to "%3 %4"</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Odpověď serveru "%1 %2" do "%3 %4"</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -388,7 +388,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountstate.cpp" line="138"/>
|
<location filename="../src/gui/accountstate.cpp" line="138"/>
|
||||||
<source>Asking Credentials</source>
|
<source>Asking Credentials</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Požádat o pověření</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountstate.cpp" line="140"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/folderstatusmodel.cpp" line="209"/>
|
<location filename="../src/gui/folderstatusmodel.cpp" line="209"/>
|
||||||
<source>There are unresolved conflicts. Click for details.</source>
|
<source>There are unresolved conflicts. Click for details.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Jsou zde nevyřešené konflikty. Klikněte pro detaily.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/folderstatusmodel.cpp" line="878"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="20"/>
|
<location filename="../src/gui/issueswidget.ui" line="20"/>
|
||||||
<source>List of issues</source>
|
<source>List of issues</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Seznam problémů</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="34"/>
|
<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="273"/>
|
||||||
<location filename="../src/gui/owncloudgui.cpp" line="304"/>
|
<location filename="../src/gui/owncloudgui.cpp" line="304"/>
|
||||||
<source>Synchronization is paused</source>
|
<source>Synchronization is paused</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Synchronizace je pozastavena</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudgui.cpp" line="306"/>
|
<location filename="../src/gui/owncloudgui.cpp" line="306"/>
|
||||||
<source>Error during synchronization</source>
|
<source>Error during synchronization</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Chyba při synchronizaci</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudgui.cpp" line="314"/>
|
<location filename="../src/gui/owncloudgui.cpp" line="314"/>
|
||||||
@@ -3843,17 +3843,17 @@ Nedoporučuje se jí používat.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="36"/>
|
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="36"/>
|
||||||
<source>Please switch to your browser to proceed.</source>
|
<source>Please switch to your browser to proceed.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Chcete-li pokračovat, přepněte prosím do svého prohlížeče.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="46"/>
|
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="46"/>
|
||||||
<source>An error occured while connecting. Please try again.</source>
|
<source>An error occured while connecting. Please try again.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Při připojování došlo k chybě. Prosím zkuste to znovu.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="56"/>
|
<location filename="../src/gui/wizard/owncloudoauthcredspage.ui" line="56"/>
|
||||||
<source>Re-open Browser</source>
|
<source>Re-open Browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Znovu otevřít prohlížeč</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -4180,7 +4180,7 @@ Nedoporučuje se jí používat.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
||||||
<source>Could not open browser</source>
|
<source>Could not open browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Nemohu otevřít prohlížeč</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="34"/>
|
<location filename="../src/gui/guiutility.cpp" line="34"/>
|
||||||
|
|||||||
@@ -60,12 +60,12 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/notificationwidget.ui" line="56"/>
|
<location filename="../src/gui/notificationwidget.ui" line="56"/>
|
||||||
<source>Lorem ipsum dolor sit amet</source>
|
<source>Lorem ipsum dolor sit amet</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Lorem ipsum dolor sit amet</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/notificationwidget.ui" line="69"/>
|
<location filename="../src/gui/notificationwidget.ui" line="69"/>
|
||||||
<source>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod temporm </source>
|
<source>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod temporm </source>
|
||||||
<translation type="unfinished"/>
|
<translation>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod temporm</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/notificationwidget.ui" line="89"/>
|
<location filename="../src/gui/notificationwidget.ui" line="89"/>
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
||||||
<source>Unknown error: network reply was deleted</source>
|
<source>Unknown error: network reply was deleted</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Error desconocido: la respuesta de la red fue eliminada</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
||||||
|
|||||||
@@ -83,12 +83,12 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
||||||
<source>Unknown error: network reply was deleted</source>
|
<source>Unknown error: network reply was deleted</source>
|
||||||
<translation type="unfinished"/>
|
<translation>未知のエラーです:ネットワーク応答が削除されました</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
||||||
<source>Server replied "%1 %2" to "%3 %4"</source>
|
<source>Server replied "%1 %2" to "%3 %4"</source>
|
||||||
<translation type="unfinished"/>
|
<translation>サーバの返答は "%1 %2" から "%3 %4"です</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="667"/>
|
<location filename="../src/gui/accountsettings.cpp" line="667"/>
|
||||||
<source>Obtaining authorization from the browser. <a href='%1'>Click here</a> to re-open the browser.</source>
|
<source>Obtaining authorization from the browser. <a href='%1'>Click here</a> to re-open the browser.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>ブラウザから権限を取得しています。<a href='%1'>ここをクリック</a>してブラウザを再度開いてください。 </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="671"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="133"/>
|
<location filename="../src/gui/issueswidget.ui" line="133"/>
|
||||||
<source>There were too many issues. Not all will be visible here.</source>
|
<source>There were too many issues. Not all will be visible here.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>問題が多すぎます。すべてはここに表示できません。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="155"/>
|
<location filename="../src/gui/issueswidget.ui" line="155"/>
|
||||||
<source>Copy the issues list to the clipboard.</source>
|
<source>Copy the issues list to the clipboard.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>問題リストをクリップボードにコピーしてください。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="158"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="112"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="112"/>
|
||||||
<source>Error returned from the server: <em>%1</em></source>
|
<source>Error returned from the server: <em>%1</em></source>
|
||||||
<translation type="unfinished"/>
|
<translation>サーバからエラーが返されました: <em>%1</em> </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="115"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="121"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="121"/>
|
||||||
<source>The reply from the server did not contain all expected fields</source>
|
<source>The reply from the server did not contain all expected fields</source>
|
||||||
<translation type="unfinished"/>
|
<translation>サーバからの返答にあるべきフィールドがありません</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="125"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="125"/>
|
||||||
<source><h1>Login Error</h1><p>%1</p></source>
|
<source><h1>Login Error</h1><p>%1</p></source>
|
||||||
<translation type="unfinished"/>
|
<translation><h1>ログインエラー</h1><p>%1</p> </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
|
||||||
<source><h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p></source>
|
<source><h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p></source>
|
||||||
<translation type="unfinished"/>
|
<translation><h1>ユーザの誤りです</h1><p><em>%1</em>としてログインされましたがm、<em>%2</em>でなければいけません。<br>別のタブで %3 からログアウトし、<a href='%4'>ここをクリック</a>して %2 としてログインしてください</p> </translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -1885,7 +1885,7 @@ for additional privileges during the process.</source>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/wizard/owncloudoauthcredspage.cpp" line="44"/>
|
<location filename="../src/gui/wizard/owncloudoauthcredspage.cpp" line="44"/>
|
||||||
<source>Login in your browser</source>
|
<source>Login in your browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>御自身のブラウザでログインしてください</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -1962,7 +1962,7 @@ It is not advisable to use it.</source>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
|
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
|
||||||
<source>The server reported the following error:</source>
|
<source>The server reported the following error:</source>
|
||||||
<translation type="unfinished"/>
|
<translation>サーバが以下のエラーを報告しています:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
|
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
|
||||||
@@ -2723,12 +2723,12 @@ It is not advisable to use it.</source>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="163"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="163"/>
|
||||||
<source>Open link in browser</source>
|
<source>Open link in browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>ブラウザでリンクを開く</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
|
||||||
<source>Copy link to clipboard</source>
|
<source>Copy link to clipboard</source>
|
||||||
<translation type="unfinished"/>
|
<translation>クリップボードにリンクをコピー</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
|
||||||
@@ -2807,12 +2807,12 @@ It is not advisable to use it.</source>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="235"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="235"/>
|
||||||
<source>Open link in browser</source>
|
<source>Open link in browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>ブラウザでリンクを開く</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
|
||||||
<source>Copy link to clipboard</source>
|
<source>Copy link to clipboard</source>
|
||||||
<translation type="unfinished"/>
|
<translation>クリップボードにリンクをコピー</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
|
||||||
@@ -4178,12 +4178,12 @@ It is not advisable to use it.</source>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
||||||
<source>Could not open browser</source>
|
<source>Could not open browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>ブラウザを開くことができませんでした。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="34"/>
|
<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>
|
<source>There was an error when launching the browser to go to URL %1. Maybe no default browser is configured?</source>
|
||||||
<translation type="unfinished"/>
|
<translation>URL %1 をブラウザで開く際にエラーが発生しました。おそらくデフォルトのブラウザが設定されていないのでは?</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="55"/>
|
<location filename="../src/gui/guiutility.cpp" line="55"/>
|
||||||
|
|||||||
@@ -1720,7 +1720,7 @@ Elementer hvor sletting er tillatt, vil bli slettet hvis de forhindrer fjerning
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
|
||||||
<source><h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p></source>
|
<source><h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p></source>
|
||||||
<translation type="unfinished"/>
|
<translation><h1>Feil bruker</h1><p>Du logget inn med bruker <em>%1</em>, men må logge inn med bruker <em>%2</em>.<br>Logg ut av %3 i en annen tab, <a href='%4'>klikk deretter her</a> og logg inn som bruker %2</p></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
||||||
<source>Unknown error: network reply was deleted</source>
|
<source>Unknown error: network reply was deleted</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Onbekende fout: antwoord van het netwerk is verwijderd</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
||||||
@@ -243,7 +243,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="656"/>
|
<location filename="../src/gui/accountsettings.cpp" line="656"/>
|
||||||
<source>Server %1 is currently in maintenance mode.</source>
|
<source>Server %1 is currently in maintenance mode.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Server %1 is momenteel in onderhoudsmodus.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="658"/>
|
<location filename="../src/gui/accountsettings.cpp" line="658"/>
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="667"/>
|
<location filename="../src/gui/accountsettings.cpp" line="667"/>
|
||||||
<source>Obtaining authorization from the browser. <a href='%1'>Click here</a> to re-open the browser.</source>
|
<source>Obtaining authorization from the browser. <a href='%1'>Click here</a> to re-open the browser.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Probeert autorisatie te krijgen van de browser. 1 Klik hier 1 om de browser opnieuw te openen.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="671"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/folderstatusmodel.cpp" line="209"/>
|
<location filename="../src/gui/folderstatusmodel.cpp" line="209"/>
|
||||||
<source>There are unresolved conflicts. Click for details.</source>
|
<source>There are unresolved conflicts. Click for details.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Er zijn onopgeloste conflicten. Klik voor details.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/folderstatusmodel.cpp" line="878"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/folderstatusmodel.cpp" line="884"/>
|
<location filename="../src/gui/folderstatusmodel.cpp" line="884"/>
|
||||||
<source>Reconciling changes</source>
|
<source>Reconciling changes</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Wijzigingen doorvoeren</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/folderstatusmodel.cpp" line="919"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="133"/>
|
<location filename="../src/gui/issueswidget.ui" line="133"/>
|
||||||
<source>There were too many issues. Not all will be visible here.</source>
|
<source>There were too many issues. Not all will be visible here.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Er zijn teveel problemen. Niet alles zal worden vertoond.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="155"/>
|
<location filename="../src/gui/issueswidget.ui" line="155"/>
|
||||||
<source>Copy the issues list to the clipboard.</source>
|
<source>Copy the issues list to the clipboard.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Kopieer de probleemlijst naar het klembord.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="158"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/logbrowser.cpp" line="89"/>
|
<location filename="../src/gui/logbrowser.cpp" line="89"/>
|
||||||
<source>&Capture debug messages</source>
|
<source>&Capture debug messages</source>
|
||||||
<translation type="unfinished"/>
|
<translation>&Capture berichten debuggen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/logbrowser.cpp" line="101"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="115"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="115"/>
|
||||||
<source>There was an error accessing the 'token' endpoint: <br><em>%1</em></source>
|
<source>There was an error accessing the 'token' endpoint: <br><em>%1</em></source>
|
||||||
<translation type="unfinished"/>
|
<translation>Er heeft zich een fout voorgedaan bij het verkrijgen van de 'token' eindpunt: 1 2 %1 2</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="118"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="118"/>
|
||||||
<source>Could not parse the JSON returned from the server: <br><em>%1</em></source>
|
<source>Could not parse the JSON returned from the server: <br><em>%1</em></source>
|
||||||
<translation type="unfinished"/>
|
<translation>Kon de JSON dat teruggekomen is van de server niet ontleden: 1 2 %1 2</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="121"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="121"/>
|
||||||
<source>The reply from the server did not contain all expected fields</source>
|
<source>The reply from the server did not contain all expected fields</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Het antwoord van de server bevat niet alle verwachte velden</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="125"/>
|
<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>
|
<message>
|
||||||
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
|
<location filename="../src/gui/creds/oauth.cpp" line="131"/>
|
||||||
<source><h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p></source>
|
<source><h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p></source>
|
||||||
<translation type="unfinished"/>
|
<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>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -1892,7 +1892,7 @@ vragen om extra autorisaties tijdens installatie.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/wizard/owncloudoauthcredspage.cpp" line="44"/>
|
<location filename="../src/gui/wizard/owncloudoauthcredspage.cpp" line="44"/>
|
||||||
<source>Login in your browser</source>
|
<source>Login in your browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Login in uw browser</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -1970,7 +1970,7 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
|
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
|
||||||
<source>The server reported the following error:</source>
|
<source>The server reported the following error:</source>
|
||||||
<translation type="unfinished"/>
|
<translation>De server rapporteerde de volgende fout:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
|
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
|
||||||
@@ -2132,7 +2132,7 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/propagatedownload.cpp" line="459"/>
|
<location filename="../src/libsync/propagatedownload.cpp" line="459"/>
|
||||||
<source>The download would reduce free local disk space below the limit</source>
|
<source>The download would reduce free local disk space below the limit</source>
|
||||||
<translation type="unfinished"/>
|
<translation>De download zal de vrije lokale schijfruimte reduceren tot onder het limiet</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/propagatedownload.cpp" line="463"/>
|
<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="186"/>
|
||||||
<location filename="../src/libsync/propagateupload.cpp" line="549"/>
|
<location filename="../src/libsync/propagateupload.cpp" line="549"/>
|
||||||
<source>Upload of %1 exceeds the quota for the folder</source>
|
<source>Upload of %1 exceeds the quota for the folder</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Upload van %1 overtreft de quota van de folder</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/propagateupload.cpp" line="622"/>
|
<location filename="../src/libsync/propagateupload.cpp" line="622"/>
|
||||||
@@ -2659,12 +2659,12 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="35"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="35"/>
|
||||||
<source>Enter a name to create a new public link...</source>
|
<source>Enter a name to create a new public link...</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Voer een naam in om een nieuwe publieke link aan te maken</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="42"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="42"/>
|
||||||
<source>&Create new</source>
|
<source>&Create new</source>
|
||||||
<translation type="unfinished"/>
|
<translation>&Create nieuw</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="105"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="105"/>
|
||||||
@@ -2715,12 +2715,12 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="93"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="93"/>
|
||||||
<source>Link shares have been disabled</source>
|
<source>Link shares have been disabled</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Link delen zijn uitgeschakeld</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="107"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="107"/>
|
||||||
<source>Create public link share</source>
|
<source>Create public link share</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Maak een verdeelbare publieke link aan</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="168"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="168"/>
|
||||||
@@ -2741,7 +2741,7 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="165"/>
|
||||||
<source>Copy link to clipboard (direct download)</source>
|
<source>Copy link to clipboard (direct download)</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Kopieer de link naar het klembord (directe download)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="166"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="166"/>
|
||||||
@@ -2751,17 +2751,17 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="167"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="167"/>
|
||||||
<source>Send link by email (direct download)</source>
|
<source>Send link by email (direct download)</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Verzend link met email (directe download)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="519"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="519"/>
|
||||||
<source>Confirm Link Share Deletion</source>
|
<source>Confirm Link Share Deletion</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Bevestig Gedeelde Link Verwijdering</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="520"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="520"/>
|
||||||
<source><p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p></source>
|
<source><p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p></source>
|
||||||
<translation type="unfinished"/>
|
<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>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="527"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="527"/>
|
||||||
@@ -2777,7 +2777,7 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="253"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="253"/>
|
||||||
<source>Delete link share</source>
|
<source>Delete link share</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Verwijder verdeelbare link</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="458"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="458"/>
|
||||||
@@ -4186,7 +4186,7 @@ We adviseren deze site niet te gebruiken.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
<location filename="../src/gui/guiutility.cpp" line="33"/>
|
||||||
<source>Could not open browser</source>
|
<source>Could not open browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Kon het browser niet openen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/guiutility.cpp" line="34"/>
|
<location filename="../src/gui/guiutility.cpp" line="34"/>
|
||||||
|
|||||||
@@ -1966,7 +1966,7 @@ Não é aconselhada a sua utilização.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
|
<location filename="../src/gui/owncloudsetupwizard.cpp" line="297"/>
|
||||||
<source>The server reported the following error:</source>
|
<source>The server reported the following error:</source>
|
||||||
<translation type="unfinished"/>
|
<translation>O servidor retornou o seguinte erro:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
|
<location filename="../src/gui/owncloudsetupwizard.cpp" line="452"/>
|
||||||
@@ -2727,7 +2727,7 @@ Não é aconselhada a sua utilização.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="163"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="163"/>
|
||||||
<source>Open link in browser</source>
|
<source>Open link in browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Abrir ligação no navegador</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="164"/>
|
||||||
@@ -2742,7 +2742,7 @@ Não é aconselhada a sua utilização.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="166"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="166"/>
|
||||||
<source>Send link by email</source>
|
<source>Send link by email</source>
|
||||||
<translation>Enviar hiperligação por e-mail</translation>
|
<translation>Enviar hiperligação por correio eletrónico</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.cpp" line="167"/>
|
<location filename="../src/gui/sharelinkwidget.cpp" line="167"/>
|
||||||
@@ -2811,7 +2811,7 @@ Não é aconselhada a sua utilização.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="235"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="235"/>
|
||||||
<source>Open link in browser</source>
|
<source>Open link in browser</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Abrir ligação no navegador</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="237"/>
|
||||||
@@ -2821,7 +2821,7 @@ Não é aconselhada a sua utilização.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="239"/>
|
||||||
<source>Send link by email</source>
|
<source>Send link by email</source>
|
||||||
<translation>Enviar hiperligação por e-mail</translation>
|
<translation>Enviar hiperligação por correio eletrónico</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/shareusergroupwidget.cpp" line="249"/>
|
<location filename="../src/gui/shareusergroupwidget.cpp" line="249"/>
|
||||||
@@ -2939,7 +2939,7 @@ Não é aconselhada a sua utilização.</translation>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/socketapi.cpp" line="568"/>
|
<location filename="../src/gui/socketapi.cpp" line="568"/>
|
||||||
<source>Send private link by email...</source>
|
<source>Send private link by email...</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Enviar hiperligação privada por correio eletrónico...</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
|||||||
@@ -83,12 +83,12 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="247"/>
|
||||||
<source>Unknown error: network reply was deleted</source>
|
<source>Unknown error: network reply was deleted</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Незнайома помилка: відповідь мережі була видалена</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
<location filename="../src/libsync/abstractnetworkjob.cpp" line="390"/>
|
||||||
<source>Server replied "%1 %2" to "%3 %4"</source>
|
<source>Server replied "%1 %2" to "%3 %4"</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Сервер відповів "%1 %2" на "%3 %4"</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="650"/>
|
<location filename="../src/gui/accountsettings.cpp" line="650"/>
|
||||||
<source>The server version %1 is old and unsupported! Proceed at your own risk.</source>
|
<source>The server version %1 is old and unsupported! Proceed at your own risk.</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Версія на вашому сервері %1 застаріла та вже не підтримується! Продовжуйте на свій ризик та розсуд.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="652"/>
|
<location filename="../src/gui/accountsettings.cpp" line="652"/>
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="671"/>
|
<location filename="../src/gui/accountsettings.cpp" line="671"/>
|
||||||
<source>Connecting to %1...</source>
|
<source>Connecting to %1...</source>
|
||||||
<translation type="unfinished"/>
|
<translation>З'єднання з %1...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/accountsettings.cpp" line="674"/>
|
<location filename="../src/gui/accountsettings.cpp" line="674"/>
|
||||||
@@ -567,7 +567,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="168"/>
|
<location filename="../src/gui/application.cpp" line="168"/>
|
||||||
<source>Quit ownCloud</source>
|
<source>Quit ownCloud</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Вийти з ownCloud</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -1387,7 +1387,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="20"/>
|
<location filename="../src/gui/issueswidget.ui" line="20"/>
|
||||||
<source>List of issues</source>
|
<source>List of issues</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Перелік проблем</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/issueswidget.ui" line="34"/>
|
<location filename="../src/gui/issueswidget.ui" line="34"/>
|
||||||
|
|||||||
@@ -2671,7 +2671,7 @@ It is not advisable to use it.</source>
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="220"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="220"/>
|
||||||
<source>Show file listing</source>
|
<source>Show file listing</source>
|
||||||
<translation type="unfinished"/>
|
<translation>顯示檔案列表</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/sharelinkwidget.ui" line="200"/>
|
<location filename="../src/gui/sharelinkwidget.ui" line="200"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user