Merge pull request #32 from nextcloud-gmbh/oc_master

Oc master
This commit is contained in:
Roeland Jago Douma 2017-06-28 13:24:24 +02:00 committed by GitHub
commit 501394ec6f
108 changed files with 2598 additions and 1644 deletions

View File

@ -153,8 +153,6 @@ if(APPLE)
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" )
endif()
find_package(OpenSSL 1.0.0 REQUIRED)
if(APPLE)
find_package(Sparkle)
endif(APPLE)
@ -178,9 +176,11 @@ endif()
find_package(ZLIB)
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
if (NOT DEFINED APPLICATION_ICON_NAME)
set(APPLICATION_ICON_NAME ${APPLICATION_SHORTNAME})
endif()
configure_file(test/test_journal.db "${CMAKE_BINARY_DIR}/test/test_journal.db" COPYONLY)
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
include(OwnCloudCPack.cmake)

View File

@ -2,17 +2,22 @@ ChangeLog
=========
version 2.4.0 (2017-0X-XX)
* OAuth2 authentication support
* Sharing: Add support for multiple public link shares (#5655)
* Sharing: Add option to copy/email direct links (#5627)
* Sharing: Show warning that links are public
* Sharing: Many UI improvements
* Wizards: Never propose an existing folder for syncing (#5597)
* Wizard: Don't show last page anymore, go to settings directly (#5726)
* Settings Dialog: Display the user server avatar
* Selective Sync: Open sub folder context menu (#5596)
* Selective Sync: Skip excluded folders when reading db
* Selective Sync: SelectiveSync: Remove local files of unselected folder despite other modified files (#5783)
* Exclude list: remove .htaccess
* Detect maintenance mode (#4485)
* Discovery: Increase the MAX_DEPTH and show deep folders as ignored
* Downloads: Remove empty temporary if disk space full (#5746)
* Wizard: Don't show not-so-useful result page (#5726)
* Downloads: Re-trigger folder discovery on 404
* When creating explorer favorite use more specific windows functions (#5690)
* Added owncloudcmd bandwidth limit parameter (#5707)
* AccountSettings: Sync with clean discovery on Ctrl-F6 (#5666)
@ -22,6 +27,9 @@ version 2.4.0 (2017-0X-XX)
* Switch 3rdparty/json usage to Qt5's QJson (#5710)
* Reduce memory usage
* Documentation improvements
* Logging improvements (with Qt logging categories), new --logdebug parameter
* Harmonize source code style with clang-format
* Crash fixes
version 2.3.2 (2017-05-08)
* Fix more crashes (thanks to everyone submitting to our crash reporter!)

17
Jenkinsfile vendored
View File

@ -1,5 +1,12 @@
#!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
@ -9,17 +16,17 @@ node('CLIENT') {
sh '''rm -rf build
mkdir build
cd build
cmake -DUNIT_TESTING=1 -DBUILD_WITH_QT4=OFF ..
cmake -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 -DWITH_TESTING=1 -DBUILD_WITH_QT4=OFF ..
make -j4
ctest --output-on-failure'''
ctest -V --output-on-failure'''
stage 'Qt5 - clang'
sh '''rm -rf build
mkdir build
cd build
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DBUILD_WITH_QT4=OFF ..
cmake -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DWITH_TESTING=1 -DBUILD_WITH_QT4=OFF ..
make -j4
ctest --output-on-failure'''
ctest -V --output-on-failure'''
stage 'Win32'
@ -37,6 +44,8 @@ node('CLIENT') {
ctest .
'''
}
// Stage 'macOS' TODO
}

View File

@ -3,6 +3,7 @@ set( APPLICATION_EXECUTABLE "owncloud" )
set( APPLICATION_DOMAIN "owncloud.com" )
set( APPLICATION_VENDOR "ownCloud" )
set( APPLICATION_UPDATE_URL "https://updates.owncloud.com/client/" CACHE string "URL for updater" )
set( APPLICATION_ICON_NAME "owncloud" )
set( THEME_CLASS "ownCloudTheme" )
set( APPLICATION_REV_DOMAIN "com.owncloud.desktopclient" )

2
binary

@ -1 +1 @@
Subproject commit 741b49156bb7b55347c20228d6ff9d4aa493cd91
Subproject commit 1818b48380f4fc50d482b980e5ec0d347f896a70

View File

@ -1,306 +0,0 @@
# - Try to find the OpenSSL encryption library
# Once done this will define
#
# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
#
# Read-Only variables:
# OPENSSL_FOUND - system has the OpenSSL library
# OPENSSL_INCLUDE_DIR - the OpenSSL include directory
# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL
# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s)
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
# Copyright 2009-2011 Mathieu Malaterre <mathieu.malaterre@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if (UNIX)
find_package(PkgConfig QUIET)
pkg_check_modules(_OPENSSL QUIET openssl)
endif (UNIX)
# http://www.slproweb.com/products/Win32OpenSSL.html
SET(_OPENSSL_ROOT_HINTS
$ENV{OPENSSL_ROOT_DIR}
${OPENSSL_ROOT_DIR}
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
)
SET(_OPENSSL_ROOT_PATHS
"$ENV{PROGRAMFILES}/OpenSSL"
"$ENV{PROGRAMFILES}/OpenSSL-Win32"
"$ENV{PROGRAMFILES}/OpenSSL-Win64"
"C:/OpenSSL/"
"C:/OpenSSL-Win32/"
"C:/OpenSSL-Win64/"
)
SET(_OPENSSL_ROOT_HINTS_AND_PATHS
HINTS ${_OPENSSL_ROOT_HINTS}
PATHS ${_OPENSSL_ROOT_PATHS}
)
FIND_PATH(OPENSSL_INCLUDE_DIR
NAMES
openssl/ssl.h
HINTS
${_OPENSSL_INCLUDEDIR}
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
IF(WIN32 AND NOT CYGWIN)
# MINGW should go here too
IF(MSVC)
# /MD and /MDd are the standard values - if someone wants to use
# others, the libnames have to change here too
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
# TODO: handle /MT and static lib
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
# * MD for dynamic-release
# * MDd for dynamic-debug
# * MT for static-release
# * MTd for static-debug
# Implementation details:
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
# libeay32MD.lib is identical to ../libeay32.lib, and
# ssleay32MD.lib is identical to ../ssleay32.lib
FIND_LIBRARY(LIB_EAY_DEBUG
NAMES
libeay32MDd
libeay32
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
"lib"
"VC"
"lib/VC"
)
FIND_LIBRARY(LIB_EAY_RELEASE
NAMES
libeay32MD
libeay32
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
"lib"
"VC"
"lib/VC"
)
FIND_LIBRARY(SSL_EAY_DEBUG
NAMES
ssleay32MDd
ssleay32
ssl
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
"lib"
"VC"
"lib/VC"
)
FIND_LIBRARY(SSL_EAY_RELEASE
NAMES
ssleay32MD
ssleay32
ssl
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
"lib"
"VC"
"lib/VC"
)
if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
set( OPENSSL_LIBRARIES
optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
)
else()
set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
endif()
MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE)
MARK_AS_ADVANCED(LIB_EAY_DEBUG LIB_EAY_RELEASE)
ELSEIF(MINGW)
# same player, for MingW
FIND_LIBRARY(LIB_EAY
NAMES
libeay32
crypto
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
"lib"
"lib/MinGW"
)
FIND_LIBRARY(SSL_EAY
NAMES
ssleay32
ssl
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
"lib"
"lib/MinGW"
)
MARK_AS_ADVANCED(SSL_EAY LIB_EAY)
set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
ELSE(MSVC)
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
FIND_LIBRARY(LIB_EAY
NAMES
libeay32
HINTS
${_OPENSSL_LIBDIR}
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
FIND_LIBRARY(SSL_EAY
NAMES
ssleay32
HINTS
${_OPENSSL_LIBDIR}
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
MARK_AS_ADVANCED(SSL_EAY LIB_EAY)
set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
ENDIF(MSVC)
ELSE(WIN32 AND NOT CYGWIN)
FIND_LIBRARY(OPENSSL_SSL_LIBRARY
NAMES
ssl
ssleay32
ssleay32MD
HINTS
${_OPENSSL_LIBDIR}
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
FIND_LIBRARY(OPENSSL_CRYPTO_LIBRARY
NAMES
crypto
HINTS
${_OPENSSL_LIBDIR}
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
MARK_AS_ADVANCED(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY)
# compat defines
SET(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY})
SET(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
SET(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
ENDIF(WIN32 AND NOT CYGWIN)
function(from_hex HEX DEC)
string(TOUPPER "${HEX}" HEX)
set(_res 0)
string(LENGTH "${HEX}" _strlen)
while (_strlen GREATER 0)
math(EXPR _res "${_res} * 16")
string(SUBSTRING "${HEX}" 0 1 NIBBLE)
string(SUBSTRING "${HEX}" 1 -1 HEX)
if (NIBBLE STREQUAL "A")
math(EXPR _res "${_res} + 10")
elseif (NIBBLE STREQUAL "B")
math(EXPR _res "${_res} + 11")
elseif (NIBBLE STREQUAL "C")
math(EXPR _res "${_res} + 12")
elseif (NIBBLE STREQUAL "D")
math(EXPR _res "${_res} + 13")
elseif (NIBBLE STREQUAL "E")
math(EXPR _res "${_res} + 14")
elseif (NIBBLE STREQUAL "F")
math(EXPR _res "${_res} + 15")
else()
math(EXPR _res "${_res} + ${NIBBLE}")
endif()
string(LENGTH "${HEX}" _strlen)
endwhile()
set(${DEC} ${_res} PARENT_SCOPE)
endfunction(from_hex)
if (OPENSSL_INCLUDE_DIR)
if (_OPENSSL_VERSION)
set(OPENSSL_VERSION "${_OPENSSL_VERSION}")
elseif(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
# The version number is encoded as 0xMNNFFPPS: major minor fix patch status
# The status gives if this is a developer or prerelease and is ignored here.
# Major, minor, and fix directly translate into the version numbers shown in
# the string. The patch field translates to the single character suffix that
# indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so
# on.
string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$"
"\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}")
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
# 96 is the ASCII code of 'a' minus 1
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
unset(_tmp)
# Once anyone knows how OpenSSL would call the patch versions beyond 'z'
# this should be updated to handle that, too. This has not happened yet
# so it is simply ignored here for now.
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
endif (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
endif (_OPENSSL_VERSION)
endif (OPENSSL_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
if (OPENSSL_VERSION)
find_package_handle_standard_args(OpenSSL
REQUIRED_VARS
OPENSSL_LIBRARIES
OPENSSL_INCLUDE_DIR
VERSION_VAR
OPENSSL_VERSION
FAIL_MESSAGE
"Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
)
else (OPENSSL_VERSION)
find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
OPENSSL_LIBRARIES
OPENSSL_INCLUDE_DIR
)
endif (OPENSSL_VERSION)
MARK_AS_ADVANCED(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)

View File

@ -13,7 +13,9 @@
# so that it doesn't pull a different Qt version. For that reason
# first look in the Qt lib directory for QtKeychain.
get_target_property(_QTCORE_LIB_PATH Qt5::Core IMPORTED_LOCATION_RELEASE)
get_filename_component(QT_LIB_DIR "${_QTCORE_LIB_PATH}" DIRECTORY)
# Use PATH here because Debian 7.0 has CMake 2.8.9 and DIRECTORY is only available from 2.8.12+
get_filename_component(QT_LIB_DIR "${_QTCORE_LIB_PATH}" PATH)
find_path(QTKEYCHAIN_INCLUDE_DIR
NAMES

View File

@ -1,39 +0,0 @@
# (c) 2014 Copyright ownCloud GmbH
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - Try to find QtKeychain
# Once done this will define
# QTKEYCHAIN_FOUND - System has QtKeychain
# QTKEYCHAIN_INCLUDE_DIRS - The QtKeychain include directories
# QTKEYCHAIN_LIBRARIES - The libraries needed to use QtKeychain
# QTKEYCHAIN_DEFINITIONS - Compiler switches required for using LibXml2
find_path(QTKEYCHAIN_INCLUDE_DIR
NAMES
keychain.h
PATH_SUFFIXES
qtkeychain
)
find_library(QTKEYCHAIN_LIBRARY
NAMES
qtkeychain
libqtkeychain
PATHS
/usr/lib
/usr/lib/${CMAKE_ARCH_TRIPLET}
/usr/local/lib
/opt/local/lib
${CMAKE_LIBRARY_PATH}
${CMAKE_INSTALL_PREFIX}/lib
)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set QTKEYCHAIN_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(QtKeychain DEFAULT_MSG
QTKEYCHAIN_LIBRARY QTKEYCHAIN_INCLUDE_DIR)
mark_as_advanced(QTKEYCHAIN_INCLUDE_DIR QTKEYCHAIN_LIBRARY)

View File

@ -17,6 +17,7 @@
#cmakedefine APPLICATION_SHORTNAME "@APPLICATION_SHORTNAME@"
#cmakedefine APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@"
#cmakedefine APPLICATION_UPDATE_URL "@APPLICATION_UPDATE_URL@"
#cmakedefine APPLICATION_ICON_NAME "@APPLICATION_ICON_NAME@"
#cmakedefine ZLIB_FOUND @ZLIB_FOUND@

View File

@ -376,8 +376,7 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
trav.error_status = cur->error_status;
trav.has_ignored_files = cur->has_ignored_files;
trav.checksum = cur->checksum;
trav.checksumTypeId = cur->checksumTypeId;
trav.checksumHeader = cur->checksumHeader;
if( other_node ) {
csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data;
@ -670,7 +669,7 @@ void csync_file_stat_free(csync_file_stat_t *st)
SAFE_FREE(st->directDownloadCookies);
SAFE_FREE(st->etag);
SAFE_FREE(st->destpath);
SAFE_FREE(st->checksum);
SAFE_FREE(st->checksumHeader);
SAFE_FREE(st);
}
}

View File

@ -223,6 +223,10 @@ struct csync_vio_file_stat_s {
enum csync_vio_file_flags_e flags;
char *original_name; // only set if locale conversion fails
// For remote file stats: the highest quality checksum the server provided
// in the "SHA1:324315da2143" form.
char *checksumHeader;
};
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
@ -262,8 +266,7 @@ struct csync_tree_walk_file_s {
char *directDownloadUrl;
char *directDownloadCookies;
const char *checksum;
uint32_t checksumTypeId;
const char *checksumHeader;
struct {
int64_t size;
@ -304,8 +307,8 @@ typedef int (*csync_vio_stat_hook) (csync_vio_handle_t *dhhandle,
void *userdata);
/* Compute the checksum of the given \a checksumTypeId for \a path. */
typedef const char* (*csync_checksum_hook) (
const char *path, uint32_t checksumTypeId, void *userdata);
typedef const char *(*csync_checksum_hook)(
const char *path, const char *otherChecksumHeader, void *userdata);
/**
* @brief Allocate a csync context.

View File

@ -235,6 +235,11 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
match = CSYNC_FILE_SILENTLY_EXCLUDED;
goto out;
}
rc = csync_fnmatch(".sync_*.db*", bname, 0);
if (rc == 0) {
match = CSYNC_FILE_SILENTLY_EXCLUDED;
goto out;
}
rc = csync_fnmatch(".csync_journal.db*", bname, 0);
if (rc == 0) {
match = CSYNC_FILE_SILENTLY_EXCLUDED;

View File

@ -191,8 +191,11 @@ struct csync_file_stat_s {
char *directDownloadCookies;
char remotePerm[REMOTE_PERM_BUF_SIZE+1];
const char *checksum;
uint32_t checksumTypeId;
// In the local tree, this can hold a checksum and its type if it is
// computed during discovery for some reason.
// In the remote tree, this will have the server checksum, if available.
// In both cases, the format is "SHA1:baff".
const char *checksumHeader;
CSYNC_STATUS error_status;

View File

@ -65,6 +65,19 @@ static c_rbnode_t *_csync_check_ignored(c_rbtree_t *tree, const char *path, int
}
}
/* Returns true if we're reasonably certain that hash equality
* for the header means content equality.
*
* Cryptographic safety is not required - this is mainly
* intended to rule out checksums like Adler32 that are not intended for
* hashing and have high likelihood of collision with particular inputs.
*/
static bool _csync_is_collision_safe_hash(const char *checksum_header)
{
return strncmp(checksum_header, "SHA1:", 5) == 0
|| strncmp(checksum_header, "MD5:", 4) == 0;
}
/**
* The main function in the reconcile pass.
*
@ -272,11 +285,31 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
// Folders of the same path are always considered equals
is_conflict = false;
} else {
// If the size or mtime is different, it's definitely a conflict.
is_conflict = ((other->size != cur->size) || (other->modtime != cur->modtime));
// FIXME: do a binary comparision of the file here because of the following
// edge case:
// The files could still have different content, even though the mtime
// and size are the same.
// It could be a conflict even if size and mtime match!
//
// In older client versions we always treated these cases as a
// non-conflict. This behavior is preserved in case the server
// doesn't provide a suitable content hash.
//
// When it does have one, however, we do create a job, but the job
// will compare hashes and avoid the download if they are equal.
const char *remoteChecksumHeader =
(ctx->current == REMOTE_REPLICA ? cur->checksumHeader : other->checksumHeader);
if (remoteChecksumHeader) {
is_conflict |= _csync_is_collision_safe_hash(remoteChecksumHeader);
}
// SO: If there is no checksum, we can have !is_conflict here
// even though the files have different content! This is an
// intentional tradeoff. Downloading and comparing files would
// be technically correct in this situation but leads to too
// much waste.
// In particular this kind of NEW/NEW situation with identical
// sizes and mtimes pops up when the local database is lost for
// whatever reason.
}
if (ctx->current == REMOTE_REPLICA) {
// If the files are considered equal, only update the DB with the etag from remote

View File

@ -225,7 +225,12 @@ int csync_statedb_close(CSYNC *ctx) {
return rc;
}
#define METADATA_COLUMNS "phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentChecksum, contentChecksumTypeId"
#define METADATA_QUERY \
"phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, " \
"filesize, ignoredChildrenRemote, " \
"contentchecksumtype.name || ':' || contentChecksum " \
"FROM metadata " \
"LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id"
// This funciton parses a line from the metadata table into the given csync_file_stat
// structure which it is also allocating.
@ -287,9 +292,8 @@ static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3
if(column_count > 13) {
(*st)->has_ignored_files = sqlite3_column_int(stmt, 13);
}
if(column_count > 15 && sqlite3_column_int(stmt, 15)) {
(*st)->checksum = c_strdup( (char*) sqlite3_column_text(stmt, 14));
(*st)->checksumTypeId = sqlite3_column_int(stmt, 15);
if (column_count > 14 && sqlite3_column_text(stmt, 14)) {
(*st)->checksumHeader = c_strdup((char *)sqlite3_column_text(stmt, 14));
}
}
@ -313,7 +317,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
}
if( ctx->statedb.by_hash_stmt == NULL ) {
const char *hash_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE phash=?1";
const char *hash_query = "SELECT " METADATA_QUERY " WHERE phash=?1";
SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL));
ctx->statedb.lastReturnValue = rc;
@ -356,7 +360,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
}
if( ctx->statedb.by_fileid_stmt == NULL ) {
const char *query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE fileid=?1";
const char *query = "SELECT " METADATA_QUERY " WHERE fileid=?1";
SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL));
ctx->statedb.lastReturnValue = rc;
@ -396,7 +400,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
}
if( ctx->statedb.by_inode_stmt == NULL ) {
const char *inode_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE inode=?1";
const char *inode_query = "SELECT " METADATA_QUERY " WHERE inode=?1";
SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL));
ctx->statedb.lastReturnValue = rc;
@ -439,7 +443,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
* In other words, anything that is between path+'/' and path+'0',
* (because '0' follows '/' in ascii)
*/
const char *below_path_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE path > (?||'/') AND path < (?||'0') ORDER BY path||'/' ASC";
const char *below_path_query = "SELECT " METADATA_QUERY " WHERE path > (?||'/') AND path < (?||'0') ORDER BY path||'/' ASC";
SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, below_path_query, -1, &stmt, NULL));
ctx->statedb.lastReturnValue = rc;
if( rc != SQLITE_OK ) {

View File

@ -287,16 +287,15 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
// Checksum comparison at this stage is only enabled for .eml files,
// check #4754 #4755
bool isEmlFile = csync_fnmatch("*.eml", file, FNM_CASEFOLD) == 0;
if (isEmlFile && fs->size == tmp->size && tmp->checksumTypeId) {
if (isEmlFile && fs->size == tmp->size && tmp->checksumHeader) {
if (ctx->callbacks.checksum_hook) {
st->checksum = ctx->callbacks.checksum_hook(
file, tmp->checksumTypeId,
ctx->callbacks.checksum_userdata);
st->checksumHeader = ctx->callbacks.checksum_hook(
file, tmp->checksumHeader,
ctx->callbacks.checksum_userdata);
}
bool checksumIdentical = false;
if (st->checksum) {
st->checksumTypeId = tmp->checksumTypeId;
checksumIdentical = strncmp(st->checksum, tmp->checksum, 1000) == 0;
if (st->checksumHeader) {
checksumIdentical = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
}
if (checksumIdentical) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", path);
@ -381,15 +380,14 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
// Verify the checksum where possible
if (isRename && tmp->checksumTypeId && ctx->callbacks.checksum_hook
&& fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) {
st->checksum = ctx->callbacks.checksum_hook(
file, tmp->checksumTypeId,
ctx->callbacks.checksum_userdata);
if (st->checksum) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksum, tmp->checksum);
st->checksumTypeId = tmp->checksumTypeId;
isRename = strncmp(st->checksum, tmp->checksum, 1000) == 0;
if (isRename && tmp->checksumHeader && ctx->callbacks.checksum_hook
&& fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) {
st->checksumHeader = ctx->callbacks.checksum_hook(
file, tmp->checksumHeader,
ctx->callbacks.checksum_userdata);
if (st->checksumHeader) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksumHeader, tmp->checksumHeader);
isRename = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
}
}
@ -506,6 +504,11 @@ out:
strncpy(st->remotePerm, fs->remotePerm, REMOTE_PERM_BUF_SIZE);
}
// For the remote: propagate the discovered checksum
if (fs->checksumHeader && ctx->current == REMOTE_REPLICA) {
st->checksumHeader = c_strdup(fs->checksumHeader);
}
st->phash = h;
st->pathlen = len;
memcpy(st->path, (len ? path : ""), len + 1);

View File

@ -40,6 +40,9 @@ csync_vio_file_stat_t* csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat
if (file_stat_cpy->directDownloadUrl) {
file_stat_cpy->directDownloadUrl = c_strdup(file_stat_cpy->directDownloadUrl);
}
if (file_stat_cpy->checksumHeader) {
file_stat_cpy->checksumHeader = c_strdup(file_stat_cpy->checksumHeader);
}
file_stat_cpy->name = c_strdup(file_stat_cpy->name);
return file_stat_cpy;
}
@ -57,6 +60,7 @@ void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) {
SAFE_FREE(file_stat->directDownloadCookies);
SAFE_FREE(file_stat->name);
SAFE_FREE(file_stat->original_name);
SAFE_FREE(file_stat->checksumHeader);
SAFE_FREE(file_stat);
}

View File

@ -157,7 +157,16 @@ static void check_csync_excluded(void **state)
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
rc = csync_excluded_no_ctx(csync->excludes, "subdir/._sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db.ctmp", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db-shm", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
rc = csync_excluded_no_ctx(csync->excludes, "subdir/.sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
/* pattern ]*.directory - ignore and remove */
rc = csync_excluded_no_ctx(csync->excludes, "my.~directory", CSYNC_FTW_TYPE_FILE);

View File

@ -120,7 +120,6 @@ follow `Windows Installer Build (Cross-Compile)`_ instead.
* Make sure that you have CMake_ and Git_.
* Download the Qt_ MinGW package. You will use the MinGW version bundled with it.
* Download an `OpenSSL Windows Build`_ (the non-"Light" version)
2. Get the QtKeychain_ sources as well as the latest versions of the ownCloud client
from Git as follows::
@ -130,11 +129,10 @@ follow `Windows Installer Build (Cross-Compile)`_ instead.
3. Open the Qt MinGW shortcut console from the Start Menu
4. Make sure that OpenSSL's ``bin`` directory as well as your qtkeychain source
directories are in your PATH. This will allow CMake to find the library and
headers, as well as allow the ownCloud client to find the DLLs at runtime::
4. Make sure that your qtkeychain source directories are in your PATH. This will
allow CMake to find the library and headers, as well as allow the ownCloud
client to find the DLLs at runtime::
set PATH=C:\<OpenSSL Install Dir>\bin;%PATH%
set PATH=C:\<qtkeychain Clone Dir>;%PATH%
5. Build qtkeychain **directly in the source directory** so that the DLL is built
@ -251,7 +249,7 @@ To build the most up-to-date version of the client:
.. note:: qtkeychain must be compiled with the same prefix e.g ``CMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ .``
.. note:: Example:: ``cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 -DCMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ -D_OPENSSL_LIBDIR=/usr/local/opt/openssl/lib/ -D_OPENSSL_INCLUDEDIR=/usr/local/opt/openssl/include/ -D_OPENSSL_VERSION=1.0.2a -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include/ -DNO_SHIBBOLETH=1``
.. note:: Example:: ``cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 -DCMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ -DNO_SHIBBOLETH=1``
4. Call ``make``.
@ -279,7 +277,6 @@ The following are known cmake parameters:
.. _Git: http://git-scm.com
.. _MacPorts: http://www.macports.org
.. _Homebrew: http://mxcl.github.com/homebrew/
.. _OpenSSL Windows Build: http://slproweb.com/products/Win32OpenSSL.html
.. _Qt: http://www.qt.io/download
.. _Microsoft Authenticode: https://msdn.microsoft.com/en-us/library/ie/ms537361%28v=vs.85%29.aspx
.. _QtKeychain: https://github.com/frankosterfeld/qtkeychain

View File

@ -9,6 +9,45 @@ Icon=@APPLICATION_EXECUTABLE@
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
GenericName[oc]=Dorsièr de Sincronizacion
@ -149,6 +188,10 @@ GenericName[zh_CN]=文件夹同步
Name[zh_CN]=@APPLICATION_NAME@
Icon[zh_CN]=@APPLICATION_EXECUTABLE@
GenericName[zh_TW]=
Comment[es_AR]=Cliente de sincronización para escritorio @APPLICATION_NAME@
GenericName[es_AR]=Sincronización de directorio
Name[es_AR]=Cliente de sincronización para escritorio @APPLICATION_NAME@
Icon[es_AR]=@APPLICATION_EXECUTABLE@
Comment[lt_LT]=@APPLICATION_NAME@ darbalaukio sinchronizavimo programa
GenericName[lt_LT]=Katalogo sinchnorizacija
Name[lt_LT]=@APPLICATION_NAME@ darbalaukio programa

View File

@ -172,9 +172,10 @@ void RemotePathChecker::workerThreadLoop()
RemotePathChecker::RemotePathChecker()
: _watchedDirectories(make_shared<const vector<wstring>>())
: _stop(false)
, _watchedDirectories(make_shared<const vector<wstring>>())
, _connected(false)
, _newQueries(CreateEvent(NULL, true, true, NULL))
, _newQueries(CreateEvent(NULL, FALSE, FALSE, NULL))
, _thread([this]{ this->workerThreadLoop(); })
{
}

View File

@ -2,7 +2,7 @@
// This is the number that will end up in the version window of the DLLs.
// Increment this version before committing a new build if you are today's shell_integration build master.
#define OCEXT_BUILD_NUM 44
#define OCEXT_BUILD_NUM 45
#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)

View File

@ -188,6 +188,7 @@ void help()
std::cout << " --downlimit [n] Limit the download speed of files to n KB/s" << std::endl;
std::cout << " -h Sync hidden files,do not ignore them" << std::endl;
std::cout << " --version, -v Display version and exit" << std::endl;
std::cout << " --debug More verbose logging" << std::endl;
std::cout << "" << std::endl;
exit(0);
}
@ -495,7 +496,7 @@ restart_sync:
}
Cmd cmd;
QString dbPath = options.source_dir + SyncJournalDb::makeDbName(credentialFreeUrl, folder, user);
QString dbPath = options.source_dir + SyncJournalDb::makeDbName(options.source_dir, credentialFreeUrl, folder, user);
SyncJournalDb db(dbPath);
if (!selectiveSyncList.empty()) {

View File

@ -35,6 +35,7 @@ set(client_UI
wizard/owncloudadvancedsetuppage.ui
wizard/owncloudconnectionmethoddialog.ui
wizard/owncloudhttpcredspage.ui
wizard/owncloudoauthcredspage.ui
wizard/owncloudsetupnocredspage.ui
wizard/owncloudwizardresultpage.ui
)
@ -93,11 +94,13 @@ set(client_SRCS
servernotificationhandler.cpp
creds/credentialsfactory.cpp
creds/httpcredentialsgui.cpp
creds/oauth.cpp
wizard/postfixlineedit.cpp
wizard/abstractcredswizardpage.cpp
wizard/owncloudadvancedsetuppage.cpp
wizard/owncloudconnectionmethoddialog.cpp
wizard/owncloudhttpcredspage.cpp
wizard/owncloudoauthcredspage.cpp
wizard/owncloudsetuppage.cpp
wizard/owncloudwizardcommon.cpp
wizard/owncloudwizard.cpp
@ -173,7 +176,6 @@ set(3rdparty_INC
)
include_directories(${3rdparty_INC})
include_directories(${OPENSSL_INCLUDE_DIR})
# csync is required.
include_directories(${CMAKE_SOURCE_DIR}/csync/src
@ -221,15 +223,13 @@ endif()
include( AddAppIconMacro )
set(ownCloud_old ${ownCloud})
# set an icon_app_name. For historical reasons we can not use the
# application_shortname for ownCloud but must rather set it manually.
if ( EXISTS ${OEM_THEME_DIR}/OEM.cmake )
set(ICON_APP_NAME ${APPLICATION_SHORTNAME})
else()
set(ICON_APP_NAME "owncloud")
# For historical reasons we can not use the application_shortname
# for ownCloud but must rather set it manually.
if (NOT DEFINED APPLICATION_ICON_NAME)
set(APPLICATION_ICON_NAME ${APPLICATION_SHORTNAME})
endif()
kde4_add_app_icon( ownCloud "${theme_dir}/colored/${ICON_APP_NAME}-icon*.png")
kde4_add_app_icon( ownCloud "${theme_dir}/colored/${APPLICATION_ICON_NAME}-icon*.png")
list(APPEND final_src ${ownCloud})
set(ownCloud ${ownCloud_old})
@ -243,11 +243,11 @@ endif()
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
if(NOT WIN32)
file( GLOB _icons "${theme_dir}/colored/${ICON_APP_NAME}-icon-*.png" )
file( GLOB _icons "${theme_dir}/colored/${APPLICATION_ICON_NAME}-icon-*.png" )
foreach( _file ${_icons} )
string( REPLACE "${theme_dir}/colored/${ICON_APP_NAME}-icon-" "" _res ${_file} )
string( REPLACE "${theme_dir}/colored/${APPLICATION_ICON_NAME}-icon-" "" _res ${_file} )
string( REPLACE ".png" "" _res ${_res} )
install( FILES ${_file} RENAME ${ICON_APP_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
install( FILES ${_file} RENAME ${APPLICATION_ICON_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
endforeach( _file )
endif(NOT WIN32)

View File

@ -202,6 +202,7 @@ void AccountSettings::slotOpenAccountWizard()
void AccountSettings::slotToggleSignInState()
{
if (_accountState->isSignedOut()) {
_accountState->account()->resetRejectedCertificates();
_accountState->signIn();
} else {
_accountState->signOutByUi();

View File

@ -53,8 +53,6 @@
#include <QMenu>
#include <QMessageBox>
#include <openssl/crypto.h>
class QSocket;
namespace OCC {
@ -438,6 +436,7 @@ void Application::parseOptions(const QStringList &options)
showHint("Path for confdir not specified");
}
} else if (option == QLatin1String("--debug")) {
_logDebug = true;
_debugMode = true;
} else if (option == QLatin1String("--version")) {
_versionOnly = true;

View File

@ -15,9 +15,14 @@
#include <QInputDialog>
#include <QLabel>
#include <QDesktopServices>
#include <QNetworkReply>
#include <QTimer>
#include <QBuffer>
#include "creds/httpcredentialsgui.h"
#include "theme.h"
#include "account.h"
#include <QMessageBox>
using namespace QKeychain;
@ -25,11 +30,61 @@ namespace OCC {
void HttpCredentialsGui::askFromUser()
{
// The rest of the code assumes that this will be done asynchronously
QMetaObject::invokeMethod(this, "askFromUserAsync", Qt::QueuedConnection);
_password = QString(); // So our QNAM does not add any auth
// First, we will send a call to the webdav endpoint to check what kind of auth we need.
auto reply = _account->sendRequest("GET", _account->davUrl());
QTimer::singleShot(30 * 1000, reply, &QNetworkReply::abort);
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply] {
reply->deleteLater();
if (reply->rawHeader("WWW-Authenticate").contains("Bearer ")) {
// OAuth
_asyncAuth.reset(new OAuth(_account, this));
connect(_asyncAuth.data(), &OAuth::result,
this, &HttpCredentialsGui::asyncAuthResult);
_asyncAuth->start();
} else if (reply->error() == QNetworkReply::AuthenticationRequiredError) {
// Show the dialog
// We will re-enter the event loop, so better wait the next iteration
QMetaObject::invokeMethod(this, "showDialog", Qt::QueuedConnection);
} else {
// Network error?
emit asked();
}
});
}
void HttpCredentialsGui::askFromUserAsync()
void HttpCredentialsGui::asyncAuthResult(OAuth::Result r, const QString &user,
const QString &token, const QString &refreshToken)
{
switch (r) {
case OAuth::NotSupported:
// We will re-enter the event loop, so better wait the next iteration
QMetaObject::invokeMethod(this, "showDialog", Qt::QueuedConnection);
_asyncAuth.reset(0);
return;
case OAuth::Error:
_asyncAuth.reset(0);
emit asked();
return;
case OAuth::LoggedIn:
break;
}
if (_user != user) {
QMessageBox::warning(nullptr, tr("Login Error"), tr("You must sign in as user %1").arg(_user));
_asyncAuth->openBrowser();
return;
}
_password = token;
_refreshToken = refreshToken;
_ready = true;
persist();
_asyncAuth.reset(0);
emit asked();
}
void HttpCredentialsGui::showDialog()
{
QString msg = tr("Please enter %1 password:<br>"
"<br>"
@ -87,6 +142,4 @@ QString HttpCredentialsGui::requestAppPasswordText(const Account *account)
return tr("<a href=\"%1\">Click here</a> to request an app password from the web interface.")
.arg(account->url().toString() + path);
}
} // namespace OCC

View File

@ -15,6 +15,9 @@
#pragma once
#include "creds/httpcredentials.h"
#include "creds/oauth.h"
#include <QPointer>
#include <QTcpServer>
namespace OCC {
@ -34,10 +37,26 @@ public:
: HttpCredentials(user, password, certificate, key)
{
}
void askFromUser() Q_DECL_OVERRIDE;
Q_INVOKABLE void askFromUserAsync();
HttpCredentialsGui(const QString &user, const QString &password, const QString &refreshToken,
const QSslCertificate &certificate, const QSslKey &key)
: HttpCredentials(user, password, certificate, key)
{
_refreshToken = refreshToken;
}
/**
* This will query the server and either uses OAuth via _asyncAuth->start()
* or call showDialog to ask the password
*/
Q_INVOKABLE void askFromUser() Q_DECL_OVERRIDE;
static QString requestAppPasswordText(const Account *account);
private slots:
void asyncAuthResult(OAuth::Result, const QString &user, const QString &accessToken, const QString &refreshToken);
void showDialog();
private:
QScopedPointer<OAuth, QScopedPointerObjectDeleteLater<OAuth>> _asyncAuth;
};
} // namespace OCC

123
src/gui/creds/oauth.cpp Normal file
View File

@ -0,0 +1,123 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <QDesktopServices>
#include <QNetworkReply>
#include <QTimer>
#include "account.h"
#include "creds/oauth.h"
#include <QJsonObject>
#include <QJsonDocument>
#include "theme.h"
namespace OCC {
Q_LOGGING_CATEGORY(lcOauth, "sync.credentials.oauth", QtInfoMsg)
OAuth::~OAuth()
{
}
static void httpReplyAndClose(QTcpSocket *socket, const char *code, const char *html)
{
socket->write("HTTP/1.1 ");
socket->write(code);
socket->write("\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: ");
socket->write(QByteArray::number(qstrlen(html)));
socket->write("\r\n\r\n");
socket->write(html);
socket->disconnectFromHost();
}
void OAuth::start()
{
// Listen on the socket to get a port which will be used in the redirect_uri
if (!_server.listen(QHostAddress::LocalHost)) {
emit result(NotSupported, QString());
return;
}
if (!openBrowser())
return;
QObject::connect(&_server, &QTcpServer::newConnection, this, [this] {
while (QTcpSocket *socket = _server.nextPendingConnection()) {
QObject::connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
QObject::connect(socket, &QIODevice::readyRead, this, [this, socket] {
QByteArray peek = socket->peek(qMin(socket->bytesAvailable(), 4000LL)); //The code should always be within the first 4K
if (peek.indexOf('\n') < 0)
return; // wait until we find a \n
QRegExp rx("^GET /\\?code=([a-zA-Z0-9]+)[& ]"); // Match a /?code=... URL
if (rx.indexIn(peek) != 0) {
httpReplyAndClose(socket, "404 Not Found", "<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center></body></html>");
return;
}
// TODO: add redirect to the page on the server
httpReplyAndClose(socket, "200 OK", "<h1>Login Successful</h1><p>You can close this window.</p>");
QString code = rx.cap(1); // The 'code' is the first capture of the regexp
QUrl requestToken(_account->url().toString()
+ QLatin1String("/index.php/apps/oauth2/api/v1/token?grant_type=authorization_code&code=")
+ code
+ QLatin1String("&redirect_uri=http://localhost:") + QString::number(_server.serverPort()));
requestToken.setUserName(Theme::instance()->oauthClientId());
requestToken.setPassword(Theme::instance()->oauthClientSecret());
QNetworkRequest req;
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
auto reply = _account->sendRequest("POST", requestToken, req);
QTimer::singleShot(30 * 1000, reply, &QNetworkReply::abort);
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply] {
auto jsonData = reply->readAll();
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
QString accessToken = json["access_token"].toString();
QString refreshToken = json["refresh_token"].toString();
QString user = json["user_id"].toString();
if (reply->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError
|| json.isEmpty() || refreshToken.isEmpty() || accessToken.isEmpty()
|| json["token_type"].toString() != QLatin1String("Bearer")) {
qCWarning(lcOauth) << "Error when getting the accessToken" << reply->error() << json << jsonParseError.errorString();
emit result(Error);
return;
}
emit result(LoggedIn, user, accessToken, refreshToken);
});
});
}
});
QTimer::singleShot(5 * 60 * 1000, this, [this] { result(Error); });
}
bool OAuth::openBrowser()
{
Q_ASSERT(_server.isListening());
auto url = QUrl(_account->url().toString()
+ QLatin1String("/index.php/apps/oauth2/authorize?response_type=code&client_id=")
+ Theme::instance()->oauthClientId()
+ QLatin1String("&redirect_uri=http://localhost:") + QString::number(_server.serverPort()));
if (!QDesktopServices::openUrl(url)) {
// We cannot open the browser, then we claim we don't support OAuth.
emit result(NotSupported, QString());
return false;
}
return true;
}
} // namespace OCC

70
src/gui/creds/oauth.h Normal file
View File

@ -0,0 +1,70 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#pragma once
#include <QPointer>
#include <QTcpServer>
namespace OCC {
/**
* Job that do the authorization grant and fetch the access token
*
* Normal workflow:
*
* --> start()
* |
* +----> openBrowser() open the browser to the login page, redirects to http://localhost:xxx
* |
* +----> _server starts listening on a TCP port waiting for an HTTP request with a 'code'
* |
* v
* request the access_token and the refresh_token via 'apps/oauth2/api/v1/token'
* |
* v
* emit result(...)
*
*/
class OAuth : public QObject
{
Q_OBJECT
public:
OAuth(Account *account, QObject *parent)
: QObject(parent)
, _account(account)
{
}
~OAuth();
enum Result { NotSupported,
LoggedIn,
Error };
Q_ENUM(Result);
void start();
bool openBrowser();
signals:
/**
* The state has changed.
* when logged in, token has the value of the token.
*/
void result(OAuth::Result result, const QString &user = QString(), const QString &token = QString(), const QString &refreshToken = QString());
private:
Account *_account;
QTcpServer _server;
};
} // namespace OCC

View File

@ -1034,7 +1034,7 @@ QString FolderDefinition::absoluteJournalPath() const
QString FolderDefinition::defaultJournalPath(AccountPtr account)
{
return SyncJournalDb::makeDbName(account->url(), targetPath, account->credentials()->user());
return SyncJournalDb::makeDbName(localPath, account->url(), targetPath, account->credentials()->user());
}
} // namespace OCC

View File

@ -239,11 +239,22 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account,
foreach (const auto &folderAlias, settings.childGroups()) {
FolderDefinition folderDefinition;
if (FolderDefinition::load(settings, folderAlias, &folderDefinition)) {
auto defaultJournalPath = folderDefinition.defaultJournalPath(account->account());
// Migration: Old settings don't have journalPath
if (folderDefinition.journalPath.isEmpty()) {
folderDefinition.journalPath = folderDefinition.defaultJournalPath(account->account());
folderDefinition.journalPath = defaultJournalPath;
}
folderDefinition.defaultJournalPath(account->account());
// Migration: ._ files sometimes don't work
// So if the configured journalPath is the default one ("._sync_*.db")
// but the current default doesn't have the underscore, switch to the
// new default. See SyncJournalDb::makeDbName().
if (folderDefinition.journalPath.startsWith("._sync_")
&& defaultJournalPath.startsWith(".sync_")) {
folderDefinition.journalPath = defaultJournalPath;
}
// Migration: If an old db is found, move it to the new name.
if (backwardsCompatible) {
SyncJournalDb::maybeMigrateDb(folderDefinition.localPath, folderDefinition.absoluteJournalPath());

View File

@ -614,6 +614,8 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
if (!parentInfo) {
return;
}
ASSERT(parentInfo->_fetching); // we should only get a result if we were doing a fetch
ASSERT(parentInfo->_subs.isEmpty());
if (parentInfo->hasLabel()) {
beginRemoveRows(idx, 0, 0);
@ -712,9 +714,11 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
newSubs.append(newInfo);
}
beginInsertRows(idx, 0, newSubs.size() - 1);
parentInfo->_subs = std::move(newSubs);
endInsertRows();
if (!newSubs.isEmpty()) {
beginInsertRows(idx, 0, newSubs.size() - 1);
parentInfo->_subs = std::move(newSubs);
endInsertRows();
}
for (auto it = undecidedIndexes.begin(); it != undecidedIndexes.end(); ++it) {
suggestExpand(idx.child(*it, 0));

View File

@ -160,7 +160,10 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
// Fire event for the path that was changed.
if (event->len > 0 && event->wd > -1) {
QByteArray fileName(event->name);
if (fileName.startsWith("._sync_") || fileName.startsWith(".csync_journal.db") || fileName.startsWith(".owncloudsync.log")) {
if (fileName.startsWith("._sync_")
|| fileName.startsWith(".csync_journal.db")
|| fileName.startsWith(".owncloudsync.log")
|| fileName.startsWith(".sync_")) {
} else {
const QString p = _watches[event->wd] + '/' + fileName;
_parent->changeDetected(p);

View File

@ -152,6 +152,12 @@
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="aboutLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>About</string>
</property>

View File

@ -48,6 +48,9 @@ IgnoreListEditor::IgnoreListEditor(QWidget *parent)
"and cannot be modified in this view.")
.arg(QDir::toNativeSeparators(cfgFile.excludeFile(ConfigFile::SystemScope)));
addPattern(".csync_journal.db*", /*deletable=*/false, /*readonly=*/true);
addPattern("._sync_*.db*", /*deletable=*/false, /*readonly=*/true);
addPattern(".sync_*.db*", /*deletable=*/false, /*readonly=*/true);
readIgnoreFile(cfgFile.excludeFile(ConfigFile::SystemScope), true);
readIgnoreFile(cfgFile.excludeFile(ConfigFile::UserScope), false);

View File

@ -871,6 +871,7 @@ void ownCloudGui::slotDisplayIdle()
void ownCloudGui::slotLogin()
{
if (auto account = qvariant_cast<AccountStatePtr>(sender()->property(propertyAccountC))) {
account->account()->resetRejectedCertificates();
account->signIn();
} else {
auto list = AccountManager::instance()->accounts();

View File

@ -346,7 +346,7 @@ void OwncloudSetupWizard::slotAuthError()
}
_ocWizard->show();
if (_ocWizard->currentId() == WizardCommon::Page_ShibbolethCreds) {
if (_ocWizard->currentId() == WizardCommon::Page_ShibbolethCreds || _ocWizard->currentId() == WizardCommon::Page_OAuthCreds) {
_ocWizard->back();
}
_ocWizard->displayError(errorMsg, _ocWizard->currentId() == WizardCommon::Page_ServerSetup && checkDowngradeAdvised(reply));
@ -625,7 +625,11 @@ bool DetermineAuthTypeJob::finished()
redirection.clear();
}
if ((reply()->error() == QNetworkReply::AuthenticationRequiredError) || redirection.isEmpty()) {
emit authType(WizardCommon::HttpCreds);
if (reply()->rawHeader("WWW-Authenticate").contains("Bearer ")) {
emit authType(WizardCommon::OAuth);
} else {
emit authType(WizardCommon::HttpCreds);
}
} else if (redirection.toString().endsWith(account()->davPath())) {
// do a new run
_redirects++;

View File

@ -14,6 +14,7 @@
#include "systray.h"
#include "theme.h"
#include "config.h"
#ifdef USE_FDO_NOTIFICATIONS
#include <QDBusConnection>
@ -30,8 +31,8 @@ namespace OCC {
void Systray::showMessage(const QString &title, const QString &message, MessageIcon icon, int millisecondsTimeoutHint)
{
#ifdef USE_FDO_NOTIFICATIONS
if (QDBusInterface(NOTIFICATIONS_SERVICE, NOTIFICATIONS_PATH, NOTIFICATIONS_IFACE).isValid()) {
QList<QVariant> args = QList<QVariant>() << "owncloud" << quint32(0) << "owncloud"
if(QDBusInterface(NOTIFICATIONS_SERVICE, NOTIFICATIONS_PATH, NOTIFICATIONS_IFACE).isValid()) {
QList<QVariant> args = QList<QVariant>() << APPLICATION_NAME << quint32(0) << APPLICATION_ICON_NAME
<< title << message << QStringList() << QVariantMap() << qint32(-1);
QDBusMessage method = QDBusMessage::createMethodCall(NOTIFICATIONS_SERVICE, NOTIFICATIONS_PATH, NOTIFICATIONS_IFACE, "Notify");
method.setArguments(args);

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <QVariant>
#include "wizard/owncloudoauthcredspage.h"
#include "theme.h"
#include "account.h"
#include "cookiejar.h"
#include "wizard/owncloudwizardcommon.h"
#include "wizard/owncloudwizard.h"
#include "creds/httpcredentialsgui.h"
#include "creds/credentialsfactory.h"
namespace OCC {
OwncloudOAuthCredsPage::OwncloudOAuthCredsPage()
: AbstractCredentialsWizardPage()
{
_ui.setupUi(this);
Theme *theme = Theme::instance();
_ui.topLabel->hide();
_ui.bottomLabel->hide();
QVariant variant = theme->customMedia(Theme::oCSetupTop);
WizardCommon::setupCustomMedia(variant, _ui.topLabel);
variant = theme->customMedia(Theme::oCSetupBottom);
WizardCommon::setupCustomMedia(variant, _ui.bottomLabel);
WizardCommon::initErrorLabel(_ui.errorLabel);
setTitle(WizardCommon::titleTemplate().arg(tr("Connect to %1").arg(Theme::instance()->appNameGUI())));
setSubTitle(WizardCommon::subTitleTemplate().arg(tr("Login in your browser")));
connect(_ui.openLinkButton, &QCommandLinkButton::clicked, [this] {
_ui.errorLabel->hide();
if (_asyncAuth)
_asyncAuth->openBrowser();
});
}
void OwncloudOAuthCredsPage::initializePage()
{
OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard);
ocWizard->account()->setCredentials(CredentialsFactory::create("http"));
_asyncAuth.reset(new OAuth(ocWizard->account().data(), this));
connect(_asyncAuth.data(), &OAuth::result, this, &OwncloudOAuthCredsPage::asyncAuthResult, Qt::QueuedConnection);
_asyncAuth->start();
wizard()->hide();
}
void OCC::OwncloudOAuthCredsPage::cleanupPage()
{
// The next or back button was activated, show the wizard again
wizard()->show();
_asyncAuth.reset();
}
void OwncloudOAuthCredsPage::asyncAuthResult(OAuth::Result r, const QString &user,
const QString &token, const QString &refreshToken)
{
switch (r) {
case OAuth::NotSupported: {
/* OAuth not supported (can't open browser), fallback to HTTP credentials */
OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
ocWizard->back();
ocWizard->setAuthType(WizardCommon::HttpCreds);
break;
}
case OAuth::Error:
/* Error while getting the access token. (Timeout, or the server did not accept our client credentials */
_ui.errorLabel->show();
wizard()->show();
break;
case OAuth::LoggedIn: {
_token = token;
_user = user;
_refreshToken = refreshToken;
OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard);
emit connectToOCUrl(ocWizard->account()->url().toString());
break;
}
}
}
int OwncloudOAuthCredsPage::nextId() const
{
return WizardCommon::Page_AdvancedSetup;
}
void OwncloudOAuthCredsPage::setConnected()
{
wizard()->show();
}
AbstractCredentials *OwncloudOAuthCredsPage::getCredentials() const
{
OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard);
return new HttpCredentialsGui(_user, _token, _refreshToken,
ocWizard->_clientSslCertificate, ocWizard->_clientSslKey);
}
bool OwncloudOAuthCredsPage::isComplete() const
{
return false; /* We can never go forward manually */
}
} // namespace OCC

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#pragma once
#include <QList>
#include <QMap>
#include <QNetworkCookie>
#include <QUrl>
#include <QPointer>
#include "wizard/abstractcredswizardpage.h"
#include "accountfwd.h"
#include "creds/oauth.h"
#include "ui_owncloudoauthcredspage.h"
namespace OCC {
class OwncloudOAuthCredsPage : public AbstractCredentialsWizardPage
{
Q_OBJECT
public:
OwncloudOAuthCredsPage();
AbstractCredentials *getCredentials() const Q_DECL_OVERRIDE;
void initializePage() Q_DECL_OVERRIDE;
void cleanupPage() override;
int nextId() const Q_DECL_OVERRIDE;
void setConnected();
bool isComplete() const override;
public Q_SLOTS:
void asyncAuthResult(OAuth::Result, const QString &user, const QString &token,
const QString &reniewToken);
signals:
void connectToOCUrl(const QString &);
public:
QString _user;
QString _token;
QString _refreshToken;
QScopedPointer<OAuth> _asyncAuth;
Ui_OwncloudOAuthCredsPage _ui;
};
} // namespace OCC

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OwncloudOAuthCredsPage</class>
<widget class="QWidget" name="OwncloudOAuthCredsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>424</width>
<height>373</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="topLabel">
<property name="text">
<string notr="true">TextLabel</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Please switch to your browser to proceed.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="errorLabel">
<property name="text">
<string>An error occured while connecting. Please try again.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="openLinkButton">
<property name="text">
<string>Re-open Browser</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>127</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="bottomLabel">
<property name="text">
<string notr="true">TextLabel</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -203,6 +203,8 @@ int OwncloudSetupPage::nextId() const
{
if (_authType == WizardCommon::HttpCreds) {
return WizardCommon::Page_HttpCreds;
} else if (_authType == WizardCommon::OAuth) {
return WizardCommon::Page_OAuthCreds;
} else {
return WizardCommon::Page_ShibbolethCreds;
}

View File

@ -20,6 +20,7 @@
#include "wizard/owncloudwizard.h"
#include "wizard/owncloudsetuppage.h"
#include "wizard/owncloudhttpcredspage.h"
#include "wizard/owncloudoauthcredspage.h"
#ifndef NO_SHIBBOLETH
#include "wizard/owncloudshibbolethcredspage.h"
#endif
@ -42,12 +43,11 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
, _account(0)
, _setupPage(new OwncloudSetupPage(this))
, _httpCredsPage(new OwncloudHttpCredsPage(this))
,
, _browserCredsPage(new OwncloudOAuthCredsPage)
#ifndef NO_SHIBBOLETH
_shibbolethCredsPage(new OwncloudShibbolethCredsPage)
,
, _shibbolethCredsPage(new OwncloudShibbolethCredsPage)
#endif
_advancedSetupPage(new OwncloudAdvancedSetupPage)
, _advancedSetupPage(new OwncloudAdvancedSetupPage)
, _resultPage(new OwncloudWizardResultPage)
, _credentialsPage(0)
, _setupLog()
@ -55,6 +55,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setPage(WizardCommon::Page_ServerSetup, _setupPage);
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
setPage(WizardCommon::Page_OAuthCreds, _browserCredsPage);
#ifndef NO_SHIBBOLETH
setPage(WizardCommon::Page_ShibbolethCreds, _shibbolethCredsPage);
#endif
@ -70,6 +71,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
connect(this, SIGNAL(currentIdChanged(int)), SLOT(slotCurrentPageChanged(int)));
connect(_setupPage, SIGNAL(determineAuthType(QString)), SIGNAL(determineAuthType(QString)));
connect(_httpCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
connect(_browserCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
#ifndef NO_SHIBBOLETH
connect(_shibbolethCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
#endif
@ -142,6 +144,10 @@ void OwncloudWizard::successfulStep()
_httpCredsPage->setConnected();
break;
case WizardCommon::Page_OAuthCreds:
_browserCredsPage->setConnected();
break;
#ifndef NO_SHIBBOLETH
case WizardCommon::Page_ShibbolethCreds:
_shibbolethCredsPage->setConnected();
@ -169,7 +175,9 @@ void OwncloudWizard::setAuthType(WizardCommon::AuthType type)
_credentialsPage = _shibbolethCredsPage;
} else
#endif
{
if (type == WizardCommon::OAuth) {
_credentialsPage = _browserCredsPage;
} else {
_credentialsPage = _httpCredsPage;
}
next();
@ -193,6 +201,11 @@ void OwncloudWizard::slotCurrentPageChanged(int id)
}
setOption(QWizard::HaveCustomButton1, id == WizardCommon::Page_AdvancedSetup);
if (id == WizardCommon::Page_AdvancedSetup && _credentialsPage == _browserCredsPage) {
// For OAuth, disable the back button in the Page_AdvancedSetup because we don't want
// to re-open the browser.
button(QWizard::BackButton)->setEnabled(false);
}
}
void OwncloudWizard::displayError(const QString &msg, bool retryHTTPonly)

View File

@ -30,6 +30,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcWizard)
class OwncloudSetupPage;
class OwncloudHttpCredsPage;
class OwncloudOAuthCredsPage;
#ifndef NO_SHIBBOLETH
class OwncloudShibbolethCredsPage;
#endif
@ -94,6 +95,7 @@ private:
AccountPtr _account;
OwncloudSetupPage *_setupPage;
OwncloudHttpCredsPage *_httpCredsPage;
OwncloudOAuthCredsPage *_browserCredsPage;
#ifndef NO_SHIBBOLETH
OwncloudShibbolethCredsPage *_shibbolethCredsPage;
#endif
@ -102,6 +104,8 @@ private:
AbstractCredentialsWizardPage *_credentialsPage;
QStringList _setupLog;
friend class OwncloudSetupWizard;
};
} // namespace OCC

View File

@ -30,7 +30,8 @@ namespace WizardCommon {
enum AuthType {
HttpCreds,
Shibboleth
Shibboleth,
OAuth
};
enum SyncMode {
@ -42,6 +43,7 @@ namespace WizardCommon {
Page_ServerSetup,
Page_HttpCreds,
Page_ShibbolethCreds,
Page_OAuthCreds,
Page_AdvancedSetup,
Page_Result
};

View File

@ -9,7 +9,6 @@ include_directories(${CMAKE_SOURCE_DIR}/csync/src
${CMAKE_BINARY_DIR}/csync
${CMAKE_BINARY_DIR}/csync/src
)
include_directories(${OPENSSL_INCLUDE_DIR})
if ( APPLE )
list(APPEND OS_SPECIFIC_LINK_LIBRARIES
@ -108,7 +107,6 @@ list(APPEND libsync_LINK_TARGETS
${QT_LIBRARIES}
ocsync
${OS_SPECIFIC_LINK_LIBRARIES}
${OPENSSL_LIBRARIES}
)
if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND)

View File

@ -152,10 +152,12 @@ void AbstractNetworkJob::slotFinished()
}
if (_reply->error() != QNetworkReply::NoError) {
qCWarning(lcNetworkJob) << _reply->error() << errorString()
<< _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (_reply->error() == QNetworkReply::ProxyAuthenticationRequiredError) {
qCWarning(lcNetworkJob) << _reply->rawHeader("Proxy-Authenticate");
if (!_ignoreCredentialFailure || _reply->error() != QNetworkReply::AuthenticationRequiredError) {
qCWarning(lcNetworkJob) << _reply->error() << errorString()
<< _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (_reply->error() == QNetworkReply::ProxyAuthenticationRequiredError) {
qCWarning(lcNetworkJob) << _reply->rawHeader("Proxy-Authenticate");
}
}
emit networkError(_reply);
}

View File

@ -81,6 +81,8 @@ Q_LOGGING_CATEGORY(lcChecksums, "sync.checksums", QtInfoMsg)
QByteArray makeChecksumHeader(const QByteArray &checksumType, const QByteArray &checksum)
{
if (checksumType.isEmpty() || checksum.isEmpty())
return QByteArray();
QByteArray header = checksumType;
header.append(':');
header.append(checksum);
@ -105,6 +107,16 @@ bool parseChecksumHeader(const QByteArray &header, QByteArray *type, QByteArray
return true;
}
QByteArray parseChecksumHeaderType(const QByteArray &header)
{
const auto idx = header.indexOf(':');
if (idx < 0) {
return QByteArray();
}
return header.left(idx);
}
bool uploadChecksumEnabled()
{
static bool enabled = qgetenv("OWNCLOUD_DISABLE_CHECKSUM_UPLOAD").isEmpty();
@ -214,39 +226,27 @@ void ValidateChecksumHeader::slotChecksumCalculated(const QByteArray &checksumTy
emit validated(checksumType, checksum);
}
CSyncChecksumHook::CSyncChecksumHook(SyncJournalDb *journal)
: _journal(journal)
CSyncChecksumHook::CSyncChecksumHook()
{
}
const char *CSyncChecksumHook::hook(const char *path, uint32_t checksumTypeId, void *this_obj)
const char *CSyncChecksumHook::hook(const char *path, const char *otherChecksumHeader, void * /*this_obj*/)
{
CSyncChecksumHook *checksumHook = static_cast<CSyncChecksumHook *>(this_obj);
QByteArray checksum = checksumHook->compute(QString::fromUtf8(path), checksumTypeId);
QByteArray type = parseChecksumHeaderType(QByteArray(otherChecksumHeader));
if (type.isEmpty())
return NULL;
QByteArray checksum = ComputeChecksum::computeNow(path, type);
if (checksum.isNull()) {
qCWarning(lcChecksums) << "Failed to compute checksum" << type << "for" << path;
return NULL;
}
char *result = (char *)malloc(checksum.size() + 1);
memcpy(result, checksum.constData(), checksum.size());
result[checksum.size()] = 0;
QByteArray checksumHeader = makeChecksumHeader(type, checksum);
char *result = (char *)malloc(checksumHeader.size() + 1);
memcpy(result, checksumHeader.constData(), checksumHeader.size());
result[checksumHeader.size()] = 0;
return result;
}
QByteArray CSyncChecksumHook::compute(const QString &path, int checksumTypeId)
{
QByteArray checksumType = _journal->getChecksumType(checksumTypeId);
if (checksumType.isEmpty()) {
qCWarning(lcChecksums) << "Checksum type" << checksumTypeId << "not found";
return QByteArray();
}
QByteArray checksum = ComputeChecksum::computeNow(path, checksumType);
if (checksum.isNull()) {
qCWarning(lcChecksums) << "Failed to compute checksum" << checksumType << "for" << path;
return QByteArray();
}
return checksum;
}
}

View File

@ -31,6 +31,9 @@ QByteArray makeChecksumHeader(const QByteArray &checksumType, const QByteArray &
/// Parses a checksum header
bool parseChecksumHeader(const QByteArray &header, QByteArray *type, QByteArray *checksum);
/// Convenience for getting the type from a checksum header, null if none
QByteArray parseChecksumHeaderType(const QByteArray &header);
/// Checks OWNCLOUD_DISABLE_CHECKSUM_UPLOAD
bool uploadChecksumEnabled();
@ -119,20 +122,15 @@ class OWNCLOUDSYNC_EXPORT CSyncChecksumHook : public QObject
{
Q_OBJECT
public:
explicit CSyncChecksumHook(SyncJournalDb *journal);
explicit CSyncChecksumHook();
/**
* Returns the checksum value for \a path for the given \a checksumTypeId.
* Returns the checksum value for \a path that is comparable to \a otherChecksum.
*
* Called from csync, where a instance of CSyncChecksumHook has
* to be set as userdata.
* The return value will be owned by csync.
*/
static const char *hook(const char *path, uint32_t checksumTypeId, void *this_obj);
QByteArray compute(const QString &path, int checksumTypeId);
private:
SyncJournalDb *_journal;
static const char *hook(const char *path, const char *otherChecksumHeader, void *this_obj);
};
}

View File

@ -139,7 +139,9 @@ void ConnectionValidator::slotStatusFound(const QUrl &url, const QJsonObject &in
return;
}
if (info["maintenance"].toBool()) {
// Check for maintenance mode: Servers send "true", so go through QVariant
// to parse it correctly.
if (info["maintenance"].toVariant().toBool()) {
reportResult(MaintenanceMode);
return;
}

View File

@ -18,6 +18,8 @@
#include <QNetworkReply>
#include <QSettings>
#include <QSslKey>
#include <QJsonObject>
#include <QJsonDocument>
#include <keychain.h>
@ -37,6 +39,7 @@ Q_LOGGING_CATEGORY(lcHttpCredentials, "sync.credentials.http", QtInfoMsg)
namespace {
const char userC[] = "user";
const char isOAuthC[] = "oauth";
const char clientCertificatePEMC[] = "_clientCertificatePEM";
const char clientKeyPEMC[] = "_clientKeyPEM";
const char authenticationFailedC[] = "owncloud-authentication-failed";
@ -54,9 +57,20 @@ public:
protected:
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) Q_DECL_OVERRIDE
{
QByteArray credHash = QByteArray(_cred->user().toUtf8() + ":" + _cred->password().toUtf8()).toBase64();
QNetworkRequest req(request);
req.setRawHeader(QByteArray("Authorization"), QByteArray("Basic ") + credHash);
if (!_cred->password().isEmpty()) {
if (_cred->isUsingOAuth()) {
req.setRawHeader("Authorization", "Bearer " + _cred->password().toUtf8());
} else {
QByteArray credHash = QByteArray(_cred->user().toUtf8() + ":" + _cred->password().toUtf8()).toBase64();
req.setRawHeader("Authorization", "Basic " + credHash);
}
} else if (!request.url().password().isEmpty()) {
// Typically the requests to get or refresh the OAuth access token. The client
// credentials are put in the URL from the code making the request.
QByteArray credHash = request.url().userInfo().toUtf8().toBase64();
req.setRawHeader("Authorization", "Basic " + credHash);
}
if (!_cred->_clientSslKey.isNull() && !_cred->_clientSslCertificate.isNull()) {
// SSL configuration
@ -149,6 +163,13 @@ void HttpCredentials::fetchFromKeychain()
// User must be fetched from config file
fetchUser();
if (!_ready && !_refreshToken.isEmpty()) {
// This happens if the credentials are still loaded from the keychain, bur we are called
// here because the auth is invalid, so this means we simply need to refresh the credentials
refreshAccessToken();
return;
}
const QString kck = keychainKey(_account->url().toString(), _user);
if (_ready) {
@ -160,7 +181,6 @@ void HttpCredentials::fetchFromKeychain()
addSettingsToJob(_account, job);
job->setInsecureFallback(false);
job->setKey(kck);
qCDebug(lcHttpCredentials) << "-------- ----->" << _clientSslCertificate << _clientSslKey;
connect(job, SIGNAL(finished(QKeychain::Job *)), SLOT(slotReadClientCertPEMJobDone(QKeychain::Job *)));
job->start();
@ -236,7 +256,13 @@ bool HttpCredentials::stillValid(QNetworkReply *reply)
void HttpCredentials::slotReadJobDone(QKeychain::Job *incomingJob)
{
QKeychain::ReadPasswordJob *job = static_cast<ReadPasswordJob *>(incomingJob);
_password = job->textData();
bool isOauth = _account->credentialSetting(QLatin1String(isOAuthC)).toBool();
if (isOauth) {
_refreshToken = job->textData();
} else {
_password = job->textData();
}
if (_user.isEmpty()) {
qCWarning(lcHttpCredentials) << "Strange: User is empty!";
@ -244,7 +270,9 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *incomingJob)
QKeychain::Error error = job->error();
if (!_password.isEmpty() && error == NoError) {
if (!_refreshToken.isEmpty() && error == NoError) {
refreshAccessToken();
} else if (!_password.isEmpty() && error == NoError) {
// All cool, the keychain did not come back with error.
// Still, the password can be empty which indicates a problem and
// the password dialog has to be opened.
@ -262,6 +290,41 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *incomingJob)
}
}
void HttpCredentials::refreshAccessToken()
{
QUrl requestToken(_account->url().toString()
+ QLatin1String("/index.php/apps/oauth2/api/v1/token?grant_type=refresh_token&refresh_token=")
+ _refreshToken);
requestToken.setUserName(Theme::instance()->oauthClientId());
requestToken.setPassword(Theme::instance()->oauthClientSecret());
QNetworkRequest req;
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
auto reply = _account->sendRequest("POST", requestToken, req);
QTimer::singleShot(30 * 1000, reply, &QNetworkReply::abort);
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply] {
reply->deleteLater();
auto jsonData = reply->readAll();
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
QString accessToken = json["access_token"].toString();
if (reply->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError || json.isEmpty()) {
// Network error maybe?
qCWarning(lcHttpCredentials) << "Error while refreshing the token" << reply->errorString() << jsonData << jsonParseError.errorString();
} else if (accessToken.isEmpty()) {
// The token is no longer valid.
qCDebug(lcHttpCredentials) << "Expired refresh token. Logging out";
_refreshToken.clear();
} else {
_ready = true;
_password = accessToken;
_refreshToken = json["refresh_token"].toString();
persist();
}
emit fetched();
});
}
void HttpCredentials::invalidateToken()
{
if (!_password.isEmpty()) {
@ -279,6 +342,12 @@ void HttpCredentials::invalidateToken()
return;
}
if (!_refreshToken.isEmpty()) {
// Only invalidate the access_token (_password) but keep the _refreshToken in the keychain
// (when coming from forgetSensitiveData, the _refreshToken is cleared)
return;
}
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
addSettingsToJob(_account, job);
job->setInsecureFallback(true);
@ -315,6 +384,9 @@ void HttpCredentials::clearQNAMCache()
void HttpCredentials::forgetSensitiveData()
{
// need to be done before invalidateToken, so it actually deletes the refresh_token from the keychain
_refreshToken.clear();
invalidateToken();
_previousPassword.clear();
}
@ -327,6 +399,7 @@ void HttpCredentials::persist()
}
_account->setCredentialSetting(QLatin1String(userC), _user);
_account->setCredentialSetting(QLatin1String(isOAuthC), isUsingOAuth());
// write cert
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
@ -359,7 +432,7 @@ void HttpCredentials::slotWriteClientKeyPEMJobDone(Job *incomingJob)
job->setInsecureFallback(false);
connect(job, SIGNAL(finished(QKeychain::Job *)), SLOT(slotWriteJobDone(QKeychain::Job *)));
job->setKey(keychainKey(_account->url().toString(), _user));
job->setTextData(_password);
job->setTextData(isUsingOAuth() ? _refreshToken : _password);
job->start();
}
@ -378,6 +451,8 @@ void HttpCredentials::slotWriteJobDone(QKeychain::Job *job)
void HttpCredentials::slotAuthentication(QNetworkReply *reply, QAuthenticator *authenticator)
{
if (!_ready)
return;
Q_UNUSED(authenticator)
// Because of issue #4326, we need to set the login and password manually at every requests
// Thus, if we reach this signal, those credentials were invalid and we terminate.

View File

@ -32,6 +32,43 @@ class ReadPasswordJob;
namespace OCC {
/*
The authentication system is this way because of Shibboleth.
There used to be two different ways to authenticate: Shibboleth and HTTP Basic Auth.
AbstractCredentials can be inherited from both ShibbolethCrendentials and HttpCredentials.
HttpCredentials is then split in HttpCredentials and HttpCredentialsGui.
This class handle both HTTP Basic Auth and OAuth. But anything that needs GUI to ask the user
is in HttpCredentialsGui.
The authentication mechanism looks like this.
1) First, AccountState will attempt to load the certificate from the keychain
----> fetchFromKeychain ------------------------> shortcut to refreshAccessToken if the cached
| } information is still valid
v }
slotReadClientCertPEMJobDone } There are first 3 QtKeychain jobs to fetch
| } the TLS client keys, if any, and the password
v } (or refresh token
slotReadClientKeyPEMJobDone }
| }
v
slotReadJobDone
| |
| +-------> emit fetched() if OAuth is not used
|
v
refreshAccessToken()
|
v
emit fetched()
2) If the credentials is still not valid when fetched() is emitted, the ui, will call askFromUser()
which is implemented in HttpCredentialsGui
*/
class OWNCLOUDSYNC_EXPORT HttpCredentials : public AbstractCredentials
{
Q_OBJECT
@ -48,15 +85,21 @@ public:
bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE;
void persist() Q_DECL_OVERRIDE;
QString user() const Q_DECL_OVERRIDE;
// the password or token
QString password() const;
void invalidateToken() Q_DECL_OVERRIDE;
void forgetSensitiveData() Q_DECL_OVERRIDE;
QString fetchUser();
virtual bool sslIsTrusted() { return false; }
void refreshAccessToken();
// To fetch the user name as early as possible
void setAccount(Account *account) Q_DECL_OVERRIDE;
// Whether we are using OAuth
bool isUsingOAuth() const { return !_refreshToken.isNull(); }
private Q_SLOTS:
void slotAuthentication(QNetworkReply *, QAuthenticator *);
@ -71,7 +114,8 @@ private Q_SLOTS:
protected:
QString _user;
QString _password;
QString _password; // user's password, or access_token for OAuth
QString _refreshToken; // OAuth _refreshToken, set if OAuth is used.
QString _previousPassword;
QString _fetchErrorString;
@ -80,6 +124,7 @@ protected:
QSslCertificate _clientSslCertificate;
};
} // namespace OCC
#endif

View File

@ -272,7 +272,8 @@ void DiscoverySingleDirectoryJob::start()
<< "http://owncloud.org/ns:id"
<< "http://owncloud.org/ns:downloadURL"
<< "http://owncloud.org/ns:dDC"
<< "http://owncloud.org/ns:permissions";
<< "http://owncloud.org/ns:permissions"
<< "http://owncloud.org/ns:checksums";
if (_isRootPath)
props << "http://owncloud.org/ns:data-fingerprint";
@ -294,6 +295,28 @@ void DiscoverySingleDirectoryJob::abort()
}
}
/**
* Returns the highest-quality checksum in a 'checksums'
* property retrieved from the server.
*
* Example: "ADLER32:1231 SHA1:ab124124 MD5:2131affa21"
* -> "SHA1:ab124124"
*/
static QByteArray findBestChecksum(const QByteArray &checksums)
{
int i = 0;
// The order of the searches here defines the preference ordering.
if (-1 != (i = checksums.indexOf("SHA1:"))
|| -1 != (i = checksums.indexOf("MD5:"))
|| -1 != (i = checksums.indexOf("Adler32:"))) {
// Now i is the start of the best checksum
// Grab it until the next space or end of string.
auto checksum = checksums.mid(i);
return checksum.mid(0, checksum.indexOf(" "));
}
return QByteArray();
}
static csync_vio_file_stat_t *propertyMapToFileStat(const QMap<QString, QString> &map)
{
csync_vio_file_stat_t *file_stat = csync_vio_file_stat_new();
@ -343,6 +366,11 @@ static csync_vio_file_stat_t *propertyMapToFileStat(const QMap<QString, QString>
} else {
qCWarning(lcDiscovery) << "permissions too large" << v;
}
} else if (property == "checksums") {
QByteArray checksum = findBestChecksum(value.toUtf8());
if (!checksum.isEmpty()) {
file_stat->checksumHeader = strdup(checksum.constData());
}
}
}

View File

@ -62,6 +62,12 @@ bool SqlDatabase::openHelper(const QString &filename, int sqliteFlags)
if (_errId != SQLITE_OK) {
qCWarning(lcSql) << "Error:" << _error << "for" << filename;
if (_errId == SQLITE_CANTOPEN) {
qCWarning(lcSql) << "CANTOPEN extended errcode: " << sqlite3_extended_errcode(_db);
#if SQLITE_VERSION_NUMBER >= 3012000
qCWarning(lcSql) << "CANTOPEN system errno: " << sqlite3_system_errno(_db);
#endif
}
close();
return false;
}

View File

@ -344,6 +344,41 @@ void PropagateDownloadFile::start()
}
}
// If we have a conflict where size and mtime are identical,
// compare the remote checksum to the local one.
// Maybe it's not a real conflict and no download is necessary!
if (_item->_instruction == CSYNC_INSTRUCTION_CONFLICT
&& _item->_size == _item->log._other_size
&& _item->_modtime == _item->log._other_modtime
&& !_item->_checksumHeader.isEmpty()) {
qCDebug(lcPropagateDownload) << _item->_file << "may not need download, computing checksum";
auto computeChecksum = new ComputeChecksum(this);
computeChecksum->setChecksumType(parseChecksumHeaderType(_item->_checksumHeader));
connect(computeChecksum, SIGNAL(done(QByteArray, QByteArray)),
SLOT(conflictChecksumComputed(QByteArray, QByteArray)));
computeChecksum->start(propagator()->getFilePath(_item->_file));
return;
}
startDownload();
}
void PropagateDownloadFile::conflictChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
{
if (makeChecksumHeader(checksumType, checksum) == _item->_checksumHeader) {
qCDebug(lcPropagateDownload) << _item->_file << "remote and local checksum match";
// No download necessary, just update metadata
updateMetadata(/*isConflict=*/false);
return;
}
startDownload();
}
void PropagateDownloadFile::startDownload()
{
if (propagator()->_abortRequested.fetchAndAddRelaxed(0))
return;
// do a klaas' case clash check.
if (propagator()->localFileNameClash(_item->_file)) {
done(SyncFileItem::NormalError, tr("File %1 can not be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
@ -513,6 +548,11 @@ void PropagateDownloadFile::slotGetFinished()
} else if (fileNotFound) {
job->setErrorString(tr("File was deleted from server"));
job->setErrorStatus(SyncFileItem::SoftError);
// As a precaution against bugs that cause our database and the
// reality on the server to diverge, rediscover this folder on the
// next sync run.
propagator()->_journal->avoidReadFromDbOnNextSync(_item->_file);
}
SyncFileItem::Status status = job->errorStatus();
@ -667,7 +707,7 @@ namespace { // Anonymous namespace for the recall feature
continue;
}
qCInfo(lcPropagateDownload) << "Recalling" << localRecalledFile << "Checksum:" << record._contentChecksumType << record._contentChecksum;
qCInfo(lcPropagateDownload) << "Recalling" << localRecalledFile << "Checksum:" << record._checksumHeader;
QString targetPath = makeRecallFileName(recalledFile);
@ -712,8 +752,7 @@ void PropagateDownloadFile::transmissionChecksumValidated(const QByteArray &chec
void PropagateDownloadFile::contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
{
_item->_contentChecksum = checksum;
_item->_contentChecksumType = checksumType;
_item->_checksumHeader = makeChecksumHeader(checksumType, checksum);
downloadFinished();
}
@ -822,6 +861,13 @@ void PropagateDownloadFile::downloadFinished()
// Get up to date information for the journal.
_item->_size = FileSystem::getSize(fn);
updateMetadata(isConflict);
}
void PropagateDownloadFile::updateMetadata(bool isConflict)
{
QString fn = propagator()->getFilePath(_item->_file);
if (!propagator()->_journal->setFileRecord(SyncJournalFileRecord(*_item, fn))) {
done(SyncFileItem::FatalError, tr("Error writing metadata to the database"));
return;

View File

@ -106,6 +106,40 @@ private slots:
/**
* @brief The PropagateDownloadFile class
* @ingroup libsync
*
* This is the flow:
\code{.unparsed}
start()
|
| deleteExistingFolder() if enabled
|
+--> mtime and size identical?
| then compute the local checksum
| done?-> conflictChecksumComputed()
| |
| checksum differs? |
+-> startDownload() <--------------------------+
| |
+-> run a GETFileJob | checksum identical?
|
done?-> slotGetFinished() |
| |
+-> validate checksum header |
|
done?-> transmissionChecksumValidated() |
| |
+-> compute the content checksum |
|
done?-> contentChecksumComputed() |
| |
+-> downloadFinished() |
| |
+------------------+ |
| |
+-> updateMetadata() <-------------------------+
\endcode
*/
class PropagateDownloadFile : public PropagateItemJob
{
@ -136,11 +170,22 @@ public:
void setDeleteExistingFolder(bool enabled);
private slots:
/// Called when ComputeChecksum on the local file finishes,
/// maybe the local and remote checksums are identical?
void conflictChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum);
/// Called to start downloading the remote file
void startDownload();
/// Called when the GETFileJob finishes
void slotGetFinished();
void abort() Q_DECL_OVERRIDE;
/// Called when the download's checksum header was validated
void transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum);
/// Called when the download's checksum computation is done
void contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum);
void downloadFinished();
/// Called when it's time to update the db metadata
void updateMetadata(bool isConflict);
void abort() Q_DECL_OVERRIDE;
void slotDownloadProgress(qint64, qint64);
void slotChecksumFail(const QString &errMsg);

View File

@ -173,8 +173,7 @@ void PropagateRemoteMove::finalize()
SyncJournalFileRecord record(*_item, propagator()->getFilePath(_item->_renameTarget));
record._path = _item->_renameTarget;
if (oldRecord.isValid()) {
record._contentChecksum = oldRecord._contentChecksum;
record._contentChecksumType = oldRecord._contentChecksumType;
record._checksumHeader = oldRecord._checksumHeader;
if (record._fileSize != oldRecord._fileSize) {
qCWarning(lcPropagateRemoteMove) << "File sizes differ on server vs sync journal: " << record._fileSize << oldRecord._fileSize;

View File

@ -231,9 +231,10 @@ void PropagateUploadFileCommon::slotComputeContentChecksum()
QByteArray checksumType = contentChecksumType();
// Maybe the discovery already computed the checksum?
if (_item->_contentChecksumType == checksumType
&& !_item->_contentChecksum.isEmpty()) {
slotComputeTransmissionChecksum(checksumType, _item->_contentChecksum);
QByteArray existingChecksumType, existingChecksum;
parseChecksumHeader(_item->_checksumHeader, &existingChecksumType, &existingChecksum);
if (existingChecksumType == checksumType) {
slotComputeTransmissionChecksum(checksumType, existingChecksum);
return;
}
@ -250,8 +251,7 @@ void PropagateUploadFileCommon::slotComputeContentChecksum()
void PropagateUploadFileCommon::slotComputeTransmissionChecksum(const QByteArray &contentChecksumType, const QByteArray &contentChecksum)
{
_item->_contentChecksum = contentChecksum;
_item->_contentChecksumType = contentChecksumType;
_item->_checksumHeader = makeChecksumHeader(contentChecksumType, contentChecksum);
#ifdef WITH_TESTING
_stopWatch.addLapTime(QLatin1String("ContentChecksum"));
@ -288,13 +288,11 @@ void PropagateUploadFileCommon::slotStartUpload(const QByteArray &transmissionCh
// When we start chunks, we will add it again, once for every chunks.
propagator()->_activeJobList.removeOne(this);
_transmissionChecksum = transmissionChecksum;
_transmissionChecksumType = transmissionChecksumType;
_transmissionChecksumHeader = makeChecksumHeader(transmissionChecksumType, transmissionChecksum);
if (_item->_contentChecksum.isEmpty() && _item->_contentChecksumType.isEmpty()) {
// If the _contentChecksum was not set, reuse the transmission checksum as the content checksum.
_item->_contentChecksum = transmissionChecksum;
_item->_contentChecksumType = transmissionChecksumType;
// If no checksum header was not set, reuse the transmission checksum as the content checksum.
if (_item->_checksumHeader.isEmpty()) {
_item->_checksumHeader = _transmissionChecksumHeader;
}
const QString fullFilePath = propagator()->getFilePath(_item->_file);

View File

@ -226,8 +226,7 @@ protected:
Utility::StopWatch _stopWatch;
#endif
QByteArray _transmissionChecksum;
QByteArray _transmissionChecksumType;
QByteArray _transmissionChecksumHeader;
public:
PropagateUploadFileCommon(OwncloudPropagator *propagator, const SyncFileItemPtr &item)

View File

@ -283,9 +283,8 @@ void PropagateUploadFileNG::startNextChunk()
if (!ifMatch.isEmpty()) {
headers["If"] = "<" + destination.toUtf8() + "> ([" + ifMatch + "])";
}
if (!_transmissionChecksumType.isEmpty()) {
headers[checkSumHeaderC] = makeChecksumHeader(
_transmissionChecksumType, _transmissionChecksum);
if (!_transmissionChecksumHeader.isEmpty()) {
headers[checkSumHeaderC] = _transmissionChecksumHeader;
}
headers["OC-Total-Length"] = QByteArray::number(fileSize);

View File

@ -103,9 +103,8 @@ void PropagateUploadFileV1::startNextChunk()
}
qCDebug(lcPropagateUpload) << _chunkCount << isFinalChunk << chunkStart << currentChunkSize;
if (isFinalChunk && !_transmissionChecksumType.isEmpty()) {
headers[checkSumHeaderC] = makeChecksumHeader(
_transmissionChecksumType, _transmissionChecksum);
if (isFinalChunk && !_transmissionChecksumHeader.isEmpty()) {
headers[checkSumHeaderC] = _transmissionChecksumHeader;
}
const QString fileName = propagator()->getFilePath(_item->_file);

View File

@ -241,8 +241,7 @@ void PropagateLocalRename::start()
SyncJournalFileRecord record(*_item, targetFile);
record._path = _item->_renameTarget;
if (oldRecord.isValid()) {
record._contentChecksum = oldRecord._contentChecksum;
record._contentChecksumType = oldRecord._contentChecksumType;
record._checksumHeader = oldRecord._checksumHeader;
}
if (!_item->_isDirectory) { // Directories are saved at the end

View File

@ -52,7 +52,7 @@
namespace OCC {
Q_LOGGING_CATEGORY(lcEngine, "sync.engine")
Q_LOGGING_CATEGORY(lcEngine, "sync.engine", QtInfoMsg)
bool SyncEngine::s_anySyncRunning = false;
@ -73,7 +73,6 @@ SyncEngine::SyncEngine(AccountPtr account, const QString &localPath,
, _backInTimeFiles(0)
, _uploadLimit(0)
, _downloadLimit(0)
, _checksum_hook(journal)
, _anotherSyncNeeded(NoFollowUpSync)
{
qRegisterMetaType<SyncFileItem>("SyncFileItem");
@ -426,9 +425,12 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
}
// Sometimes the discovery computes checksums for local files
if (!remote && file->checksum && file->checksumTypeId) {
item->_contentChecksum = QByteArray(file->checksum);
item->_contentChecksumType = _journal->getChecksumType(file->checksumTypeId);
if (!remote && file->checksumHeader) {
item->_checksumHeader = QByteArray(file->checksumHeader);
}
// For conflicts, store the remote checksum there
if (remote && item->_instruction == CSYNC_INSTRUCTION_CONFLICT && file->checksumHeader) {
item->_checksumHeader = QByteArray(file->checksumHeader);
}
// record the seen files to be able to clean the journal later
@ -1159,6 +1161,7 @@ void SyncEngine::checkForPermission(SyncFileItemVector &syncItems)
bool selectiveListOk;
auto selectiveSyncBlackList = _journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &selectiveListOk);
std::sort(selectiveSyncBlackList.begin(), selectiveSyncBlackList.end());
SyncFileItemPtr needle;
for (SyncFileItemVector::iterator it = syncItems.begin(); it != syncItems.end(); ++it) {
if ((*it)->_direction != SyncFileItem::Up) {
@ -1177,8 +1180,41 @@ void SyncEngine::checkForPermission(SyncFileItemVector &syncItems)
(*it)->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
if ((*it)->_isDirectory) {
auto it_base = it;
for (SyncFileItemVector::iterator it_next = it + 1; it_next != syncItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
it = it_next;
// We want to ignore almost all instructions for items inside selective-sync excluded folders.
//The exception are DOWN/REMOVE actions that remove local files and folders that are
//guaranteed to be up-to-date with their server copies.
if ((*it)->_direction == SyncFileItem::Down && (*it)->_instruction == CSYNC_INSTRUCTION_REMOVE) {
// We need to keep the "delete" items. So we need to un-ignore parent directories
QString parentDir = (*it)->_file;
do {
parentDir = QFileInfo(parentDir).path();
if (parentDir.isEmpty() || !parentDir.startsWith((*it_base)->destination())) {
break;
}
// Find the parent directory in the syncItems vector. Since the vector
// is sorted we can use a lower_bound, but we need a fake
// SyncFileItemPtr needle to compare against
if (!needle)
needle = SyncFileItemPtr::create();
needle->_file = parentDir;
auto parent_it = std::lower_bound(it_base, it, needle);
if (parent_it == syncItems.end() || (*parent_it)->destination() != parentDir) {
break;
}
ASSERT((*parent_it)->_isDirectory);
if ((*parent_it)->_instruction != CSYNC_INSTRUCTION_IGNORE) {
break; // already changed
}
(*parent_it)->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
(*parent_it)->_status = SyncFileItem::NoStatus;
(*parent_it)->_errorString.clear();
} while (true);
continue;
}
(*it)->_instruction = CSYNC_INSTRUCTION_IGNORE;
(*it)->_status = SyncFileItem::FileIgnored;
(*it)->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");

View File

@ -190,8 +190,13 @@ public:
quint64 _inode;
QByteArray _fileId;
QByteArray _remotePerm;
QByteArray _contentChecksum;
QByteArray _contentChecksumType;
// When is this set, and is it the local or the remote checksum?
// - if mtime or size changed locally for *.eml files (local checksum)
// - for potential renames of local files (local checksum)
// - for conflicts (remote checksum) (what about eval_rename/new reconcile?)
QByteArray _checksumHeader;
QString _directDownloadUrl;
QString _directDownloadCookies;

View File

@ -17,6 +17,7 @@
#include <QStringList>
#include <QElapsedTimer>
#include <QUrl>
#include <QDir>
#include "ownsql.h"
@ -28,6 +29,7 @@
#include "version.h"
#include "filesystem.h"
#include "asserts.h"
#include "checksums.h"
#include "../../csync/src/std/c_jhash.h"
@ -42,7 +44,8 @@ SyncJournalDb::SyncJournalDb(const QString &dbFilePath, QObject *parent)
{
}
QString SyncJournalDb::makeDbName(const QUrl &remoteUrl,
QString SyncJournalDb::makeDbName(const QString &localPath,
const QUrl &remoteUrl,
const QString &remotePath,
const QString &user)
{
@ -54,6 +57,42 @@ QString SyncJournalDb::makeDbName(const QUrl &remoteUrl,
journalPath.append(ba.left(6).toHex());
journalPath.append(".db");
// If the journal doesn't exist and we can't create a file
// at that location, try again with a journal name that doesn't
// have the ._ prefix.
//
// The disadvantage of that filename is that it will only be ignored
// by client versions >2.3.2.
//
// See #5633: "._*" is often forbidden on samba shared folders.
// If it exists already, the path is clearly usable
QFile file(QDir(localPath).filePath(journalPath));
if (file.exists()) {
return journalPath;
}
// Try to create a file there
if (file.open(QIODevice::ReadWrite)) {
// Ok, all good.
file.close();
file.remove();
return journalPath;
}
// Can we create it if we drop the underscore?
QString alternateJournalPath = journalPath.mid(2).prepend(".");
QFile file2(QDir(localPath).filePath(alternateJournalPath));
if (file2.open(QIODevice::ReadWrite)) {
// The alternative worked, use it
qCInfo(lcDb) << "Using alternate database path" << alternateJournalPath;
file2.close();
file2.remove();
return alternateJournalPath;
}
// Neither worked, just keep the original and throw errors later
qCWarning(lcDb) << "Could not find a writable database path" << file.fileName();
return journalPath;
}
@ -448,7 +487,7 @@ bool SyncJournalDb::checkConnect()
_getFileRecordQuery.reset(new SqlQuery(_db));
if (_getFileRecordQuery->prepare(
"SELECT path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize,"
" ignoredChildrenRemote, contentChecksum, contentchecksumtype.name"
" ignoredChildrenRemote, contentchecksumtype.name || ':' || contentChecksum"
" FROM metadata"
" LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id"
" WHERE phash=?1")) {
@ -832,7 +871,7 @@ bool SyncJournalDb::setFileRecord(const SyncJournalFileRecord &_record)
qCInfo(lcDb) << "Updating file record for path:" << record._path << "inode:" << record._inode
<< "modtime:" << record._modtime << "type:" << record._type
<< "etag:" << record._etag << "fileId:" << record._fileId << "remotePerm:" << record._remotePerm
<< "fileSize:" << record._fileSize << "checksum:" << record._contentChecksum << record._contentChecksumType;
<< "fileSize:" << record._fileSize << "checksum:" << record._checksumHeader;
qlonglong phash = getPHash(record._path);
if (checkConnect()) {
@ -848,7 +887,9 @@ bool SyncJournalDb::setFileRecord(const SyncJournalFileRecord &_record)
QString remotePerm(record._remotePerm);
if (remotePerm.isEmpty())
remotePerm = QString(); // have NULL in DB (vs empty)
int contentChecksumTypeId = mapChecksumType(record._contentChecksumType);
QByteArray checksumType, checksum;
parseChecksumHeader(record._checksumHeader, &checksumType, &checksum);
int contentChecksumTypeId = mapChecksumType(checksumType);
_setFileRecordQuery->reset_and_clear_bindings();
_setFileRecordQuery->bindValue(1, QString::number(phash));
_setFileRecordQuery->bindValue(2, plen);
@ -864,7 +905,7 @@ bool SyncJournalDb::setFileRecord(const SyncJournalFileRecord &_record)
_setFileRecordQuery->bindValue(12, remotePerm);
_setFileRecordQuery->bindValue(13, record._fileSize);
_setFileRecordQuery->bindValue(14, record._serverHasIgnoredFiles ? 1 : 0);
_setFileRecordQuery->bindValue(15, record._contentChecksum);
_setFileRecordQuery->bindValue(15, checksum);
_setFileRecordQuery->bindValue(16, contentChecksumTypeId);
if (!_setFileRecordQuery->exec()) {
@ -943,10 +984,7 @@ SyncJournalFileRecord SyncJournalDb::getFileRecord(const QString &filename)
rec._remotePerm = _getFileRecordQuery->baValue(9);
rec._fileSize = _getFileRecordQuery->int64Value(10);
rec._serverHasIgnoredFiles = (_getFileRecordQuery->intValue(11) > 0);
rec._contentChecksum = _getFileRecordQuery->baValue(12);
if (!_getFileRecordQuery->nullValue(13)) {
rec._contentChecksumType = _getFileRecordQuery->baValue(13);
}
rec._checksumHeader = _getFileRecordQuery->baValue(12);
_getFileRecordQuery->reset_and_clear_bindings();
} else {
int errId = _getFileRecordQuery->errorId();

View File

@ -41,7 +41,8 @@ public:
virtual ~SyncJournalDb();
/// Create a journal path for a specific configuration
static QString makeDbName(const QUrl &remoteUrl,
static QString makeDbName(const QString &localPath,
const QUrl &remoteUrl,
const QString &remotePath,
const QString &user);

View File

@ -47,8 +47,7 @@ SyncJournalFileRecord::SyncJournalFileRecord(const SyncFileItem &item, const QSt
, _fileSize(item._size)
, _remotePerm(item._remotePerm)
, _serverHasIgnoredFiles(item._serverHasIgnoredFiles)
, _contentChecksum(item._contentChecksum)
, _contentChecksumType(item._contentChecksumType)
, _checksumHeader(item._checksumHeader)
{
// use the "old" inode coming with the item for the case where the
// filesystem stat fails. That can happen if the the file was removed
@ -106,8 +105,7 @@ SyncFileItem SyncJournalFileRecord::toSyncFileItem()
item._size = _fileSize;
item._remotePerm = _remotePerm;
item._serverHasIgnoredFiles = _serverHasIgnoredFiles;
item._contentChecksum = _contentChecksum;
item._contentChecksumType = _contentChecksumType;
item._checksumHeader = _checksumHeader;
return item;
}
@ -130,7 +128,6 @@ bool operator==(const SyncJournalFileRecord &lhs,
&& lhs._fileSize == rhs._fileSize
&& lhs._remotePerm == rhs._remotePerm
&& lhs._serverHasIgnoredFiles == rhs._serverHasIgnoredFiles
&& lhs._contentChecksum == rhs._contentChecksum
&& lhs._contentChecksumType == rhs._contentChecksumType;
&& lhs._checksumHeader == rhs._checksumHeader;
}
}

View File

@ -57,8 +57,7 @@ public:
qint64 _fileSize;
QByteArray _remotePerm;
bool _serverHasIgnoredFiles;
QByteArray _contentChecksum;
QByteArray _contentChecksumType;
QByteArray _checksumHeader;
};
bool OWNCLOUDSYNC_EXPORT

View File

@ -12,8 +12,6 @@
* for more details.
*/
#include <openssl/crypto.h>
#include "theme.h"
#include "version.h"
#include "config.h"
@ -308,11 +306,7 @@ QString Theme::gitSHA1() const
.arg(__DATE__)
.arg(__TIME__)
.arg(QString::fromAscii(qVersion()))
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
.arg(QSslSocket::sslLibraryVersionString());
#else
.arg(QCoreApplication::translate("ownCloudTheme::about()", "built with %1").arg(QString::fromAscii(OPENSSL_VERSION_TEXT)));
#endif
#endif
return devString;
}
@ -503,5 +497,15 @@ QString Theme::quotaBaseFolder() const
return QLatin1String("/");
}
QString Theme::oauthClientId() const
{
return "xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69";
}
QString Theme::oauthClientSecret() const
{
return "UBntmLjC2yYCeHwsyj73Uwo9TAaecAetRwMw0xYcvNL9yRdLSUi0hUAHfvCHFeFh";
}
} // end namespace client

View File

@ -320,6 +320,13 @@ public:
*/
virtual QString quotaBaseFolder() const;
/**
* The OAuth client_id, secret pair.
* Note that client that change these value cannot connect to un-branded owncloud servers.
*/
virtual QString oauthClientId() const;
virtual QString oauthClientSecret() const;
protected:
#ifndef TOKEN_AUTH_ONLY

View File

@ -59,3 +59,4 @@ list(APPEND FolderMan_SRC ${FolderWatcher_SRC})
list(APPEND FolderMan_SRC stub.cpp )
owncloud_add_test(FolderMan "${FolderMan_SRC}")
configure_file(test_journal.db "${PROJECT_BINARY_DIR}/bin/test_journal.db" COPYONLY)

View File

@ -17,6 +17,12 @@
#include <QMap>
#include <QtTest>
/*
* TODO: In theory we should use QVERIFY instead of Q_ASSERT for testing, but this
* only works when directly called from a QTest :-(
*/
static const QUrl sRootUrl("owncloud://somehost/owncloud/remote.php/webdav/");
static const QUrl sRootUrl2("owncloud://somehost/owncloud/remote.php/dav/files/admin/");
static const QUrl sUploadUrl("owncloud://somehost/owncloud/remote.php/dav/uploads/admin/");
@ -282,6 +288,7 @@ public:
QDateTime lastModified = QDateTime::currentDateTime().addDays(-7);
QString etag = generateEtag();
QByteArray fileId = generateFileId();
QByteArray checksums;
qint64 size = 0;
char contentChar = 'W';
@ -346,12 +353,13 @@ public:
xml.writeEmptyElement(davUri, QStringLiteral("resourcetype"));
auto gmtDate = fileInfo.lastModified.toTimeZone(QTimeZone(0));
auto stringDate = gmtDate.toString("ddd, dd MMM yyyy HH:mm:ss 'GMT'");
auto stringDate = QLocale::c().toString(gmtDate, "ddd, dd MMM yyyy HH:mm:ss 'GMT'");
xml.writeTextElement(davUri, QStringLiteral("getlastmodified"), stringDate);
xml.writeTextElement(davUri, QStringLiteral("getcontentlength"), QString::number(fileInfo.size));
xml.writeTextElement(davUri, QStringLiteral("getetag"), fileInfo.etag);
xml.writeTextElement(ocUri, QStringLiteral("permissions"), fileInfo.isShared ? QStringLiteral("SRDNVCKW") : QStringLiteral("RDNVCKW"));
xml.writeTextElement(ocUri, QStringLiteral("id"), fileInfo.fileId);
xml.writeTextElement(ocUri, QStringLiteral("checksums"), fileInfo.checksums);
xml.writeEndElement(); // prop
xml.writeTextElement(davUri, QStringLiteral("status"), "HTTP/1.1 200 OK");
xml.writeEndElement(); // propstat
@ -704,10 +712,17 @@ public:
class FakeQNAM : public QNetworkAccessManager
{
public:
using Override = std::function<QNetworkReply *(Operation, const QNetworkRequest &)>;
private:
FileInfo _remoteRootFileInfo;
FileInfo _uploadFileInfo;
// maps a path to an HTTP error
QHash<QString, int> _errorPaths;
// monitor requests and optionally provide custom replies
Override _override;
public:
FakeQNAM(FileInfo initialRoot) : _remoteRootFileInfo{std::move(initialRoot)} { }
FileInfo &currentRemoteState() { return _remoteRootFileInfo; }
@ -715,6 +730,8 @@ public:
QHash<QString, int> &errorPaths() { return _errorPaths; }
void setOverride(const Override &override) { _override = override; }
protected:
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
QIODevice *outgoingData = 0) {
@ -726,8 +743,13 @@ protected:
bool isUpload = request.url().path().startsWith(sUploadUrl.path());
FileInfo &info = isUpload ? _uploadFileInfo : _remoteRootFileInfo;
if (_override) {
if (auto reply = _override(op, request))
return reply;
}
auto verb = request.attribute(QNetworkRequest::CustomVerbAttribute);
if (verb == QLatin1String("PROPFIND"))
if (verb == "PROPFIND")
// Ignore outgoingData always returning somethign good enough, works for now.
return new FakePropfindReply{info, op, request, this};
else if (verb == QLatin1String("GET") || op == QNetworkAccessManager::GetOperation)
@ -823,6 +845,7 @@ public:
void clear() { _qnam->errorPaths().clear(); }
};
ErrorList serverErrorPaths() { return {_fakeQnam}; }
void setServerOverride(const FakeQNAM::Override &override) { _fakeQnam->setOverride(override); }
QString localPath() const {
// SyncEngine wants a trailing slash

Binary file not shown.

View File

@ -21,10 +21,11 @@ private slots:
memset(&_ctx, 0, sizeof(CSYNC));
_ctx.statedb.file = c_strdup("./test_journal.db");
QString db = QCoreApplication::applicationDirPath() + "/test_journal.db";
_ctx.statedb.file = c_strdup(db.toLocal8Bit());
rc = csync_statedb_load((CSYNC*)(&_ctx), _ctx.statedb.file, &(_ctx.statedb.db));
Q_ASSERT(rc == 0);
QVERIFY(rc == 0);
}
void testFullResult() {
@ -85,5 +86,5 @@ private slots:
};
QTEST_APPLESS_MAIN(TestCSyncSqlite)
QTEST_GUILESS_MAIN(TestCSyncSqlite)
#include "testcsyncsqlite.moc"

View File

@ -220,7 +220,18 @@ private slots:
FileInfo { QStringLiteral("parentFolder"), {
FileInfo{ QStringLiteral("subFolder"), {
{ QStringLiteral("fileA.txt"), 400 },
{ QStringLiteral("fileB.txt"), 400, 'o' }
{ QStringLiteral("fileB.txt"), 400, 'o' },
FileInfo { QStringLiteral("subsubFolder"), {
{ QStringLiteral("fileC.txt"), 400 },
{ QStringLiteral("fileD.txt"), 400, 'o' }
}},
FileInfo{ QStringLiteral("anotherFolder"), {
FileInfo { QStringLiteral("emptyFolder"), { } },
FileInfo { QStringLiteral("subsubFolder"), {
{ QStringLiteral("fileE.txt"), 400 },
{ QStringLiteral("fileF.txt"), 400, 'o' }
}}
}}
}}
}}
}}};
@ -233,9 +244,11 @@ private slots:
{"parentFolder/subFolder/"});
fakeFolder.syncEngine().journal()->avoidReadFromDbOnNextSync("parentFolder/subFolder/");
// But touch a local file before the next sync, such that the local folder
// But touch local file before the next sync, such that the local folder
// can't be removed
fakeFolder.localModifier().setContents("parentFolder/subFolder/fileB.txt", 'n');
fakeFolder.localModifier().setContents("parentFolder/subFolder/subsubFolder/fileD.txt", 'n');
fakeFolder.localModifier().setContents("parentFolder/subFolder/anotherFolder/subsubFolder/fileF.txt", 'n');
// Several follow-up syncs don't change the state at all,
// in particular the remote state doesn't change and fileB.txt
@ -250,8 +263,13 @@ private slots:
// The local state should still have subFolderA
auto local = fakeFolder.currentLocalState();
QVERIFY(local.find("parentFolder/subFolder"));
QVERIFY(local.find("parentFolder/subFolder/fileA.txt"));
QVERIFY(!local.find("parentFolder/subFolder/fileA.txt"));
QVERIFY(local.find("parentFolder/subFolder/fileB.txt"));
QVERIFY(!local.find("parentFolder/subFolder/subsubFolder/fileC.txt"));
QVERIFY(local.find("parentFolder/subFolder/subsubFolder/fileD.txt"));
QVERIFY(!local.find("parentFolder/subFolder/anotherFolder/subsubFolder/fileE.txt"));
QVERIFY(local.find("parentFolder/subFolder/anotherFolder/subsubFolder/fileF.txt"));
QVERIFY(!local.find("parentFolder/subFolder/anotherFolder/emptyFolder"));
}
}
}
@ -303,6 +321,70 @@ private slots:
}
}
void testFakeConflict()
{
FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
int nGET = 0;
fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &) {
if (op == QNetworkAccessManager::GetOperation)
++nGET;
return nullptr;
});
// For directly editing the remote checksum
FileInfo &remoteInfo = dynamic_cast<FileInfo &>(fakeFolder.remoteModifier());
// Base mtime with no ms content (filesystem is seconds only)
auto mtime = QDateTime::currentDateTime().addDays(-4);
mtime.setMSecsSinceEpoch(mtime.toMSecsSinceEpoch() / 1000 * 1000);
// Conflict: Same content, mtime, but no server checksum
// -> ignored in reconcile
fakeFolder.localModifier().setContents("A/a1", 'C');
fakeFolder.localModifier().setModTime("A/a1", mtime);
fakeFolder.remoteModifier().setContents("A/a1", 'C');
fakeFolder.remoteModifier().setModTime("A/a1", mtime);
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nGET, 0);
// Conflict: Same content, mtime, but weak server checksum
// -> ignored in reconcile
mtime = mtime.addDays(1);
fakeFolder.localModifier().setContents("A/a1", 'D');
fakeFolder.localModifier().setModTime("A/a1", mtime);
fakeFolder.remoteModifier().setContents("A/a1", 'D');
fakeFolder.remoteModifier().setModTime("A/a1", mtime);
remoteInfo.find("A/a1")->checksums = "Adler32:bad";
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nGET, 0);
// Conflict: Same content, mtime, but server checksum differs
// -> downloaded
mtime = mtime.addDays(1);
fakeFolder.localModifier().setContents("A/a1", 'W');
fakeFolder.localModifier().setModTime("A/a1", mtime);
fakeFolder.remoteModifier().setContents("A/a1", 'W');
fakeFolder.remoteModifier().setModTime("A/a1", mtime);
remoteInfo.find("A/a1")->checksums = "SHA1:bad";
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nGET, 1);
// Conflict: Same content, mtime, matching checksums
// -> PropagateDownload, but it skips the download
mtime = mtime.addDays(1);
fakeFolder.localModifier().setContents("A/a1", 'C');
fakeFolder.localModifier().setModTime("A/a1", mtime);
fakeFolder.remoteModifier().setContents("A/a1", 'C');
fakeFolder.remoteModifier().setModTime("A/a1", mtime);
remoteInfo.find("A/a1")->checksums = "SHA1:56900fb1d337cf7237ff766276b9c1e8ce507427";
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nGET, 1);
// Extra sync reads from db, no difference
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nGET, 1);
}
};
QTEST_GUILESS_MAIN(TestSyncEngine)

View File

@ -53,17 +53,15 @@ private slots:
record._fileId = "abcd";
record._remotePerm = "744";
record._fileSize = 213089055;
record._contentChecksum = "mychecksum";
record._contentChecksumType = "MD5";
record._checksumHeader = "MD5:mychecksum";
QVERIFY(_db.setFileRecord(record));
SyncJournalFileRecord storedRecord = _db.getFileRecord("foo");
QVERIFY(storedRecord == record);
// Update checksum
record._contentChecksum = "newchecksum";
record._contentChecksumType = "Adler32";
_db.updateFileRecordChecksum("foo", record._contentChecksum, record._contentChecksumType);
record._checksumHeader = "Adler32:newchecksum";
_db.updateFileRecordChecksum("foo", "newchecksum", "Adler32");
storedRecord = _db.getFileRecord("foo");
QVERIFY(storedRecord == record);
@ -91,16 +89,14 @@ private slots:
SyncJournalFileRecord record;
record._path = "foo-checksum";
record._remotePerm = "744";
record._contentChecksum = "mychecksum";
record._contentChecksumType = "MD5";
record._checksumHeader = "MD5:mychecksum";
record._modtime = QDateTime::currentDateTimeUtc();
QVERIFY(_db.setFileRecord(record));
SyncJournalFileRecord storedRecord = _db.getFileRecord("foo-checksum");
QVERIFY(storedRecord._path == record._path);
QVERIFY(storedRecord._remotePerm == record._remotePerm);
QVERIFY(storedRecord._contentChecksum == record._contentChecksum);
QVERIFY(storedRecord._contentChecksumType == record._contentChecksumType);
QVERIFY(storedRecord._checksumHeader == record._checksumHeader);
// qDebug()<< "OOOOO " << storedRecord._modtime.toTime_t() << record._modtime.toTime_t();

View File

@ -807,112 +807,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>No es pot restablir l&apos;estat de la carpeta</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>S&apos;ha trobat un diari de sincronització antic &apos;%1&apos;, però no s&apos;ha pogut eliminar. Assegureu-vos que no hi ha cap aplicació que actualment en faci ús.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(copia de seguretat)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(copia de seguretat %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Estat indefinit.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>S&apos;està esperant per començar a sincronitzar.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>S&apos;està preparant per la sincronització.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>S&apos;està sincronitzant.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>La darrera sincronització va ser correcta.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>La última sincronització ha estat un èxit, però amb avisos en fitxers individuals.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Error de configuració.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Cancel·la usuari.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>La sincronització està en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sync està pausat)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>No s&apos;ha seleccionat cap directori vàlid!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>La ruta seleccionada no és un directori!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>No teniu permisos per escriure en la carpeta seleccionada!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1255,17 +1255,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Quant a</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Actualitzacions</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Reiniciar &amp;&amp; Actualitzar</translation>
</message>
@ -1345,22 +1345,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Els elements que poden ser eliminats s&apos;eliminaran si impedeixen que una carpeta sigui eliminada. Això és útil per les metadades.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>No s&apos;ha pogut obrir el fitxer</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>No es poden desar els canvis a &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Afegeix una plantilla per ignorar</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Afegeix una nova plantilla d&apos;ignorats:</translation>
</message>
@ -2018,27 +2018,27 @@ No és aconsellada usar-la.</translation>
<translation>El fitxer s&apos;ha esborrat del servidor</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>No es pot descarregar el fitxer completament.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>El fitxer ha canviat des de que es va descobrir</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Error en escriure les metadades a la base de dades</translation>
</message>
@ -2549,6 +2549,11 @@ No és aconsellada usar-la.</translation>
<source>Allow editing</source>
<translation>Permetre edició</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -810,112 +810,112 @@ Pokračováním v synchronizaci způsobí přepsání všech vašich souborů st
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Nelze obnovit stav adresáře</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Byl nalezen starý záznam synchronizace &apos;%1&apos;, ale nebylo možné jej odebrat. Ujistěte se, že není aktuálně používán jinou aplikací.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation> (záloha)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation> (záloha %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Nedefinovaný stav.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Čeká na spuštění synchronizace.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Příprava na synchronizaci.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Synchronizace probíhá.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Poslední synchronizace byla úspěšná.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Poslední synchronizace byla úspěšná, ale s varováním u některých souborů</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Chyba nastavení.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Zrušení uživatelem.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Synchronizace pozastavena.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronizace je pozastavena)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Nebyl vybrán platný adresář!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Vybraná cesta nevede do adresáře!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Nemáte oprávnění pro zápis do zvoleného adresáře!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>Místní složka %1 obsahuje symbolický odkaz. Cílový odkaz obsahuje již synchronizované složky. Vyberte si prosím jinou!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Ze serveru se do tohoto umístění již synchronizuje. Prosím zvolte jinou místní složku!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Místní adresář %1 již obsahuje podadresář použitý pro synchronizaci odesílání. Zvolte prosím jiný!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Místní adresář %1 je již obsažen ve adresáři použitém pro synchronizaci. Vyberte prosím jiný!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Místní adresář %1 je symbolickým obsahem. Cíl odkazu je již obsažen v adresáři použitém pro synchronizaci. Vyberte prosím jiný!</translation>
</message>
@ -1258,17 +1258,17 @@ Pokračováním v synchronizaci způsobí přepsání všech vašich souborů st
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>O aplikaci</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Aktualizace</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Restart &amp;&amp; aktualizace</translation>
</message>
@ -1348,22 +1348,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Položky u kterých je povoleno smazání budou vymazány, pokud by bránily odstranění adresáře. Toto je užitečné pro metadata.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Nepodařilo se otevřít soubor</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Nelze zapsat změny do &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Přidat masku ignorovaných</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Přidat novou masku ignorovaných souborů:</translation>
</message>
@ -2021,27 +2021,27 @@ Nedoporučuje se jí používat.</translation>
<translation>Soubor byl smazán ze serveru</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Soubor nemohl být kompletně stažen.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Stažený soubor je prázdný, přestože server oznámil, že měl být %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Soubor %1 nemohl být uložen z důvodu kolize názvu se souborem v místním systému!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Soubor se mezitím změnil</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Chyba zápisu metadat do databáze</translation>
</message>
@ -2552,6 +2552,11 @@ Nedoporučuje se jí používat.</translation>
<source>Allow editing</source>
<translation>Povolit úpravy</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Kdokoliv, kdo odkaz, může přistupovat k tomuto souboru/složce</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -812,112 +812,112 @@ Wenn diese Synchronisation fortgesetzt wird, werden Dateien eventuell von älter
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Konnte Ordner-Zustand nicht zurücksetzen</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Ein altes Synchronisations-Journal &apos;%1&apos; wurde gefunden, konnte jedoch nicht entfernt werden. Bitte stellen Sie sicher, dass keine Anwendung es verwendet.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(Sicherung)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(Sicherung %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Undefinierter Zustand.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Wartet auf Beginn der Synchronistation</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Synchronisation wird vorbereitet.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Synchronisation läuft.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Die letzte Synchronisation war erfolgreich.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Letzte Synchronisation war erfolgreich, aber mit Warnungen für einzelne Dateien.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Installationsfehler.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Benutzer-Abbruch</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Synchronisation wurde angehalten.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronisation ist pausiert)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Kein gültige Ordner gewählt!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Der gewählte Pfad ist kein Ordner!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Sie haben keine Schreibberechtigung für den ausgewählten Ordner!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>Der lokale Ordner %1 beinhaltet einen symbolischer Link. Das Ziel des Links beinhaltet bereits einen synchronisierten Ordner. Bitte wählen Sie einen anderen lokalen Ordner aus!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Es exisitiert bereits eine Synchronisation vom Server zu diesem lokalen Ordner. Bitte wählen Sie ein anderes lokales Verzeichnis!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Der lokale Ordner %1 liegt innerhalb eines synchronisierten Ordners. Bitte wählen Sie einen anderen aus!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Der lokale Ordner %1 liegt in einem Ordner, der bereits synchronisiert wird. Bitte wählen Sie einen anderen aus!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Der lokale Ordner %1 ist ein symbolischer Link. Das Ziel des Links liegt in einem Ordner, der schon synchronisiert wird. Bitte wählen Sie einen anderen aus!</translation>
</message>
@ -1260,17 +1260,17 @@ Wenn diese Synchronisation fortgesetzt wird, werden Dateien eventuell von älter
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Über</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Updates</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Neustarten &amp;&amp; aktualisieren</translation>
</message>
@ -1350,22 +1350,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Objekte, bei denen Löschen erlaubt ist, werden gelöscht, wenn sie die Löschung eines Ordners verhindern würden. Das ist für Metadaten nützlich.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Datei konnte nicht geöffnet werden</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Konnte Änderungen nicht in &apos;%1&apos; schreiben.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Ignoriermuster hinzufügen</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Neues Ignoriermuster hinzufügen:</translation>
</message>
@ -2022,27 +2022,27 @@ Es ist nicht ratsam, diese zu benutzen.</translation>
<translation>Die Datei wurde vom Server gelöscht</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Die Datei konnte nicht vollständig herunter geladen werden.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Die heruntergeladene Datei ist leer, obwohl der Server %1 als Größe übermittelt hat.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Die Datei %1 kann aufgrund eines Konfliktes mit dem lokalen Dateinamen nicht gespeichert geladen werden!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Datei ist seit der Entdeckung geändert worden</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Fehler beim Schreiben der Metadaten in die Datenbank</translation>
</message>
@ -2553,6 +2553,11 @@ Es ist nicht ratsam, diese zu benutzen.</translation>
<source>Allow editing</source>
<translation>Bearbeitung erlauben</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Jeder mit dem Link hat Zugriff auf die Datei/Ordner</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -812,112 +812,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Δεν ήταν δυνατό να επαναφερθεί η κατάσταση του φακέλου</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Βρέθηκε ένα παλαιότερο αρχείο συγχρονισμού &apos;%1&apos;, αλλά δεν μπόρεσε να αφαιρεθεί. Παρακαλώ βεβαιωθείτε ότι καμμία εφαρμογή δεν το χρησιμοποιεί αυτή τη στιγμή.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(αντίγραφο ασφαλείας)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(αντίγραοφ ασφαλέιας %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Απροσδιόριστη Κατάσταση.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Αναμονή έναρξης συγχρονισμού.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Προετοιμασία για συγχρονισμό.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Ο συγχρονισμός εκτελείται.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Ο τελευταίος συγχρονισμός ήταν επιτυχής.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Ο τελευταίος συγχρονισμός ήταν επιτυχής, αλλά υπήρχαν προειδοποιήσεις σε συγκεκριμένα αρχεία.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Σφάλμα Ρύθμισης.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Ματαίωση από Χρήστη.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Παύση συγχρονισμού.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Παύση συγχρονισμού)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Δεν επιλέχθηκε έγκυρος φάκελος!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Η επιλεγμένη διαδρομή δεν είναι φάκελος!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Δεν έχετε δικαιώματα εγγραφής στον επιλεγμένο φάκελο!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>Ο τοπικός φάκελος% 1 περιέχει έναν συμβολικό σύνδεσμο. Ο στόχος συνδέσμου περιέχει έναν ήδη συγχρονισμένο φάκελο.Παρακαλώ επιλέξτε ένα άλλο!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Υπάρχει ήδη συγχρονισμός από το διακομιστή σε αυτόν τον τοπικό φάκελο. Επιλέξτε έναν άλλο τοπικό φάκελο!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Ο τοπικός φάκελος %1 περιέχει ήδη ένα φάκελο που χρησιμοποιείται σε μια σύνδεση συγχρονισμού φακέλου. Παρακαλώ επιλέξτε άλλον!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Ο τοπικός φάκελος %1 περιέχεται ήδη σε φάκελο που χρησιμοποιείται σε μια σύνδεση συγχρονισμού. Παρακαλώ επιλέξτε άλλον!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Ο τοπικός φάκελος %1 είναι συμβολικός σύνδεσμος. Ο σύνδεσμος που παραπέμπει περιέχεται ήδη σε φάκελο που βρίσκεται σε συγχρονισμό. Παρακαλώ επιλέξτε άλλον!</translation>
</message>
@ -1260,17 +1260,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Σχετικά</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Ενημερώσεις</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Επανεκκίνηση &amp;&amp; Ενημέρωση</translation>
</message>
@ -1350,22 +1350,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Τα στοιχεία όπου επιτρέπεται η διαγραφή θα διαγράφονται εάν εμποδίζουν την αφαίρεση ενός φακέλου αρχείων. Αυτό είναι χρήσιμο για μετα-δεδομένα.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Αδυναμία ανοίγματος αρχείου</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Αδυναμία εγγραφής αλλαγών στο &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Προσθήκη Προτύπου Αγνόησης</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Προσθήκη νέου προτύπου αγνόησης:</translation>
</message>
@ -2023,27 +2023,27 @@ It is not advisable to use it.</source>
<translation>Το αρχείο διαγράφηκε από τον διακομιστή</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Η λήψη του αρχείου δεν ολοκληρώθηκε.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Το ληφθέν αρχείο είναι άδειο, παρόλο που ο διακομιστής ανακοίνωσε ότι θα έπρεπε να ήταν% 1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Το αρχείο %1 δεν είναι δυνατό να αποθηκευτεί λόγω διένεξης με το όνομα ενός τοπικού ονόματος αρχείου!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Το αρχείο έχει αλλάξει από όταν ανακαλύφθηκε</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Σφάλμα εγγραφής μεταδεδομένων στην βάση δεδομένων</translation>
</message>
@ -2554,6 +2554,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation>Επιτρέπεται η επεξεργασία</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Οποιοσδήποτε με τη σύνδεση έχει πρόσβαση στο αρχείο / φάκελο</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -832,112 +832,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"></translation>
</message>
@ -1283,17 +1283,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation type="unfinished"></translation>
</message>
@ -1371,22 +1371,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation type="unfinished"></translation>
</message>
@ -2042,27 +2042,27 @@ It is not advisable to use it.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation type="unfinished"></translation>
</message>
@ -2573,6 +2573,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -812,112 +812,112 @@ Si continua con la sincronización todos los archivos serán remplazados por su
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>No se ha podido restablecer el estado de la carpeta</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Se ha encontrado un antiguo registro de sincronización &apos;%1&apos;; pero no se ha podido eliminar. Por favor, asegúrese de que ninguna aplicación la esté utilizando.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(copia de seguridad)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(copia de seguridad %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Estado no definido.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Esperando para comenzar la sincronización.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Preparándose para sincronizar.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Sincronización en funcionamiento.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>La última sincronización se ha realizado con éxito.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>La última sincronización salió bien; pero hay advertencias para archivos individuales.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Error de configuración.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Interrumpido por el usuario.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>La sincronización está en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sincronización en pausa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>¡La carpeta seleccionada no es válida!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>¡La ruta seleccionada no es un directorio!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>¡Usted no tiene permiso para escribir en la carpeta seleccionada!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>El directorio local %1 es un enlace simbólico. El objetivo del enlace ya contiene un directorio usado en una conexión de sincronización de directorios. Por favor, elija otro.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Ya existe una tarea de sincronización entre el servidor y esta carpeta. Por favor elija otra carpeta local.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>El directorio local %1 ya contiene un directorio usado en una conexión de sincronización de directorios. Por favor, elija otro.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>El directorio local %1 está dentro de un directorio usado en una conexión de sincronización de directorios. Por favor, elija otro.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>El directorio local %1 es un enlace simbólico. El objetivo está incluido en un directorio usado en una conexión de sincronización de directorios. Por favor, elija otro.</translation>
</message>
@ -1260,17 +1260,17 @@ Si continua con la sincronización todos los archivos serán remplazados por su
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Acerca de</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Actualizaciones</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Reiniciar &amp;&amp; Actualizar</translation>
</message>
@ -1350,22 +1350,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Los elementos cuya eliminación está permitida serán eliminados si impiden que un directorio sea eliminado. Esto es útil para sus metadatos.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>No se ha podido abrir el archivo</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>No se pueden guardar cambios en &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Añadir patrón para ignorar</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Añadir nuevo patrón para ignorar:</translation>
</message>
@ -2022,27 +2022,27 @@ No se recomienda usarla.</translation>
<translation>Se ha eliminado el archivo del servidor</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>No se ha podido descargar el archivo completamente.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>El archivo descargado está vacio aunque el servidor dice que deberia haber sido %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>¡El fichero %1 no puede guardarse debido a un conflicto con el nombre de otro fichero local!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>El archivo ha cambiado desde que fue descubierto</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Error al escribir los metadatos en la base de datos</translation>
</message>
@ -2553,6 +2553,11 @@ No se recomienda usarla.</translation>
<source>Allow editing</source>
<translation>Permitir edición</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Quienquiera que posea el vínculo tendrá acceso al archivo/carpeta</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>No se pudo </translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Una antigua sincronización con journaling &apos;%1&apos; fue encontrada, pero no se pudo eliminar. Por favor, asegurate que ninguna aplicación la está utilizando.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Estado no definido.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Preparando la sincronización.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Sincronización en funcionamiento.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>La última sincronización fue exitosa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>El último Sync fue exitoso, pero hubo advertencias en archivos individuales.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Error de configuración.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Interrumpir.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>La sincronización está en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sincronización en pausa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>¡No tenés permisos para escribir el directorio seleccionado!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Acerca de</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Actualizaciones</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation type="unfinished"/>
</message>
@ -1339,22 +1339,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>No se pudo abrir el archivo</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>No se pueden guardar cambios en &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Agregar patrón a ignorar</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Añadir nuevo patrón a ignorar:</translation>
</message>
@ -2010,27 +2010,27 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation type="unfinished"/>
</message>
@ -2541,6 +2541,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Ei suutnud tühistada kataloogi staatust</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Leiti vana sünkroniseeringu zurnaal &apos;%1&apos;, kuid selle eemaldamine ebaõnnenstus. Palun veendu, et seda kasutaks ükski programm.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(varukoopia)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation> (varukoopia %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Määramata staatus.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Oodatakse sünkroonimise alustamist.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Valmistun sünkroniseerima.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Sünkroniseerimine on käimas.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Viimane sünkroniseerimine oli edukas.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Viimane sünkroniseering oli edukas, kuid mõned failid põhjustasid tõrkeid.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Seadistamise viga.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Kasutaja tühistamine.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Sünkroniseerimine on peatatud.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sünkroniseerimine on peatatud)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Sobilikku kausta pole valitud!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Valitud asukoht pole kaust!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Sul puuduvad õigused valitud kataloogi kirjutamiseks!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Info</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Uuendused</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Taaskäivita &amp;&amp; Uuenda</translation>
</message>
@ -1339,22 +1339,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Ei suutunud avada faili</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Ei saa kirjutada muudatusi &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Lisa ignoreerimise muster</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Lisa uus ignoreerimise muster:</translation>
</message>
@ -2011,27 +2011,27 @@ Selle kasutamine pole soovitatav.</translation>
<translation>Fail on serverist kustutatud</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Faili täielik allalaadimine ebaõnnestus.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Faili %1 ei saa salvestada kuna on nime konflikt kohaliku failiga!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Faili on pärast avastamist muudetud</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation type="unfinished"/>
</message>
@ -2542,6 +2542,11 @@ Selle kasutamine pole soovitatav.</translation>
<source>Allow editing</source>
<translation>Luba muutmine</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Ezin izan da karpetaren egoera berrezarri</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Aurkitu da &apos;%1&apos; sinkronizazio erregistro zaharra, baina ezin da ezabatu. Ziurtatu aplikaziorik ez dela erabiltzen ari.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Definitu gabeko egoera.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Itxoiten sinkronizazioa hasteko.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Sinkronizazioa prestatzen.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Sinkronizazioa martxan da.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Azkeneko sinkronizazioa ongi burutu zen.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Azkenengo sinkronizazioa ongi burutu zen, baina banakako fitxategi batzuetan abisuak egon dira.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Konfigurazio errorea.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Erabiltzaileak bertan behera utzi.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Sinkronizazioa pausatuta dago.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sinkronizazioa pausatuta dago)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Ez da karpeta egokirik hautatu!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Hautatutako bidea ez da karpeta bat!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Ez daukazu hautatutako karpetan idazteko baimenik!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Honi buruz</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Eguneraketak</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>Be&amp;rrabiarazi eta Eguneratu</translation>
</message>
@ -1341,22 +1341,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Ezabatzeko baimena duten itemak ezabatuko dira hauek karpeta bat ezabatzea uzten ez badute. Hau meta datuentzat interesgarria da.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Ezin izan da fitxategia ireki</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Ezin izan dira aldaketa idatzi hemen &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Gehitu Baztertzeko Eredua</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Gehitu baztertzeko eredu berria:</translation>
</message>
@ -2013,27 +2013,27 @@ Ez da gomendagarria erabltzea.</translation>
<translation>Fitxategia zerbitzaritik ezabatua izan da</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation type="unfinished"/>
</message>
@ -2544,6 +2544,11 @@ Ez da gomendagarria erabltzea.</translation>
<source>Allow editing</source>
<translation>Baimendu editatzea</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>نمی تواند حالت پوشه را تنظیم مجدد کند</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation> (backup)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation> (پشتیبان %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>موقعیت تعریف نشده</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>آماده سازی برای همگام سازی کردن.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>همگام سازی در حال اجراست</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>آخرین همگام سازی موفقیت آمیز بود</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>خطا در پیکر بندی.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>خارج کردن کاربر.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>همگام سازی فعلا متوقف شده است</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (همگامسازی موقتا متوقف شده است)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>هیچ پوشهی معتبری انتخاب نشده است!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>شما اجازه نوشتن در پوشه های انتخاب شده را ندارید!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>درباره</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>به روز رسانی ها</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation type="unfinished"/>
</message>
@ -1339,22 +1339,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>امکان باز کردن فایل وجود ندارد</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation type="unfinished"/>
</message>
@ -2010,27 +2010,27 @@ It is not advisable to use it.</source>
<translation>فایل از روی سرور حذف شد</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation type="unfinished"/>
</message>
@ -2541,6 +2541,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation>اجازهی ویرایش</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Kansion tilaa ei voitu alustaa</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation> (varmuuskopio)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation> (varmuuskopio %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Määrittelemätön tila.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Odotetaan synkronoinnin aloitusta.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Valmistellaan synkronointia.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Synkronointi on meneillään.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Viimeisin synkronointi suoritettiin onnistuneesti.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Viimeisin synkronointi onnistui, mutta yksittäisten tiedostojen kanssa ilmeni varoituksia.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Asetusvirhe.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Synkronointi on keskeytetty.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synkronointi on keskeytetty)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Kelvollista kansiota ei ole valittu!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Valittu polku ei ole kansio!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Sinulla ei ole kirjoitusoikeutta valittuun kansioon!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Paikallinen kansio %1 sisältää kansion, jota käytetään kansion synkronointiyhteydessä. Valitse toinen kansio!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Tietoja</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Päivitykset</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Käynnistä uudelleen &amp;&amp; päivitä</translation>
</message>
@ -1341,22 +1341,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Kohteet, joiden poisto on sallittu, poistetaan, jos ne estävät kansion poistamisen. Tämä on hyödyllistä metatietojen osalta.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Tiedoston avaaminen ei onnistunut</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Muutoksien kirjoittaminen kohteeseen &apos;%1&apos; epäonnistui.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Lisää ohituskaava</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Lisää uusi ohituskaava:</translation>
</message>
@ -2013,27 +2013,27 @@ Osoitteen käyttäminen ei ole suositeltavaa.</translation>
<translation>Tiedosto poistettiin palvelimelta</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Tiedostoa ei voitu ladata täysin.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Tiedosto on muuttunut löytymisen jälkeen</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Virhe kirjoittaessa metadataa tietokantaan</translation>
</message>
@ -2544,6 +2544,11 @@ Osoitteen käyttäminen ei ole suositeltavaa.</translation>
<source>Allow editing</source>
<translation>Salli muokkaus</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -813,112 +813,112 @@ Continuer la synchronisation comme d&apos;habitude fera en sorte que tous les fi
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Impossible de réinitialiser l&apos;état du dossier</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Un ancien fichier journal &apos;%1&apos; a é trouvé, mais ne peut être supprimé. Veuillez vous assurer quaucune application ne l&apos;utilise en ce moment.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(sauvegarde)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(sauvegarde %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Statut indéfini.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>En attente de synchronisation.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Préparation de la synchronisation.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Synchronisation en cours</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Synchronisation terminée avec succès</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Synchronisation terminée avec des avertissements pour certains fichiers</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Erreur d&apos;installation.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Abandon par l&apos;utilisateur.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>La synchronisation est en pause.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronisation en pause)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Aucun dossier valable sélectionné !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Le chemin sélectionné n&apos;est pas un dossier !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Vous n&apos;avez pas la permission d&apos;écrire dans le dossier sélectionné !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>Le dossier local %1 contient un lien symbolique. La cible du lien contient un dossier déjà synchronisé. Veuillez en choisir un autre !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Il y a déjà une synchronisation depuis le serveur vers ce dossier local. Merci de choisir un autre dossier local !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Le dossier local %1 contient un dossier déjà utilisé pour une synchronisation de dossiers. Veuillez en choisir un autre !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Le dossier local %1 se trouve dans un dossier déjà configuré pour une synchronisation de dossier. Veuillez en choisir un autre !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Le dossier local %1 est un lien symbolique. Le dossier vers lequel le lien pointe est inclus dans un dossier déjà configuré pour une synchronisation de dossier. Veuillez en choisir un autre !</translation>
</message>
@ -1261,17 +1261,17 @@ Continuer la synchronisation comme d&apos;habitude fera en sorte que tous les fi
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>À propos</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Mises à jour</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Redémarrer &amp;&amp; Mettre à jour</translation>
</message>
@ -1351,22 +1351,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
L&apos;option &quot;Autoriser suppression&quot; permet de ne pas bloquer la suppression d&apos;un dossier. C&apos;est utile pour les fichiers de méta-données.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Impossible d&apos;ouvrir le fichier</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Impossible d&apos;écrire les modifications sur &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Ajouter un motif d&apos;exclusion</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Ajoutez un nouveau motif d&apos;exclusion :</translation>
</message>
@ -2024,27 +2024,27 @@ Il est déconseillé de l&apos;utiliser.</translation>
<translation>Le fichier a é supprimé du serveur</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Le fichier n&apos;a pas pu être téléchargé intégralement.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Le fichier téléchargé est vide bien que le serveur indique que sa taille devrait être de %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Le fichier %1 n&apos;a pas pu être sauvegardé en raison d&apos;un conflit sur le nom du fichier local !</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Le fichier a changé depuis sa découverte</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Erreur à l&apos;écriture des métadonnées dans la base de données</translation>
</message>
@ -2555,6 +2555,11 @@ Il est déconseillé de l&apos;utiliser.</translation>
<source>Allow editing</source>
<translation>Permettre la modification</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Quiconque dispose du lien a accès aux fichiers/dossiers</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Non foi posíbel restabelecer o estado do cartafol</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Atopouse un rexistro de sincronización antigo en «%1» máis non pode ser retirado. Asegúrese de que non o está a usar ningunha aplicación.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(copia de seguranza)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(copia de seguranza %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Estado sen definir.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Preparando para sincronizar.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Estase sincronizando.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>A última sincronización fíxose correctamente.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>A última sincronización fíxose correctamente, mais con algún aviso en ficheiros individuais.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Erro de configuración.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Interrompido polo usuario.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Sincronización en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (sincronización en pausa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Non seleccionou ningún cartafol correcto!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Vostede non ten permiso para escribir neste cartafol!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Sobre</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Actualizacións</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Reiniciar e actualizar</translation>
</message>
@ -1339,22 +1339,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Non foi posíbel abrir o ficheiro</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Non é posíbel escribir os cambios en «%1».</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Engadir o patrón a ignorar</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Engadir un novo patrón a ignorar:</translation>
</message>
@ -2012,27 +2012,27 @@ Recomendámoslle que non o use.</translation>
<translation>O ficheiro vai seren eliminado do servidor</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Non foi posíbel descargar completamente o ficheiro.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Non foi posíbel gardar o ficheiro %1 por mor dunha colisión co nome dun ficheiro local!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>O ficheiro cambiou após seren atopado</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation type="unfinished"/>
</message>
@ -2543,6 +2543,11 @@ Recomendámoslle que non o use.</translation>
<source>Allow editing</source>
<translation>Permitir a edición</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(biztonsági mentés)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(biztonsági mentés: %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Ismeretlen állapot.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Várakozás a szinkronizálás elindítására.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Előkészítés szinkronizációhoz.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Szinkronizálás fut.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Legutolsó szinkronizálás sikeres volt.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Az utolsó szinkronizáció sikeresen lefutott, de néhány figyelmeztetés van.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Beállítás hiba.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Felhasználó megszakította.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Szinkronizálás megállítva.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (szinkronizálás megállítva)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Nincs érvényes könyvtár kiválasztva!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>A kiválasztott elérési út nem könyvtár!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Nincs joga a kiválasztott könyvtár írásához!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Rólunk</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Frissítések</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>Új&amp;raindítás és frissítés</translation>
</message>
@ -1339,22 +1339,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Nem sikerült a fájl megnyitása</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation type="unfinished"/>
</message>
@ -2010,27 +2010,27 @@ It is not advisable to use it.</source>
<translation>A fájl törlésre került a szerverről</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation type="unfinished"/>
</message>
@ -2541,6 +2541,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation>Szerkesztés engedélyezése</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -541,7 +541,7 @@
<message>
<location filename="../src/gui/application.cpp" line="172"/>
<source>There was an error while accessing the configuration file at %1.</source>
<translation type="unfinished"/>
<translation>Si è verificato un errore durante l&apos;accesso al file di configurazione su %1.</translation>
</message>
<message>
<location filename="../src/gui/application.cpp" line="174"/>
@ -808,112 +808,112 @@ Se continui normalmente la sincronizzazione provocherai la sovrascrittura di tut
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Impossibile ripristinare lo stato della cartella</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>È stato trovato un vecchio registro di sincronizzazione &apos;%1&apos;, ma non può essere rimosso. Assicurati che nessuna applicazione lo stia utilizzando.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(copia di sicurezza)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(copia di sicurezza %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Stato non definito.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>In attesa di iniziare la sincronizzazione.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Preparazione della sincronizzazione.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>La sincronizzazione è in corso.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>L&apos;ultima sincronizzazione è stata completata correttamente.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Ultima sincronizzazione avvenuta, ma con avvisi relativi a singoli file.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Errore di configurazione.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Interrotto dall&apos;utente.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>La sincronizzazione è sospesa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation> %1 (La sincronizzazione è sospesa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Nessuna cartella valida selezionata!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Il percorso selezionato non è una cartella!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Non hai i permessi di scrittura per la cartella selezionata!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>La cartella locale %1 contiene un collegamento simbolico. La destinazione del collegamento contiene una cartella già sincronizzata. Selezionane un&apos;altra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Esiste già una sincronizzazione dal server a questa cartella locale. Seleziona un&apos;altra cartella locale!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>La cartella locale %1 contiene già una cartella utilizzata in una connessione di sincronizzazione delle cartelle. Selezionane un&apos;altra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>La cartella locale %1 è già contenuta in una cartella utilizzata in una connessione di sincronizzazione delle cartelle. Selezionane un&apos;altra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>La cartella locale %1 è un collegamento simbolico. La destinazione del collegamento è già contenuta in una cartella utilizzata in una connessione di sincronizzazione delle cartelle. Selezionane un&apos;altra!</translation>
</message>
@ -1256,17 +1256,17 @@ Se continui normalmente la sincronizzazione provocherai la sovrascrittura di tut
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Informazioni</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Aggiornamenti</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Riavvia e aggiorna</translation>
</message>
@ -1346,22 +1346,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Gli elementi per i quali è consentita l&apos;eliminazione, saranno eliminati se impediscono la rimozione di una cartella. Utile per i metadati.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Impossibile aprire il file</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Impossibile scrivere le modifiche in &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Aggiungi modello Ignora</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Aggiungi un nuovo modello di esclusione:</translation>
</message>
@ -2018,27 +2018,27 @@ Non è consigliabile utilizzarlo.</translation>
<translation>Il file è stato eliminato dal server</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Il file non può essere scaricato completamente.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Il file scaricato è vuoto nonostante il server indicasse una dimensione di %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Il file %1 non può essere salvato a causa di un conflitto con un file locale.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Il file è stato modificato dal suo rilevamento</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Errore durante la scrittura dei metadati nel database</translation>
</message>
@ -2176,7 +2176,7 @@ Non è consigliabile utilizzarlo.</translation>
<message>
<location filename="../src/libsync/propagateupload.cpp" line="204"/>
<source>File %1 cannot be uploaded because another file with the same name, differing only in case, exists</source>
<translation type="unfinished"/>
<translation>Il file %1 non può essere caricato poiché esiste un altro file con lo stesso nome, ma con differenze tra maiuscole e minuscole</translation>
</message>
<message>
<location filename="../src/libsync/propagateupload.cpp" line="312"/>
@ -2369,7 +2369,7 @@ Non è consigliabile utilizzarlo.</translation>
<message>
<location filename="../src/gui/selectivesyncdialog.cpp" line="71"/>
<source>Deselect remote folders you do not wish to synchronize.</source>
<translation type="unfinished"/>
<translation>Deseleziona le cartelle remote che non desideri sincronizzare.</translation>
</message>
<message>
<location filename="../src/gui/selectivesyncdialog.cpp" line="91"/>
@ -2549,6 +2549,11 @@ Non è consigliabile utilizzarlo.</translation>
<source>Allow editing</source>
<translation>Consenti la modifica</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Chiunque sia in possesso del collegamento ha accesso al file/cartella</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>
@ -3074,12 +3079,12 @@ Non è consigliabile utilizzarlo.</translation>
<message>
<location filename="../src/libsync/syncengine.cpp" line="455"/>
<source>File names ending with a period are not supported on this file system.</source>
<translation type="unfinished"/>
<translation>I nomi del file che terminano con un punto non sono supportati su questo file system.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="465"/>
<source>File names containing the character &apos;%1&apos; are not supported on this file system.</source>
<translation type="unfinished"/>
<translation>I nomi del file che contengono il carattere &apos;%1&apos; non sono supportati su questo file system.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="468"/>
@ -3488,7 +3493,7 @@ Non è consigliabile utilizzarlo.</translation>
<message>
<location filename="../src/gui/wizard/owncloudadvancedsetuppage.ui" line="301"/>
<source>Ask for confirmation before synchroni&amp;zing folders larger than</source>
<translation type="unfinished"/>
<translation>Chiedi conferma prima di sincroni&amp;zzare cartelle più grandi di</translation>
</message>
<message>
<location filename="../src/gui/wizard/owncloudadvancedsetuppage.ui" line="318"/>
@ -3499,7 +3504,7 @@ Non è consigliabile utilizzarlo.</translation>
<message>
<location filename="../src/gui/wizard/owncloudadvancedsetuppage.ui" line="327"/>
<source>Ask for confirmation before synchronizing e&amp;xternal storages</source>
<translation type="unfinished"/>
<translation>Chiedi conferma prima di sincroni&amp;zzare archiviazioni esterne</translation>
</message>
<message>
<location filename="../src/gui/wizard/owncloudadvancedsetuppage.ui" line="351"/>
@ -3795,7 +3800,7 @@ Non è consigliabile utilizzarlo.</translation>
<message>
<location filename="../src/libsync/theme.cpp" line="305"/>
<source>built with %1</source>
<translation type="unfinished"/>
<translation>creato con %1</translation>
</message>
</context>
<context>

View File

@ -810,112 +810,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation> &apos;%1&apos; 使</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>()</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(%1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 ()</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation> %1 </translation>
</message>
@ -1258,17 +1258,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>(&amp;R)</translation>
</message>
@ -1348,22 +1348,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>:</translation>
</message>
@ -2019,27 +2019,27 @@ It is not advisable to use it.</source>
<translation></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation></translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation></translation>
</message>
@ -2550,6 +2550,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation></translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -811,112 +811,112 @@ Hvis synkroniseringen fortsetter som normalt, vil alle filene dine bli overskrev
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Klarte ikke å tilbakestille mappetilstand</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>En gammel synkroniseringsjournal &apos;%1&apos; ble funnet men kunne ikke fjernes. Pass at ingen applikasjoner bruker den.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation> (sikkerhetskopi)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation> (sikkerhetskopi %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Udefinert tilstand.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Venter å starte synkronisering.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Forbereder synkronisering.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Synkronisering kjører.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Siste synkronisering var vellykket.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Siste synkronisering var vellykket, men med advarsler enkelte filer.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Feil med oppsett.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Brukeravbrudd.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Synkronisering er satt pause.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synkronisering er satt pause)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Ingen gyldig mappe valgt!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Den valgte stien er ikke en mappe!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Du har ikke skrivetilgang til den valgte mappen!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>Den lokale mappen %1 inneholder en symbolsk lenke. Målet for lenken inneholder en mappe som allerede er synkronisert. Velg en annen mappe!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Det er allerede en synkronisering fra serveren til denne lokale mappen. Velg en annen mappe!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Den lokale mappen %1 inneholder allerede en mappe brukt i en mappe-synkronisering. Velg en annen!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Den lokale mappen %1 er allerede en undermappe av en mappe brukt i en mappe-synkronisering. Velg en annen!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Den lokale mappen %1 er en symbolsk lenke. Målet for lenken er allerede en undermappe av en mappe brukt i en mappe-synkronisering. Velg en annen!</translation>
</message>
@ -1259,17 +1259,17 @@ Hvis synkroniseringen fortsetter som normalt, vil alle filene dine bli overskrev
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Om</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Oppdateringer</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Omstart &amp;&amp; Oppdater</translation>
</message>
@ -1349,22 +1349,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Elementer hvor sletting er tillatt, vil bli slettet hvis de forhindrer fjerning av en mappe. Dette er hendig for metadata.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Klarte ikke å åpne fil</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Kan ikke skrive endringer til &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Nytt mønster</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Legg til ignoreringsmønster:</translation>
</message>
@ -2022,27 +2022,27 @@ Det er ikke tilrådelig å bruke den.</translation>
<translation>Filen ble slettet fra serveren</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Hele filen kunne ikke lastes ned.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Nedlastet fil er tom, selv om serveren annonserte at den skulle være %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Fil %1 kan ikke lagres grunn av lokal konflikt med filnavn.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Filen er endret siden den ble oppdaget</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Feil ved skriving av metadata til databasen</translation>
</message>
@ -2553,6 +2553,11 @@ Det er ikke tilrådelig å bruke den.</translation>
<source>Allow editing</source>
<translation>Tillat redigering</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -811,112 +811,112 @@ Doorgaan met deze synchronisatie overschrijft al uw bestanden door een eerdere v
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Kan de beginstaat van de map niet terugzetten</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Een oud synchronisatieverslag &apos;%1&apos; is gevonden maar kan niet worden verwijderd. Zorg ervoor dat geen applicatie dit bestand gebruikt.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(backup)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(backup %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Ongedefiniëerde staat</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>In afwachting van synchronisatie.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Synchronisatie wordt voorbereid</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Bezig met synchroniseren.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Laatste synchronisatie was geslaagd.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Laatste synchronisatie geslaagd, maar met waarschuwingen over individuele bestanden.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Installatiefout.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Afgebroken door gebruiker.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Synchronisatie gepauzeerd.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronisatie onderbroken)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Geen geldige map geselecteerd!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Het geselecteerde pad is geen map!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>U heeft geen permissie om te schrijven naar de geselecteerde map!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>Lokale map %1 bevat een symbolische link. De doellink bevat een map die al is gesynchroniseerd. Kies een andere!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Er wordt vanaf de server al naar deze lokale map gesynchroniseerd. Kies een andere lokale map!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Lokale map %1 bevat al een map die wordt gebruikt voor een mapsync verbinding. Kies een andere!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Lokale map %1 zit al in een map die wordt gebruikt voor een mapsync verbinding. Kies een andere!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Lokale map %1 is een symbolische link. De doellink zit al in een map die in een mapsync verbinding wordt gebruikt. Kies een andere!</translation>
</message>
@ -1260,17 +1260,17 @@ Doorgaan met deze synchronisatie overschrijft al uw bestanden door een eerdere v
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Over</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Updates</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Herstarten en &amp;Bijwerken</translation>
</message>
@ -1354,22 +1354,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een map verdwijnt. Dit is nuttig voor metadata.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Kon het bestand niet openen</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Er kunnen geen wijzigingen worden geschreven naar %1</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Toevoegen negeerpatroon</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Voeg nieuw negeerpatroon toe:</translation>
</message>
@ -2027,27 +2027,27 @@ We adviseren deze site niet te gebruiken.</translation>
<translation>Bestand was verwijderd van de server</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Het bestand kon niet volledig worden gedownload.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Het gedownloade bestand is leeg, hoewel de server meldde dat het %1 zou moeten zijn.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Bestand %1 kan niet worden opgeslagen wegens een lokaal bestandsnaam conflict!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Het bestand is gewijzigd sinds het is gevonden</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Fout bij schrijven van Metadata naar de database</translation>
</message>
@ -2558,6 +2558,11 @@ We adviseren deze site niet te gebruiken.</translation>
<source>Allow editing</source>
<translation>Toestaan bewerken</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Iedereen met de link heeft toegang tot het bestand of de map</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -805,112 +805,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Nie udało się zresetować stanu folderu</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Stary sync journal &apos;%1&apos; został znaleziony, lecz nie mógł być usunięty. Proszę się upewnić, że żaden program go obecnie nie używa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(kopia zapasowa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(kopia zapasowa %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Niezdefiniowany stan</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Poczekaj na rozpoczęcie synchronizacji.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Przygotowuję do synchronizacji</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Synchronizacja w toku</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Ostatnia synchronizacja zakończona powodzeniem.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Ostatnia synchronizacja udana, ale istnieją ostrzeżenia z pojedynczymi plikami.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Błąd ustawień.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Użytkownik anulował.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Synchronizacja wstrzymana</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation> %1 (Synchronizacja jest zatrzymana)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Nie wybrano poprawnego folderu.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Wybrana ścieżka nie jest katalogiem!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Nie masz uprawnień, aby zapisywać w tym katalogu!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Lokalny folder %1 już zawiera folder użyty na potrzeby synchronizacji. Proszę wybrać inny folder lokalny.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Lokalny folder %1 już zawiera folder użyty na potrzeby synchronizacji. Proszę wybrać inny folder lokalny.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1253,17 +1253,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>O aplikacji</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Aktualizacje</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Zrestartuj &amp;&amp; Aktualizuj</translation>
</message>
@ -1343,22 +1343,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Pozycje, dla których usuwanie jest dozwolone zostaną usunięte, jeżeli uprawnienia katalogu dopuszczają usuwanie.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Nie można otworzyć plików</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Nie mogę zapisać zmian do &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Dodaj ignorowany</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Dodaj nowy ignorowany:</translation>
</message>
@ -2016,27 +2016,27 @@ Niezalecane jest jego użycie.</translation>
<translation>Plik został usunięty z serwera</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Ten plik nie mógł być całkowicie pobrany.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Błąd podczas zapisu metadanych do bazy</translation>
</message>
@ -2547,6 +2547,11 @@ Niezalecane jest jego użycie.</translation>
<source>Allow editing</source>
<translation>Pozwól na edycję</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Każdy posiadający link ma dostęp do pliku/katalogu.</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -812,112 +812,112 @@ Continuando a sincronização fará com que todos os seus ficheiros sejam substi
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Não foi possível reiniciar o estado da pasta</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Foi encontrado um &apos;journal&apos; de sincronização, mas não foi possível removê-lo. Por favor, certifique-se que nenhuma aplicação o está a utilizar.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(cópia de segurança)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(cópia de segurança %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Estado indefinido.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>A aguardar para iniciar a sincronização.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>A preparar para sincronizar.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>A sincronização está em execução.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>A última sincronização foi bem sucedida.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>A última sincronização foi bem sucedida, mas com avisos nos ficheiros individuais.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Erro de instalação.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Abortado pelo utilizador.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>A sincronização está pausada.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (A sincronização está pausada)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Não foi selecionada nenhuma pasta válida!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>O caminho selecionado não é uma pasta!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Não tem permissão para gravar para a pasta selecionada!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>A pasta local %1 contém hiperligação simbólica. O destino da hiperligação contém uma pasta sincronizada. Por favor, escolha outra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation> existe uma sincronização do servidor para esta pasta local. Por favor escolha outra pasta local!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>A pasta local %1 contém uma pasta utilizada numa ligação de sincronização de pasta. Por favor, escolha outra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>A pasta local %1 contém uma pasta usada numa ligação de sincronização de pasta. Por favor, escolha outra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>A pasta local %1 é uma hiperligação simbólica. A hiperligação de destino contém uma pasta usada numa ligação de sincronização de pasta. Por favor, escolha outra!</translation>
</message>
@ -1260,17 +1260,17 @@ Continuando a sincronização fará com que todos os seus ficheiros sejam substi
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Sobre</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Atualizações</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Reiniciar e Atualizar</translation>
</message>
@ -1350,22 +1350,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Os itens onde é permitido a eliminação serão eliminados se estes impedirem a remoção de uma diretoria. Isto é útil para os metadados.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Não foi possível abrir o ficheiro</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Não foi possível gravar as alterações para &apos;%1&apos;</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Adicione Padrão de ignorar</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Adicione um novo padrão de ignorar:</translation>
</message>
@ -2023,27 +2023,27 @@ Não é aconselhada a sua utilização.</translation>
<translation>O ficheiro foi eliminado do servidor</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Não foi possível transferir o ficheiro na totalidade.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>O ficheiro transferido está vazio, apesar do servidor indicar que este deveria ter %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Ficheiro %1 não pode ser guardado devido à existência de um ficheiro local com o mesmo nome.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>O ficheiro alterou-se desde a sua descoberta</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Erro ao gravar os metadados para a base de dados</translation>
</message>
@ -2554,6 +2554,11 @@ Não é aconselhada a sua utilização.</translation>
<source>Allow editing</source>
<translation>Permitir edição</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Qualquer pessoa com a hiperligação terá acesso ao ficheiro/pasta</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -810,112 +810,112 @@ Continuar a sincronização como normal fará com que todos os seus arquivos sej
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Não foi possível redefinir o estado da pasta</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Uma velha revista de sincronização &apos;%1&apos; foi encontrada, mas não pôde ser removida. Por favor, certifique-se de que nenhuma aplicação está a usá-la.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation> (backup)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation> (backup %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Estado indefinido.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>À espera do início da sincronização.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Preparando para sincronização.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>A sincronização está ocorrendo.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>A última sincronização foi feita com sucesso.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>A última sincronização foi executada com sucesso, mas com advertências em arquivos individuais.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Erro de Configuração.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Usuário Abortou.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Sincronização pausada.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Pausa na Sincronização) </translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Nenhuma pasta válida selecionada!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>O caminho selecionado não é uma pasta!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Voce não tem permissão para escrita na pasta selecionada!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>A pasta local %1 contém um link simbólico. O destino do link contém uma pasta sincronizados. Por favor, escolha uma outra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation> existe uma sincronização do servidor para esta pasta local. Por favor, escolha uma outra pasta local!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>A pasta local %1 contém uma pasta utilizada numa ligação de sincronização de pasta. Por favor, escolha outra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>A pasta local %1 está contida em uma pasta usada em uma conexão de sincronização de pastas. Por favor, escolha outra!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>A pasta local %1 é um link simbólico. O destino do link está contido em uma pasta usada em uma conexão de sincronização de pastas. Por favor, escolha outra!</translation>
</message>
@ -1091,7 +1091,7 @@ Continuar a sincronização como normal fará com que todos os seus arquivos sej
<message>
<location filename="../src/gui/folderwizard.cpp" line="66"/>
<source>Click to select a local folder to sync.</source>
<translation>Click para selecionar uma pasta local para sincronização.</translation>
<translation>Clique para selecionar uma pasta local para sincronização.</translation>
</message>
<message>
<location filename="../src/gui/folderwizard.cpp" line="70"/>
@ -1258,17 +1258,17 @@ Continuar a sincronização como normal fará com que todos os seus arquivos sej
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>Sobre</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Atualizações</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Reiniciar &amp;&amp; Atualização
</translation>
@ -1294,7 +1294,7 @@ Continuar a sincronização como normal fará com que todos os seus arquivos sej
<message>
<location filename="../src/gui/creds/httpcredentialsgui.cpp" line="86"/>
<source>&lt;a href=&quot;%1&quot;&gt;Click here&lt;/a&gt; to request an app password from the web interface.</source>
<translation>&lt;a href=&quot;%1&quot;&gt;Click aqui&lt;/a&gt; para solicitar uma senha de aplicativo na interface da web.</translation>
<translation>&lt;a href=&quot;%1&quot;&gt;Clique aqui&lt;/a&gt; para solicitar uma senha de aplicativo na interface da web.</translation>
</message>
</context>
<context>
@ -1349,22 +1349,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Itens onde a eliminação é permitida serão excluídos se eles evitarem que um diretório seja removido. Isso é útil para metadados.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Não foi possível abrir o arquivo</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Não é possível gravar as alterações em &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Adicionar Ignorar Padrão</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Adicionar um novo padrão ignorar:</translation>
</message>
@ -1468,7 +1468,7 @@ Itens onde a eliminação é permitida serão excluídos se eles evitarem que um
<message>
<location filename="../src/gui/updater/ocupdater.cpp" line="355"/>
<source>Skip this time</source>
<translation>Pular desta vêz</translation>
<translation>Pular desta vez</translation>
</message>
<message>
<location filename="../src/gui/updater/ocupdater.cpp" line="356"/>
@ -2020,27 +2020,27 @@ It is not advisable to use it.</source>
<translation>O arquivo foi eliminado do servidor</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>O arquivo não pode ser baixado completamente.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>O arquivo baixado está vazio apesar do servidor anunciou que deveria ter %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>O arquivo %1 não pode ser salvo devido a um confronto com um nome de arquivo local!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Arquivo foi alterado desde a descoberta</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Ocorreu um erro ao escrever metadados ao banco de dados</translation>
</message>
@ -2551,6 +2551,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation>Permitir edição</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Qualquer pessoa com o link tem acesso ao arquivo/pasta</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -810,112 +810,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Невозможно сбросить состояние каталога</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Найден старый журнал синхронизации &apos;%1&apos;, и он не может быть удалён. Убедитесь что он не открыт в другом приложении.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation>(резервная копия)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation>(резервная копия %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Неопределенное состояние.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Ожидание запуска синхронизации.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Подготовка к синхронизации.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Идет синхронизация.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Последняя синхронизация прошла успешно.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Последняя синхронизация прошла успешно, но были предупреждения для некоторых файлов.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Ошибка установки.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Отмена пользователем.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Синхронизация приостановлена.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%! (синхронизация приостановлена)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Не выбран валидный каталог!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Выбранный путь не является каталогом!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>У вас недостаточно прав для записи в выбранный каталог!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation>Локальный каталог %1 содержит символьную ссылку. Место, на которое указывает ссылка, уже содержит засинхронизированный каталог. Пожалуйста, выберите другой!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation>Уже есть синхронизация с сервера в этот локальный каталог. Пожалуйста, выберите другой локальный каталог!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation>Локальная директория %1 уже содержит папку, которая используется для синхронизации. Пожалуйста выберите другую!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Локальная директория %1 уже содержит директорию, которая используется для синхронизации. Пожалуйста выберите другую!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation>Локальная директория %1 является символьной ссылкой. Эта ссылка указывает на путь, находящийся внутри директории, уже используемой для синхронизации. Пожалуйста укажите другую!</translation>
</message>
@ -1258,17 +1258,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>О программе</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Обновления</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Перезапуск и обновление</translation>
</message>
@ -1347,22 +1347,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
Элементы, где это разрешается, будут удалены, в случае если они помешают удалению папки. Используется для метаданных.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Невозможно открыть файл</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Невозможно записать изменения в &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Добавить шаблон игнорирования</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Добавить новый шаблон игнорирования:</translation>
</message>
@ -2020,27 +2020,27 @@ It is not advisable to use it.</source>
<translation>Файл был удален с сервера</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Невозможно полностью загрузить файл.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation>Скачанный файл пуст, хотя сервер заявил, что он должен быть %1.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Файл %1 не может быть сохранён из-за локального конфликта имен!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>После обнаружения файл был изменен</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Ошибка записи метаданных в базу данных</translation>
</message>
@ -2551,6 +2551,11 @@ It is not advisable to use it.</source>
<source>Allow editing</source>
<translation>Разрешить редактирование</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation>Каждый, у кого есть эта ссылка, имеет доступ к файлу/каталогу</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

View File

@ -803,112 +803,112 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<context>
<name>OCC::FolderMan</name>
<message>
<location filename="../src/gui/folderman.cpp" line="295"/>
<location filename="../src/gui/folderman.cpp" line="306"/>
<source>Could not reset folder state</source>
<translation>Nemožno resetovať stav priečinka</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="296"/>
<location filename="../src/gui/folderman.cpp" line="307"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation>Starý synchronizačný žurnál &apos;%1&apos; nájdený, avšak neodstrániteľný. Prosím uistite sa, že žiadna aplikácia ho práve nevyužíva.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1032"/>
<location filename="../src/gui/folderman.cpp" line="1043"/>
<source> (backup)</source>
<translation> (záloha)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1037"/>
<location filename="../src/gui/folderman.cpp" line="1048"/>
<source> (backup %1)</source>
<translation> (záloha %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1244"/>
<location filename="../src/gui/folderman.cpp" line="1255"/>
<source>Undefined State.</source>
<translation>Nedefinovaný stav.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1247"/>
<location filename="../src/gui/folderman.cpp" line="1258"/>
<source>Waiting to start syncing.</source>
<translation>Čaká sa na začiatok synchronizácie</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1250"/>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<source>Preparing for sync.</source>
<translation>Príprava na synchronizáciu.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1253"/>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<source>Sync is running.</source>
<translation>Synchronizácia prebieha.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1256"/>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<source>Last Sync was successful.</source>
<translation>Posledná synchronizácia sa úspešne skončila.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1261"/>
<location filename="../src/gui/folderman.cpp" line="1272"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Posledná synchronizácia bola úspešná, ale s varovaniami pre individuálne súbory.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1264"/>
<location filename="../src/gui/folderman.cpp" line="1275"/>
<source>Setup Error.</source>
<translation>Chyba pri inštalácii.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1267"/>
<location filename="../src/gui/folderman.cpp" line="1278"/>
<source>User Abort.</source>
<translation>Zrušené používateľom.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1270"/>
<location filename="../src/gui/folderman.cpp" line="1281"/>
<source>Sync is paused.</source>
<translation>Synchronizácia je pozastavená.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1276"/>
<location filename="../src/gui/folderman.cpp" line="1287"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronizácia je pozastavená)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1284"/>
<location filename="../src/gui/folderman.cpp" line="1295"/>
<source>No valid folder selected!</source>
<translation>Nebol zvolený platný priečinok.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1294"/>
<location filename="../src/gui/folderman.cpp" line="1305"/>
<source>The selected path is not a folder!</source>
<translation>Zvolená cesta nie je priečinok.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1298"/>
<location filename="../src/gui/folderman.cpp" line="1309"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Nemáte oprávnenia pre zápis do daného priečinka!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1349"/>
<location filename="../src/gui/folderman.cpp" line="1360"/>
<source>The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1364"/>
<location filename="../src/gui/folderman.cpp" line="1375"/>
<source>There is already a sync from the server to this local folder. Please pick another local folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1322"/>
<location filename="../src/gui/folderman.cpp" line="1333"/>
<source>The local folder %1 already contains a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1332"/>
<location filename="../src/gui/folderman.cpp" line="1343"/>
<source>The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1341"/>
<location filename="../src/gui/folderman.cpp" line="1352"/>
<source>The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
@ -1251,17 +1251,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="150"/>
<location filename="../src/gui/generalsettings.ui" line="156"/>
<location filename="../src/gui/generalsettings.ui" line="162"/>
<source>About</source>
<translation>O</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="166"/>
<location filename="../src/gui/generalsettings.ui" line="172"/>
<source>Updates</source>
<translation>Aktualizácie</translation>
</message>
<message>
<location filename="../src/gui/generalsettings.ui" line="191"/>
<location filename="../src/gui/generalsettings.ui" line="197"/>
<source>&amp;Restart &amp;&amp; Update</source>
<translation>&amp;Restart &amp;&amp; aktualizácia</translation>
</message>
@ -1339,22 +1339,22 @@ Items where deletion is allowed will be deleted if they prevent a directory from
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="112"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="115"/>
<source>Could not open file</source>
<translation>Nemožno otvoriť súbor</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="113"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="116"/>
<source>Cannot write changes to &apos;%1&apos;.</source>
<translation>Nemožno zapísať zmeny do &apos;%1&apos;.</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="140"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="143"/>
<source>Add Ignore Pattern</source>
<translation>Pridať vzor ignorovaného súboru</translation>
</message>
<message>
<location filename="../src/gui/ignorelisteditor.cpp" line="141"/>
<location filename="../src/gui/ignorelisteditor.cpp" line="144"/>
<source>Add a new ignore pattern:</source>
<translation>Pridať nový vzor ignorovaného súboru:</translation>
</message>
@ -2012,27 +2012,27 @@ Nie je vhodné ju používať.</translation>
<translation>Súbor bol vymazaný zo servera</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="549"/>
<location filename="../src/libsync/propagatedownload.cpp" line="554"/>
<source>The file could not be downloaded completely.</source>
<translation>Súbor sa nedá stiahnuť úplne.</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="556"/>
<location filename="../src/libsync/propagatedownload.cpp" line="561"/>
<source>The downloaded file is empty despite the server announced it should have been %1.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="715"/>
<location filename="../src/libsync/propagatedownload.cpp" line="720"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation>Súbor %1 nie je možné uložiť, pretože jeho názov koliduje s názvom lokálneho súboru!</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="764"/>
<location filename="../src/libsync/propagatedownload.cpp" line="769"/>
<source>File has changed since discovery</source>
<translation>Súbor sa medzitým zmenil</translation>
</message>
<message>
<location filename="../src/libsync/propagatedownload.cpp" line="814"/>
<location filename="../src/libsync/propagatedownload.cpp" line="819"/>
<source>Error writing metadata to the database</source>
<translation>Chyba pri zápise metadát do databázy</translation>
</message>
@ -2543,6 +2543,11 @@ Nie je vhodné ju používať.</translation>
<source>Allow editing</source>
<translation>Povoliť úpravy</translation>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.ui" line="267"/>
<source>Anyone with the link has access to the file/folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/sharelinkwidget.cpp" line="95"/>
<source>P&amp;assword protect</source>

Some files were not shown because too many files have changed in this diff Show More