Comparar commits

...

91 Commits

Autor SHA1 Mensagem Data
Klaas Freitag acdcc9ee50 Dolphin Plugin: Use the Application name for the socket path
do not hardcode.

This should fix #5165
2016-09-12 13:50:41 +02:00
Olivier Goffart 1d09f6b60f Allow to disable Shiboleth to build without QtWebkit (#5166) 2016-09-11 16:14:08 +02:00
Olivier Goffart 98268d102f ExcludeFiles: Fix when the folder casing is not the same in the settings and in the FS
If the folder has different case in the settings and in the FS, we should
not ignore all the files. This is important for the files system watcher.
2016-09-11 12:12:10 +02:00
Olivier Goffart 9e895a6ecc FolderStatusModel: Fix beginInsertRow/endInsertRow
We need to do the change between the begin and the end call so the selection
don't get broken
2016-09-11 12:12:10 +02:00
Markus Goetz 524220d090 Selective Sync: Fix request loop and show error in view (#5154)
I got into a situation where the model would endlessly request the directory
contents from the server because we did not notice yet that the server
is actually in maintenance mode while we were expanding the tree view when
changing the tab to the account or when just expanding it by clicking.
2016-09-06 11:11:03 +02:00
Christian Kamm af9c4d0e2f Recall: Copy instead of move recalled file #5150
That was an unintentional change in
2662203fb7

Also expand the test case to cover this.
2016-09-06 10:42:59 +02:00
Klaas Freitag c97d8aa8fd Show the rename target in the client log file. (#5149) 2016-09-05 13:26:49 +02:00
Olivier Goffart 86eab48981 Qt4 Compile 2016-08-31 10:27:20 +02:00
Olivier Goffart d2bde5489f Propagator, remove the QNAM in the name as the alternative has been removed a long time ago 2016-08-31 10:25:06 +02:00
Christian Kamm 39e93768ea Account wizard: Enable back button consistently #5107
Tested with http auth and shib auth.
2016-08-26 13:12:25 +02:00
Christian Kamm c1eb9244d1 Shibboleth: Fix detection in account wizard #5138
Following redirections generally
(bb5c2cbfa5) meant that the special
shib-redirection detection code was no longer being used.
2016-08-26 12:58:06 +02:00
Markus Goetz 6ecda6e7f4 Merge branch '2.2' 2016-08-24 11:39:12 +02:00
Jenkins for ownCloud 7362575d64 [tx-robot] updated from transifex 2016-08-24 02:18:30 +02:00
Jenkins for ownCloud 6a9b6c1167 [tx-robot] updated from transifex 2016-08-23 02:18:33 +02:00
Jenkins for ownCloud 8e00fd66de [tx-robot] updated from transifex 2016-08-22 02:18:31 +02:00
Jenkins for ownCloud ef035ea7f9 [tx-robot] updated from transifex 2016-08-21 02:18:31 +02:00
Jenkins for ownCloud 77b5c5e963 [tx-robot] updated from transifex 2016-08-20 02:18:31 +02:00
Jenkins for ownCloud 687549c455 [tx-robot] updated from transifex 2016-08-19 09:58:44 +02:00
Jocelyn Turcotte b28123bed9 Fix the Qt4 unit testing build 2016-08-18 10:34:07 +02:00
Jenkins for ownCloud 677c34fbf8 [tx-robot] updated from transifex 2016-08-18 02:18:30 +02:00
Jocelyn Turcotte 2ff7b63551 Merge pull request #5122 from jturcotte/syncfilestatustrackerTests 2016-08-17 16:04:02 +02:00
Christian Kamm b541fea793 ShareLink: Ensure the password line edit is enabled #5117 2016-08-17 15:48:25 +02:00
Jocelyn Turcotte efb6b8c2c9 [overlays] Fix folders appearing as OK even though children are still syncing #4797
This would happen if the directory would first need to be created
through an mkdir propagation job. This job's itemCompleted signal
would trigger the directory to show as SYNC even though its children
are still propagating.

Fix the issue by tracking the sync count for each file, affecting
its parents. This allows us to get rid of the O(n) vector lookup
for each status query, and properly track the hierachical sync
status of a directory.

This also removes the itemCompleted signal emission from the
PropagateDirectory job. Since we only needed for overlay icons, and
since this job doesn't do any direct propagation, we can remove it
to ensure that we won't call itemCompleted twice for the item attached
to Propagate*Mkdir jobs (since the PropagateDirectory is backed by
the same SyncFileItem, instruction and status).
2016-08-17 15:40:02 +02:00
Jocelyn Turcotte e974771796 csync: Use an explicit instruction for should_update_metadata
The current way of tracking the need to update the metadata without
propagation using a separate flag makes it difficult to track
priorities between the local and remote tree. The logic is also
difficult to logically cover since the possibilities matrix isn't
100% covered, leaving the flag only used in a few situations
(mostly involving folders, but not only).

The reason we need to change this is to be able to track the sync
state of files for overlay icons. The instruction alone can't be
used since CSYNC_INSTRUCTION_SYNC is used for folders even though
they won't be propagated. Removing this logic is however not possible
without using something else than CSYNC_INSTRUCTION_NONE since too
many codepath interpret (rightfully) this as meaning "nothing to do".

This patch adds a new CSYNC_INSTRUCTION_UPDATE_METADATA instruction
to let the update and reconcile steps tell the SyncEngine to update
the metadata of a file without any propagation. Other flags are left
to be interpretted by the implementation as implicitly needing
metadata update or not, as this was already the case for most file
propagation jobs. For example, CSYNC_INSTRUCTION_NEW for directories
now also implicitly update the metadata.

Since it's not impossible for folders to emit CSYNC_INSTRUCTION_SYNC
or CSYNC_INSTRUCTION_CONFLICT, the corresponding code paths in the
sync engine have been removed.

Since the reconcile step can now know if the local tree needs metadata
update while the remote side might want propagation, the
localMetadataUpdate logic in SyncEngine::treewalkFile now simply use
a CSYNC_INSTRUCTION_UPDATE_METADATA for the local side, which is now
implemented as a different database query.
2016-08-17 15:39:31 +02:00
Jocelyn Turcotte 82ef1bcfe0 Make sure that we invalidate parents on blacklisted items
Add a missing call that we currently only do in slotItemCompleted.
This would normally only affect the first sync and would have
gotten properly update at the end of the sync anyway.
2016-08-17 15:39:30 +02:00
Jocelyn Turcotte b7ff4a76e8 Add TestSyncEngine and TestSyncFileStatusTracker auto tests
To be able to test the SyncEngine efficiently, a set of server
mocking classes have been implemented on top of QNetworkAccessManager.

The local disk side hasn't been mocked since this would require adding
a large abstraction layer in csync. The SyncEngine is instead pointed
to a different temporary dir in each test and we test by interacting
with files in this directory instead.

The FakeFolder object wraps the SyncEngine with those abstractions
and allow controlling the local files, and the fake remote state
through the FileModifier interface, using a FileInfo tree structure
for the remote-side implementation as well as feeding and comparing
the states on both side in tests.

Tests run fast and require no setup to be run, but each server feature
that we want to test on the client side needs to be implemented in
this fake objects library. For example, the OC-FileId header isn't
set as of this commit, and we can't test the file move logic properly
without implementing it first.

The TestSyncFileStatusTracker tests already contain a few QEXPECT_FAIL
for what I esteem being issues that need to be fixed in order to catch
up on our test coverage without making this patch too huge.
2016-08-17 15:39:30 +02:00
Jenkins for ownCloud 465639af82 [tx-robot] updated from transifex 2016-08-17 02:18:31 +02:00
Jenkins for ownCloud 7f59dec0bb [tx-robot] updated from transifex 2016-08-17 01:15:16 +02:00
Jenkins for ownCloud 583f9586aa [tx-robot] updated from transifex 2016-08-16 02:18:31 +02:00
Jocelyn Turcotte 2507ba9818 tx.pl: Fix each put_to_dir taking 10 seconds
The open function expects a URL, passing only the directory name would
lead HTTP::DAV to try looking it as an hostname on the network and
only return after it timed out.
2016-08-15 15:35:53 +02:00
ckamm 88cd5421bf Tray menu: Update only on demand #4990 #4985 (#5072)
The tray menu is now only updated when it becomes visible or while
it is visible.
2016-08-15 13:42:56 +02:00
ckamm 7b26e6b8f9 Progress: Don't display unlikely estimates #5046 (#5066) 2016-08-15 13:36:53 +02:00
Jenkins for ownCloud 573d942969 [tx-robot] updated from transifex 2016-08-15 02:18:30 +02:00
Jenkins for ownCloud 1a454ec6b2 [tx-robot] updated from transifex 2016-08-15 01:15:15 +02:00
Jenkins for ownCloud 02df088843 [tx-robot] updated from transifex 2016-08-14 02:18:30 +02:00
Jenkins for ownCloud ce4daaaae2 [tx-robot] updated from transifex 2016-08-13 01:15:24 +02:00
Jenkins for ownCloud cd9335e043 [tx-robot] updated from transifex 2016-08-12 02:18:30 +02:00
Jenkins for ownCloud 775ad25be3 [tx-robot] updated from transifex 2016-08-12 01:16:28 +02:00
Jenkins for ownCloud 7e43fe599c [tx-robot] updated from transifex 2016-08-12 01:15:20 +02:00
Jenkins for ownCloud 20531e57a8 [tx-robot] updated from transifex 2016-08-11 02:18:39 +02:00
Jenkins for ownCloud 3e64840e33 [tx-robot] updated from transifex 2016-08-11 01:16:34 +02:00
Jenkins for ownCloud e6db2ee960 [tx-robot] updated from transifex 2016-08-11 01:15:18 +02:00
Markus Goetz be34bfb276 issue_template.md: Clarifying comment 2016-08-10 14:44:19 +02:00
Jenkins for ownCloud e2e16aeaaa [tx-robot] updated from transifex 2016-08-10 02:18:38 +02:00
Jenkins for ownCloud 6fbeb60d86 [tx-robot] updated from transifex 2016-08-10 01:16:38 +02:00
Thomas Müller a46a69f250 [2.2] Jenkinsfile: Add win32 build (#5091) (#5115) 2016-08-09 16:20:32 +02:00
Jenkins for ownCloud 3187a22300 [tx-robot] updated from transifex 2016-08-09 02:18:41 +02:00
Markus Goetz 9626021a63 Update ChangeLog for 2.2.3 final 2016-08-08 15:39:49 +02:00
Jenkins for ownCloud b72a19ad64 [tx-robot] updated from transifex 2016-08-08 02:18:35 +02:00
Markus Goetz 2ae37c6beb Update ChangeLog 2016-08-07 22:51:16 +02:00
Jenkins for ownCloud f8f376ac03 [tx-robot] updated from transifex 2016-08-07 02:18:30 +02:00
Jenkins for ownCloud 632d231435 [tx-robot] updated from transifex 2016-08-06 02:18:34 +02:00
Markus Goetz fc868d89f3 Merge pull request #5108 from owncloud/limit_library_path
Limit Qt and OpenSSL Library pathes to the install directory
2016-08-05 16:39:04 +02:00
Daniel Molkentin 5a57e4a7a6 Ensure OpenSSL config file is only read from app dir 2016-08-05 16:38:08 +02:00
Jenkins for ownCloud 70a1671dc1 [tx-robot] updated from transifex 2016-08-05 14:23:25 +02:00
Daniel Molkentin 7de70516f1 Fix module loading 2016-08-05 12:35:52 +02:00
Jenkins for ownCloud 50bd4b8f4f [tx-robot] updated from transifex 2016-08-05 02:18:30 +02:00
Olivier Goffart 4a7f3cb486 SyncEngine: Fix detection of backup (#5104)
Once upon a time, the SyncEngine was instantiated once per sync. But now that
the SyncEngine is kept between sync, we need to reset all these variable between
syncs.
2016-08-04 16:06:10 +02:00
Jenkins for ownCloud b7663d00b9 [tx-robot] updated from transifex 2016-08-04 02:18:35 +02:00
Jocelyn Turcotte b307f2b65c Revert "Fix a deadlock when shutting down during discovery" (#5100)
Reverts commit 622017adcf

Could be the cause of #5092 and the cost is higher than the benefit if this is the case.
A network request taking more than 30 seconds isn't something unlikely in this world
and shouldn't be a good reason to abort. We should try to untangle the threads
dependencies to properly fix this if possible instead.
2016-08-03 16:35:24 +02:00
Jenkins for ownCloud 6c94d56b53 [tx-robot] updated from transifex 2016-08-03 02:18:37 +02:00
Jenkins for ownCloud c51a80bffa [tx-robot] updated from transifex 2016-08-02 02:18:35 +02:00
Thomas Müller 87f4f70abb Merge pull request #5069 from owncloud/Jenkinsfile-2.2
[2.2] Add Jenkinsfile (#5041)
2016-08-01 12:41:04 +02:00
Olivier Goffart 19a52b9e6b Qt4: don't require a X server in the tests
Issue #5069

(cherry picked from commit 927a8b5071 and
a4310f0f5c)
2016-08-01 11:57:21 +02:00
Jenkins for ownCloud 4ea70ebd18 [tx-robot] updated from transifex 2016-08-01 02:48:18 +02:00
Jenkins for ownCloud b9a6970282 [tx-robot] updated from transifex 2016-07-31 02:50:05 +02:00
Jenkins for ownCloud a58ef9c586 [tx-robot] updated from transifex 2016-07-30 02:39:29 +02:00
Thomas Müller cef24da44c Add Jenkinsfile (#5041) 2016-07-29 08:48:28 +02:00
Jenkins for ownCloud 23c7f10b79 [tx-robot] updated from transifex 2016-07-29 02:18:35 +02:00
Jenkins for ownCloud 9e514d6cc7 [tx-robot] updated from transifex 2016-07-28 02:18:39 +02:00
Jenkins for ownCloud 4d109e43fa [tx-robot] updated from transifex 2016-07-27 02:18:42 +02:00
Daniel Molkentin b575ded464 More GmbH -> Inc Copyright header fixes 2016-07-26 16:53:11 +02:00
Jocelyn Turcotte 03a90bf03f shell/windows: Build 43, add missing 32 bit binaries
Also include a minor change from #5025
2016-07-26 14:54:27 +02:00
Jocelyn Turcotte ff7b2381e9 shell/windows: Add missing Win32 configuration changes
The changes in build location were only done on the x64 configuration.
2016-07-26 14:53:14 +02:00
Markus Goetz 24cd8041a8 ChangeLog for 2.2.3 2016-07-26 12:14:00 +02:00
Jenkins for ownCloud 3eaadfe52f [tx-robot] updated from transifex 2016-07-26 02:43:40 +02:00
Klaas Freitag ebcec44202 ShibbolethView: Open a debug windows that shows cipher info. (#5080)
It opens a window and connects to a cipher test
page, showing the output from there, that helps for debugging.

The window is enabled by setting the environment variable
OWNCLOUD_SHIBBOLETH_DEBUG
2016-07-25 17:47:23 +02:00
Jenkins for ownCloud 7b0b7fde51 [tx-robot] updated from transifex 2016-07-25 02:18:34 +02:00
Jenkins for ownCloud fa9ec12ae7 [tx-robot] updated from transifex 2016-07-24 02:18:36 +02:00
Jenkins for ownCloud 54aa4dce46 [tx-robot] updated from transifex 2016-07-23 02:18:47 +02:00
Jenkins for ownCloud 7c19f748b7 [tx-robot] updated from transifex 2016-07-22 02:18:44 +02:00
Jenkins for ownCloud 5aa82944a4 [tx-robot] updated from transifex 2016-07-21 02:18:38 +02:00
Jenkins for ownCloud 0d9cf26890 [tx-robot] updated from transifex 2016-07-20 08:18:40 +02:00
Jenkins for ownCloud a4837e9291 [tx-robot] updated from transifex 2016-07-19 08:18:37 +02:00
Jenkins for ownCloud 5672557a84 [tx-robot] updated from transifex 2016-07-18 09:29:56 +02:00
Jenkins for ownCloud 0b31f2601d [tx-robot] updated from transifex 2016-07-18 08:18:44 +02:00
Jenkins for ownCloud a5850d4515 [tx-robot] updated from transifex 2016-07-17 08:18:34 +02:00
Jenkins for ownCloud c39eb315dd [tx-robot] updated from transifex 2016-07-16 08:18:34 +02:00
Jenkins for ownCloud 6c8e88e2ed [tx-robot] updated from transifex 2016-07-15 08:18:36 +02:00
Jenkins for ownCloud eeea255104 [tx-robot] updated from transifex 2016-07-14 08:18:43 +02:00
Jenkins for ownCloud 8e2af57b57 [tx-robot] updated from transifex 2016-07-13 02:18:41 -04:00
118 arquivos alterados com 3616 adições e 1787 exclusões
+7
Ver Arquivo
@@ -136,6 +136,13 @@ if(OWNCLOUD_RESTORE_RENAME)
add_definitions(-DOWNCLOUD_RESTORE_RENAME=1)
endif()
# Disable shibboleth.
# So the client can be built without QtWebKit
option(NO_SHIBBOLETH "Build without Shibboleth support. Allow to build the client without QtWebKit" OFF)
if(NO_SHIBBOLETH)
message("Compiling without shibboleth")
add_definitions(-DNO_SHIBBOLETH=1)
endif()
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" )
+25 -1
Ver Arquivo
@@ -1,6 +1,30 @@
ChangeLog
=========
version 2.2.1 (release 2016-05-xx)
version 2.2.3 (release 2016-08-08)
* SyncEngine: Fix detection of backup (#5104)
* Fix bug with overriding URL in config (#5016)
* Sharing: Fix bug with file names containing percent encodes (#5042, #5043)
* Sharing: Permissions for federated shares on servers >=9.1 (#4996, #5001)
* Overlays: Fix issues with file name casing on OS X and Windows
* Windows: Skip symlinks and junctions again (#5019)
* Only accept notification API Capability if endpoint is OCS-enabled (#5034)
* Fix windows HiDPI (#4994)
* SocketAPI: Use different pipe name to avoid unusual delay (#4977)
* Tray: Add minimal mode as workaround and testing tool for Linux issues (#4985, #4990)
* owncloudcmd: Fix --exclude regression #4979
* Small memleak: Use the full file stat destructors (#4992)
* Fix small QAction memleak (#5008)
* Fix crash on shutting down during propagation (#4979)
* Decrease memory usage during sync #4979
* Setup csync logging earlier to get all log output (#4991)
* Enable Shibboleth debug view with OWNCLOUD_SHIBBOLETH_DEBUG env
version 2.2.2 (release 2016-06-21)
* Excludes: Don't redundantly add the same exclude files (memleak) (#4967, #4988)
* Excludes: Only log if the pattern was really logged. (#4989)
version 2.2.1 (release 2016-06-06)
* Fix out of memory error when too many uploads happen (#4611)
* Fix display errors in progress display (#4803 #4856)
* LockWatcher: Remember to upload files after they become unlocked (#4865)
+2 -2
Ver Arquivo
@@ -33,11 +33,11 @@ StrCpy $UNINSTALL_MESSAGEBOX "Ez dirudi ${APPLICATION_NAME} '$INSTDIR'.$ direkto
StrCpy $UNINSTALL_ABORT "Desinstalazioak erabiltzaileak bertan behera utzi du"
StrCpy $INIT_NO_QUICK_LAUNCH "Abiarazle Bizkorreko Lasterbidea (E/E)"
StrCpy $INIT_NO_DESKTOP "Mahaigaineko Lasterbidea (dagoena berridazten du)"
StrCpy $UAC_ERROR_ELEVATE "Ezin izan da goratu, errorea:"
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Instalatzaileak administratzaile baimenak behar ditu, saiatu berriro"
StrCpy $INIT_INSTALLER_RUNNING "Instalatzailea dagoeneko martxan da."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Desinstalatzaile honek administratzaile baimenak behar ditu, saiatu berriro"
StrCpy $UAC_ERROR_LOGON_SERVICE "Saioa hasteko zerbitzua ez dago martxan, bertan behera uzten!"
StrCpy $INIT_UNINSTALLER_RUNNING "Desinstalatzailea dagoeneko martxan da."
StrCpy $SectionGroup_Shortcuts "Lasterbideak"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
+1 -1
Ver Arquivo
@@ -9,7 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "インストール済"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "${APPLICATION_NAME} のインストール方法を選択する"
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} の最新バージョンがすでにインストールされています。$\n旧バージョンのインストールはお勧めしません。旧バージョンのインストールが本当に必要な場合は、まず最新バージョンをアンインストールしてから、旧バージョンをインストールしてください。$\nオペレーションを選択し、次へをクリックする。"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} は、${VERSION} がにインストールされています。$\n$\n実行したい操作を選択し、次へをクリックする"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} は、${VERSION} がすでにインストールされています。$\n$\n実行したい操作を選択し、次へをクリックしてください"
StrCpy $PageReinstall_SAME_Field_2 "追加/再インストールコンポーネント"
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} をアンインストール"
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} をアンインストール"
+7
Ver Arquivo
@@ -0,0 +1,7 @@
[Paths]
Prefix = .
Plugins = .
Binaries = .
Imports = .
Qml2Imports = .
LibraryExecutables = .
+1 -1
Submodule binary updated: 1cfb331dc9...0d89ac7766
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+3
Ver Arquivo
@@ -411,6 +411,9 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
File "@CPACK_RESOURCE_FILE_LICENSE@"
;File /oname=NOTES.txt ${NSI_PATH}\RELEASE_NOTES.txt
;Qt config:
File "${NSI_PATH}\qt.conf"
;Qt stuff:
File "${QT_DLL_PATH}\Qt5Core.dll"
File "${QT_DLL_PATH}\Qt5Gui.dll"
+9 -3
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
@@ -22,12 +22,18 @@ if( Qt5Core_FOUND )
find_package(Qt5Test REQUIRED)
endif()
if(NOT TOKEN_AUTH_ONLY)
find_package(Qt5WebKitWidgets REQUIRED)
find_package(Qt5WebKit REQUIRED)
find_package(Qt5Widgets REQUIRED)
if(APPLE)
find_package(Qt5MacExtras REQUIRED)
endif(APPLE)
if(NOT NO_SHIBBOLETH)
find_package(Qt5WebKitWidgets)
find_package(Qt5WebKit)
if(NOT Qt5WebKitWidgets_FOUND)
message(FATAL_ERROR "Qt5WebKit required for Shibboleth. Use -DNO_SHIBBOLETH=1 to disable it.")
endif()
endif()
endif()
else( Qt5Core_FOUND )
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# (c) 2014 Copyright ownCloud, Inc.
# (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.
+2
Ver Arquivo
@@ -23,4 +23,6 @@
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
#cmakedefine SHAREDIR "@SHAREDIR@"
#cmakedefine WITH_UNIT_TESTING 1
#endif
+2
Ver Arquivo
@@ -41,6 +41,8 @@ endif (MEM_NULL_TESTS)
add_subdirectory(src)
if (UNIT_TESTING)
set(WITH_UNIT_TESTING ON)
find_package(CMocka)
if (CMOCKA_FOUND)
include(AddCMockaTest)
-4
Ver Arquivo
@@ -62,8 +62,4 @@ if (WIN32)
check_function_exists(__mingw_asprintf HAVE___MINGW_ASPRINTF)
endif(WIN32)
if (UNIT_TESTING)
set(WITH_UNIT_TESTING ON)
endif (UNIT_TESTING)
set(CSYNC_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "csync required system libraries")
-1
Ver Arquivo
@@ -387,7 +387,6 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
trav.inode = cur->inode;
trav.error_status = cur->error_status;
trav.should_update_metadata = cur->should_update_metadata;
trav.has_ignored_files = cur->has_ignored_files;
trav.checksum = cur->checksum;
trav.checksumTypeId = cur->checksumTypeId;
+16 -17
Ver Arquivo
@@ -125,20 +125,22 @@ typedef enum csync_status_codes_e CSYNC_STATUS;
* the csync state of a file.
*/
enum csync_instructions_e {
CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */
CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */
CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */
CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */
CSYNC_INSTRUCTION_EVAL_RENAME= 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */
CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */
CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
CSYNC_INSTRUCTION_ERROR = 0x00000100,
CSYNC_INSTRUCTION_TYPE_CHANGE = 0x0000200, /* Like NEW, but deletes the old entity first (RECONCILE)
Used when the type of something changes from directory to file
or back. */
CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */
CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */
CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */
CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */
CSYNC_INSTRUCTION_EVAL_RENAME = 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */
CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */
CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
CSYNC_INSTRUCTION_ERROR = 0x00000100,
CSYNC_INSTRUCTION_TYPE_CHANGE = 0x00000200, /* Like NEW, but deletes the old entity first (RECONCILE)
Used when the type of something changes from directory to file
or back. */
CSYNC_INSTRUCTION_UPDATE_METADATA = 0x00000400, /* If the etag has been updated and need to be writen to the db,
but without any propagation (UPDATE|RECONCILE) */
};
enum csync_ftw_type_e {
@@ -254,9 +256,6 @@ struct csync_tree_walk_file_s {
enum csync_ftw_type_e type;
enum csync_instructions_e instruction;
/* For directories: If the etag has been updated and need to be writen on the db */
int should_update_metadata;
/* For directories: Does it have children that were ignored (hidden or ignore pattern) */
int has_ignored_files;
+1 -1
Ver Arquivo
@@ -40,7 +40,7 @@
#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
#include "csync_log.h"
#ifndef NDEBUG
#ifndef WITH_UNIT_TESTING
static
#endif
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
+1 -1
Ver Arquivo
@@ -34,7 +34,7 @@ enum csync_exclude_type_e {
};
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
#ifdef NDEBUG
#ifdef WITH_UNIT_TESTING
int _csync_exclude_add(c_strlist_t **inList, const char *string);
#endif
-2
Ver Arquivo
@@ -186,8 +186,6 @@ struct csync_file_stat_s {
mode_t mode; /* u32 */
unsigned int type : 4;
unsigned int child_modified : 1;
unsigned int should_update_metadata : 1; /*specify that the etag, or the remote perm or fileid has
changed and need to be updated on the db even for INSTRUCTION_NONE */
unsigned int has_ignored_files : 1; /* specify that a directory, or child directory contains ignored files */
char *destpath; /* for renames */
+29 -30
Ver Arquivo
@@ -20,6 +20,7 @@
#include "config_csync.h"
#include <assert.h>
#include "csync_private.h"
#include "csync_reconcile.h"
#include "csync_util.h"
@@ -130,6 +131,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
break;
/* file has been removed on the opposite replica */
case CSYNC_INSTRUCTION_NONE:
case CSYNC_INSTRUCTION_UPDATE_METADATA:
if (cur->has_ignored_files) {
/* Do not remove a directory that has ignored files */
break;
@@ -181,13 +183,8 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
if(!other) {
cur->instruction = CSYNC_INSTRUCTION_NEW;
if (cur->type == CSYNC_FTW_TYPE_DIR) {
// For new directories we always want to update the etag once
// the directory has been propagated. Otherwise the directory
// could appear locally without being added to the database.
cur->should_update_metadata = true;
}
} else if (other->instruction == CSYNC_INSTRUCTION_NONE
|| other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|| cur->type == CSYNC_FTW_TYPE_DIR) {
other->instruction = CSYNC_INSTRUCTION_RENAME;
other->destpath = c_strdup( cur->path );
@@ -195,7 +192,6 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
csync_vio_set_file_id( other->file_id, cur->file_id );
}
other->inode = cur->inode;
other->should_update_metadata = true;
cur->instruction = CSYNC_INSTRUCTION_NONE;
} else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
other->instruction = CSYNC_INSTRUCTION_RENAME;
@@ -205,12 +201,12 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
csync_vio_set_file_id( other->file_id, cur->file_id );
}
other->inode = cur->inode;
other->should_update_metadata = true;
cur->instruction = CSYNC_INSTRUCTION_NONE;
} else if (other->instruction == CSYNC_INSTRUCTION_NEW) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "OOOO=> NEW detected in other tree!");
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
} else {
assert(other->type != CSYNC_FTW_TYPE_DIR);
cur->instruction = CSYNC_INSTRUCTION_NONE;
other->instruction = CSYNC_INSTRUCTION_SYNC;
}
@@ -222,13 +218,19 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
break;
}
} else {
bool is_equal_files = false;
bool is_conflict = true;
/*
* file found on the other replica
*/
other = (csync_file_stat_t *) node->data;
switch (cur->instruction) {
case CSYNC_INSTRUCTION_UPDATE_METADATA:
if (other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA && ctx->current == LOCAL_REPLICA) {
// Remote wins, the SyncEngine will pick relevant local metadata since the remote tree is walked last.
cur->instruction = CSYNC_INSTRUCTION_NONE;
}
break;
case CSYNC_INSTRUCTION_EVAL_RENAME:
/* If the file already exist on the other side, we have a conflict.
Abort the rename and consider it is a new file. */
@@ -253,42 +255,39 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
case CSYNC_INSTRUCTION_EVAL:
if (other->type == CSYNC_FTW_TYPE_DIR &&
cur->type == CSYNC_FTW_TYPE_DIR) {
is_equal_files = (other->modtime == cur->modtime);
// Folders of the same path are always considered equals
is_conflict = false;
} else {
is_equal_files = ((other->size == cur->size) && (other->modtime == cur->modtime));
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.
}
if (is_equal_files) {
/* The files are considered equal. */
cur->instruction = CSYNC_INSTRUCTION_NONE;
if (ctx->current == REMOTE_REPLICA) {
// If the files are considered equal, only update the DB with the etag from remote
cur->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
other->instruction = CSYNC_INSTRUCTION_NONE;
/* update DB with new etag from remote */
if (ctx->current == LOCAL_REPLICA) {
other->should_update_metadata = true;
} else {
cur->should_update_metadata = true;
}
} else if(ctx->current == REMOTE_REPLICA) {
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
other->instruction = CSYNC_INSTRUCTION_NONE;
} else {
cur->instruction = CSYNC_INSTRUCTION_NONE;
other->instruction = CSYNC_INSTRUCTION_CONFLICT;
cur->instruction = CSYNC_INSTRUCTION_NONE;
other->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
}
break;
/* file on the other replica has not been modified */
case CSYNC_INSTRUCTION_NONE:
case CSYNC_INSTRUCTION_UPDATE_METADATA:
if (cur->type != other->type) {
// If the type of the entity changed, it's like NEW, but
// needs to delete the other entity first.
cur->instruction = CSYNC_INSTRUCTION_TYPE_CHANGE;
other->instruction = CSYNC_INSTRUCTION_NONE;
} else if (cur->type == CSYNC_FTW_TYPE_DIR) {
cur->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
other->instruction = CSYNC_INSTRUCTION_NONE;
} else {
cur->instruction = CSYNC_INSTRUCTION_SYNC;
other->instruction = CSYNC_INSTRUCTION_NONE;
}
break;
case CSYNC_INSTRUCTION_IGNORE:
@@ -310,7 +309,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
if(cur->type == CSYNC_FTW_TYPE_DIR)
{
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
"%-20s %s dir: %s",
"%-30s %s dir: %s",
csync_instruction_str(cur->instruction),
repo,
cur->path);
@@ -318,7 +317,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
else
{
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
"%-20s %s file: %s",
"%-30s %s file: %s",
csync_instruction_str(cur->instruction),
repo,
cur->path);
@@ -329,7 +328,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
if(cur->type == CSYNC_FTW_TYPE_DIR)
{
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
"%-20s %s dir: %s",
"%-30s %s dir: %s",
csync_instruction_str(cur->instruction),
repo,
cur->path);
@@ -337,7 +336,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
else
{
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
"%-20s %s file: %s",
"%-30s %s file: %s",
csync_instruction_str(cur->instruction),
repo,
cur->path);
+16 -19
Ver Arquivo
@@ -314,8 +314,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
}
if (checksumIdentical) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", path);
st->instruction = CSYNC_INSTRUCTION_NONE;
st->should_update_metadata = true;
st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
goto out;
}
}
@@ -341,18 +340,19 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", path);
ctx->remote.read_from_db = true;
}
if (metadata_differ) {
/* file id or permissions has changed. Which means we need to update them in the DB. */
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path);
st->should_update_metadata = true;
}
/* If it was remembered in the db that the remote dir has ignored files, store
* that so that the reconciler can make advantage of.
*/
if( ctx->current == REMOTE_REPLICA ) {
st->has_ignored_files = tmp->has_ignored_files;
}
st->instruction = CSYNC_INSTRUCTION_NONE;
if (metadata_differ) {
/* file id or permissions has changed. Which means we need to update them in the DB. */
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path);
st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
} else {
st->instruction = CSYNC_INSTRUCTION_NONE;
}
} else {
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
@@ -488,7 +488,9 @@ out:
}
}
}
if (st->instruction != CSYNC_INSTRUCTION_NONE && st->instruction != CSYNC_INSTRUCTION_IGNORE
if (st->instruction != CSYNC_INSTRUCTION_NONE
&& st->instruction != CSYNC_INSTRUCTION_IGNORE
&& st->instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
&& type != CSYNC_FTW_TYPE_DIR) {
st->child_modified = 1;
}
@@ -877,10 +879,11 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
if (ctx->current_fs && !ctx->current_fs->child_modified
&& ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL) {
ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
if (ctx->current == REMOTE_REPLICA) {
ctx->current_fs->should_update_metadata = true;
}
if (ctx->current == REMOTE_REPLICA) {
ctx->current_fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
} else {
ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
}
}
if (ctx->current_fs && previous_fs && ctx->current_fs->has_ignored_files) {
@@ -894,12 +897,6 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
previous_fs->child_modified = ctx->current_fs->child_modified;
}
if (flag == CSYNC_FTW_FLAG_DIR && ctx->current_fs
&& (ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL ||
ctx->current_fs->instruction == CSYNC_INSTRUCTION_NEW)) {
ctx->current_fs->should_update_metadata = true;
}
ctx->current_fs = previous_fs;
ctx->remote.read_from_db = read_from_db;
SAFE_FREE(filename);
+1
Ver Arquivo
@@ -56,6 +56,7 @@ static const _instr_code_struct _instr[] =
{ "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR },
{ "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR },
{ "INSTRUCTION_TYPE_CHANGE", CSYNC_INSTRUCTION_TYPE_CHANGE },
{ "INSTRUCTION_UPDATE_METADATA", CSYNC_INSTRUCTION_UPDATE_METADATA },
{ NULL, CSYNC_INSTRUCTION_ERROR }
};
+1 -1
Ver Arquivo
@@ -520,7 +520,7 @@ sub put_to_dir( $$;$ )
$targetUrl = $optionsRef->{url};
}
}
$d->open($dir);
$d->open($targetUrl . $dir);
my $filename = $file;
$filename =~ s/^.*\///;
+4
Ver Arquivo
@@ -64,6 +64,10 @@ csync();
assert( -e glob(localDir().'dir/file2_.sys.admin#recall#-*.dat' ) );
assert( -e glob(localDir().'dir/file3_.sys.admin#recall#-*.dat' ) );
# verify that the original files still exist
assert( -e glob(localDir().'dir/file2.dat' ) );
assert( -e glob(localDir().'dir/file3.dat' ) );
#Remove the recall file
unlink(localDir() . ".sys.admin#recall#");
+11 -3
Ver Arquivo
@@ -1,3 +1,11 @@
<!---
Please try to only report a bug if it happens with the latest version
The latest version can be seen by checking the ChangeLog: https://owncloud.org/changelog/desktop/
For support try: https://central.owncloud.org/c/help/desktop-file-sync
--->
### Expected behaviour
Tell us what should happen
@@ -20,7 +28,7 @@ PHP version:
ownCloud version:
Storage backend:
Storage backend (external storage):
### Client configuration
Client version:
@@ -38,11 +46,11 @@ logs.
```Template for output < 10 lines```
1. Output of `owncloud --logwindow` or `owncloud --logfile log.txt`
1. Client logfile: Output of `owncloud --logwindow` or `owncloud --logfile log.txt`
(On Windows using `cmd.exe`, you might need to first `cd` into the ownCloud directory)
(See also http://doc.owncloud.org/desktop/2.2/troubleshooting.html#client-logfile )
2. Web server error log:
3. ownCloud log (data/owncloud.log):
3. Server logfile: ownCloud log (data/owncloud.log):
+155 -16
Ver Arquivo
@@ -160,6 +160,138 @@ X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# 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
@@ -182,9 +314,11 @@ GenericName[de]=Ordner-Synchronisation
Name[de]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
Icon[de]=@APPLICATION_EXECUTABLE@
Comment[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
GenericName[ja_JP]=フォルダ同期
GenericName[ja_JP]=フォルダ同期
Name[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
Icon[ja_JP]=@APPLICATION_EXECUTABLE@
GenericName[el]=Συγχρονισμός φακέλου
Icon[el]=@APPLICATION_EXECUTABLE@
Comment[en_GB]=@APPLICATION_NAME@ desktop synchronisation client
GenericName[en_GB]=Folder Sync
Name[en_GB]=@APPLICATION_NAME@ desktop sync client
@@ -197,10 +331,10 @@ Comment[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
GenericName[de_DE]=Ordner-Synchronisation
Name[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
Icon[de_DE]=@APPLICATION_EXECUTABLE@
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
GenericName[bg_BG]=Синхронизиране на папката
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
Comment[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
GenericName[pl]=Folder Synchronizacji
Name[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
Icon[pl]=@APPLICATION_EXECUTABLE@
Comment[fr]=@APPLICATION_NAME@ synchronisation du client
GenericName[fr]=Dossier de Synchronisation
Name[fr]=@APPLICATION_NAME@ synchronisation du client
@@ -236,10 +370,10 @@ Comment[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
GenericName[et_EE]=Kaustade sünkroonimine
Name[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
Icon[et_EE]=@APPLICATION_EXECUTABLE@
Comment[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
GenericName[pl]=Folder Synchronizacji
Name[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
Icon[pl]=@APPLICATION_EXECUTABLE@
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
GenericName[bg_BG]=Синхронизиране на папката
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
Comment[pt_BR]=@APPLICATION_NAME@ cliente de sincronização do computador
GenericName[pt_BR]=Sincronização de Pasta
Name[pt_BR]=@APPLICATION_NAME@ cliente de sincronização de desktop
@@ -260,13 +394,17 @@ Comment[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
GenericName[sq]=Njëkohësim Dosjesh
Name[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
Icon[sq]=@APPLICATION_EXECUTABLE@
Comment[fi_FI]=@APPLICATION_NAME@ työpöytäsynkronointisovellus
GenericName[fi_FI]=Kansion synkronointi
Name[fi_FI]=@APPLICATION_NAME@ työpöytäsynkronointisovellus
Icon[fi_FI]=@APPLICATION_EXECUTABLE@
Comment[sv]=@APPLICATION_NAME@ desktop synkroniseringsklient
GenericName[sv]=Mappsynk
Name[sv]=@APPLICATION_NAME@ desktop synk-klient
Icon[sv]=@APPLICATION_EXECUTABLE@
Comment[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
GenericName[tr]=Dosya Senkronizasyonu
Name[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
Comment[tr]=@APPLICATION_NAME@ masaüstü eşitleme istemcisi
GenericName[tr]=Dosya Eşitleme
Name[tr]=@APPLICATION_NAME@ masaüstü eşitleme istemcisi
Icon[tr]=@APPLICATION_EXECUTABLE@
Comment[uk]=Настільний клієнт синхронізації @APPLICATION_NAME@
GenericName[uk]=Синхронізація теки
@@ -285,6 +423,10 @@ Comment[lt_LT]=@APPLICATION_NAME@ darbalaukio sinchronizavimo programa
GenericName[lt_LT]=Katalogo sinchnorizacija
Name[lt_LT]=@APPLICATION_NAME@ darbalaukio programa
Icon[lt_LT]=@APPLICATION_EXECUTABLE@
Comment[th_TH]=@APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
Name[th_TH]= @APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
Icon[th_TH]=@APPLICATION_EXECUTABLE@
Comment[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
GenericName[nb_NO]=Mappesynkronisering
Name[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
@@ -297,11 +439,8 @@ Comment[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
GenericName[pt_PT]=Sincronizar Pasta
Name[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
Icon[pt_PT]=@APPLICATION_EXECUTABLE@
Icon[km]=@APPLICATION_EXECUTABLE@
Comment[lb]=@APPLICATION_NAME@ Desktop Synchronisatioun Client
GenericName[lb]=Dossier Dync
Name[lb]=@APPLICATION_NAME@ Desktop Sync Client
Icon[lb]=@APPLICATION_EXECUTABLE@
Comment[th_TH]=@APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
Name[th_TH]= @APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
Icon[th_TH]=@APPLICATION_EXECUTABLE@
@@ -21,6 +21,7 @@
#include <qcoreevent.h>
#include <QFile>
#include "ownclouddolphinpluginhelper.h"
#include "config.h"
OwncloudDolphinPluginHelper* OwncloudDolphinPluginHelper::instance()
{
@@ -67,7 +68,10 @@ void OwncloudDolphinPluginHelper::tryConnect()
return;
}
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
QString socketPath = runtimeDir + QLatin1String("/ownCloud/socket");
runtimeDir.append( QChar('/'));
runtimeDir.append( QLatin1String(APPLICATION_SHORTNAME) );
const QString socketPath = runtimeDir + QLatin1String("/socket");
_socket.connectToServer(socketPath);
}
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2015 ownCloud, Inc. All rights reserved.
* Copyright (c) 2015 ownCloud GmbH. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
@@ -12,7 +12,7 @@
*/
/**
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
@@ -59,12 +59,12 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName)_x86</TargetName>
</PropertyGroup>
@@ -89,10 +89,13 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
<AdditionalDependencies>OCUtil_x86.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -108,10 +111,13 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
<AdditionalDependencies>OCUtil_x86.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
@@ -66,7 +66,7 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName)_x86</TargetName>
<TargetExt>.dll</TargetExt>
@@ -78,7 +78,7 @@
<TargetExt>.dll</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName)_x86</TargetName>
<TargetExt>.dll</TargetExt>
@@ -99,11 +99,14 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
<AdditionalDependencies>OCUtil_x86.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
<SubSystem>Windows</SubSystem>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@@ -136,11 +139,14 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
<AdditionalDependencies>OCUtil_x86.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
<SubSystem>Windows</SubSystem>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
+2 -2
Ver Arquivo
@@ -67,7 +67,7 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetExt>.dll</TargetExt>
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName)_x86</TargetName>
</PropertyGroup>
@@ -86,7 +86,7 @@
<TargetExt>.dll</TargetExt>
<TargetName>$(ProjectName)_x86</TargetName>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
+1 -1
Ver Arquivo
@@ -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 42
#define OCEXT_BUILD_NUM 43
#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
+6
Ver Arquivo
@@ -275,6 +275,12 @@ void selectiveSyncFixup(OCC::SyncJournalDb *journal, const QStringList &newList)
int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
#ifdef Q_OS_WIN
// Ensure OpenSSL config file is only loaded from app directory
QString opensslConf = QCoreApplication::applicationDirPath()+QString("/openssl.cnf");
qputenv("OPENSSL_CONF", opensslConf.toLocal8Bit());
#endif
qsrand(QTime::currentTime().msec() * QCoreApplication::applicationPid());
CmdOptions options;
+13 -6
Ver Arquivo
@@ -94,22 +94,26 @@ set(client_SRCS
servernotificationhandler.cpp
creds/credentialsfactory.cpp
creds/httpcredentialsgui.cpp
creds/shibbolethcredentials.cpp
creds/shibboleth/shibbolethwebview.cpp
creds/shibboleth/shibbolethuserjob.cpp
wizard/postfixlineedit.cpp
wizard/abstractcredswizardpage.cpp
wizard/owncloudadvancedsetuppage.cpp
wizard/owncloudconnectionmethoddialog.cpp
wizard/owncloudhttpcredspage.cpp
wizard/owncloudsetuppage.cpp
wizard/owncloudshibbolethcredspage.cpp
wizard/owncloudwizardcommon.cpp
wizard/owncloudwizard.cpp
wizard/owncloudwizardresultpage.cpp
../3rdparty/qjson/json.cpp
)
IF(NOT NO_SHIBBOLETH)
list(APPEND client_SRCS
creds/shibbolethcredentials.cpp
creds/shibboleth/shibbolethwebview.cpp
creds/shibboleth/shibbolethuserjob.cpp
wizard/owncloudshibbolethcredspage.cpp
)
endif()
set(updater_SRCS
updater/ocupdater.cpp
@@ -232,6 +236,9 @@ set(ownCloud ${ownCloud_old})
if (WITH_DBUS)
set(ADDITIONAL_APP_MODULES DBus)
endif(WITH_DBUS)
if (NOT NO_SHIBBOLETH)
list(APPEND ADDITIONAL_APP_MODULES WebKitWidgets)
endif()
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
@@ -250,14 +257,14 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES})
else()
# set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf.
set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns")
# we must add MACOSX_BUNDLE only if building a bundle
add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src})
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES})
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
install(FILES ${client_I18N} DESTINATION ${QM_DIR})
+6
Ver Arquivo
@@ -105,6 +105,12 @@ Application::Application(int &argc, char **argv) :
{
_startedAt.start();
#ifdef Q_OS_WIN
// Ensure OpenSSL config file is only loaded from app directory
QString opensslConf = QCoreApplication::applicationDirPath()+QString("/openssl.cnf");
qputenv("OPENSSL_CONF", opensslConf.toLocal8Bit());
#endif
// TODO: Can't set this without breaking current config paths
// setOrganizationName(QLatin1String(APPLICATION_VENDOR));
setOrganizationDomain(QLatin1String(APPLICATION_REV_DOMAIN));
+4
Ver Arquivo
@@ -16,7 +16,9 @@
#include "creds/credentialsfactory.h"
#include "creds/httpcredentialsgui.h"
#include "creds/dummycredentials.h"
#ifndef NO_SHIBBOLETH
#include "creds/shibbolethcredentials.h"
#endif
namespace OCC
{
@@ -31,8 +33,10 @@ AbstractCredentials* create(const QString& type)
return new HttpCredentialsGui;
} else if (type == "dummy") {
return new DummyCredentials;
#ifndef NO_SHIBBOLETH
} else if (type == "shibboleth") {
return new ShibbolethCredentials;
#endif
} else {
qWarning("Unknown credentials type: %s", qPrintable(type));
return new DummyCredentials;
+14 -1
Ver Arquivo
@@ -20,6 +20,7 @@
#include <QMessageBox>
#include <QNetworkReply>
#include <QSettings>
#include <QMainWindow>
#include "creds/shibboleth/shibbolethwebview.h"
#include "creds/shibbolethcredentials.h"
@@ -74,10 +75,23 @@ ShibbolethWebView::ShibbolethWebView(AccountPtr account, QWidget* parent)
connect(page->networkAccessManager()->cookieJar(),
SIGNAL(newCookiesForUrl (QList<QNetworkCookie>, QUrl)),
this, SLOT(onNewCookiesForUrl (QList<QNetworkCookie>, QUrl)));
page->mainFrame()->load(account->url());
this->setPage(page);
setWindowTitle(tr("%1 - Authenticate").arg(Theme::instance()->appNameGUI()));
// Debug view to display the cipher suite
if( !qgetenv("OWNCLOUD_SHIBBOLETH_DEBUG").isEmpty() ) {
// open an additional window to display some cipher debug info
QWebPage *debugPage = new UserAgentWebPage(this);
debugPage->mainFrame()->load( QUrl("https://cc.dcsec.uni-hannover.de/"));
QWebView *debugView = new QWebView(this);
debugView->setPage(debugPage);
QMainWindow *window = new QMainWindow(this);
window->setWindowTitle(tr("SSL Chipher Debug View"));
window->setCentralWidget(debugView);
window->show();
}
// If we have a valid cookie, it's most likely expired. We can use this as
// as a criteria to tell the user why the browser window pops up
QNetworkCookie shibCookie = ShibbolethCredentials::findShibCookie(_account.data(), ShibbolethCredentials::accountCookies(_account.data()));
@@ -142,7 +156,6 @@ void ShibbolethWebView::slotLoadFinished(bool success)
if (!success) {
qDebug() << Q_FUNC_INFO << "Could not load Shibboleth login page to log you in.";
}
}
+3 -5
Ver Arquivo
@@ -410,11 +410,9 @@ void Folder::bubbleUpSyncResult()
firstItemDeleted = item;
break;
case CSYNC_INSTRUCTION_SYNC:
if (!item->_isDirectory) {
updatedItems++;
if (!firstItemUpdated)
firstItemUpdated = item;
}
updatedItems++;
if (!firstItemUpdated)
firstItemUpdated = item;
break;
case CSYNC_INSTRUCTION_ERROR:
qDebug() << "Got Instruction ERROR. " << _syncResult.errorString();
+29 -8
Ver Arquivo
@@ -164,7 +164,8 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
switch(role) {
case Qt::DisplayRole:
if (x->_hasError) {
return tr("Error while loading the list of folders from the server.");
return QVariant(tr("Error while loading the list of folders from the server.")
+ QString("\n") + x->_lastErrorString);
} else {
return tr("Fetching folder list from server...");
}
@@ -498,6 +499,10 @@ bool FolderStatusModel::canFetchMore(const QModelIndex& parent) const
auto info = infoForIndex(parent);
if (!info || info->_fetched || info->_fetching)
return false;
if (info->_hasError) {
// Keep showing the error to the user, it will be hidden when the account reconnects
return false;
}
return true;
}
@@ -548,6 +553,7 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
if (parentInfo->hasLabel()) {
beginRemoveRows(idx, 0 ,0);
parentInfo->_lastErrorString.clear();
parentInfo->_hasError = false;
parentInfo->_fetchingLabel = false;
endRemoveRows();
@@ -675,6 +681,9 @@ void FolderStatusModel::slotLscolFinishedWithError(QNetworkReply* r)
}
auto parentInfo = infoForIndex(idx);
if (parentInfo) {
qDebug() << r->errorString();
parentInfo->_lastErrorString = r->errorString();
if (r->error() == QNetworkReply::ContentNotFoundError) {
parentInfo->_fetched = true;
} else {
@@ -934,11 +943,20 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
if (totalSize > 0) {
QString s1 = Utility::octetsToString( completedSize );
QString s2 = Utility::octetsToString( totalSize );
//: Example text: "5 minutes left, 12 MB of 345 MB, file 6 of 7"
overallSyncString = tr("%5 left, %1 of %2, file %3 of %4")
.arg(s1, s2)
.arg(currentFile).arg(totalFileCount)
.arg( Utility::durationToDescriptiveString1(progress.totalProgress().estimatedEta) );
if (progress.trustEta()) {
//: Example text: "5 minutes left, 12 MB of 345 MB, file 6 of 7"
overallSyncString = tr("%5 left, %1 of %2, file %3 of %4")
.arg(s1, s2)
.arg(currentFile).arg(totalFileCount)
.arg( Utility::durationToDescriptiveString1(progress.totalProgress().estimatedEta) );
} else {
//: Example text: "12 MB of 345 MB, file 6 of 7"
overallSyncString = tr("%1 of %2, file %3 of %4")
.arg(s1, s2)
.arg(currentFile).arg(totalFileCount);
}
} else if (totalFileCount > 0) {
// Don't attempt to estimate the time left if there is no kb to transfer.
overallSyncString = tr("file %1 of %2") .arg(currentFile).arg(totalFileCount);
@@ -1058,11 +1076,14 @@ void FolderStatusModel::slotShowFetchProgress()
auto idx = it.key();
auto* info = infoForIndex(idx);
if (info && info->_fetching) {
if (!info->hasLabel()) {
bool add = !info->hasLabel();
if (add) {
beginInsertRows(idx, 0, 0);
endInsertRows();
}
info->_fetchingLabel = true;
if (add) {
endInsertRows();
}
}
it.remove();
}
+1
Ver Arquivo
@@ -63,6 +63,7 @@ public:
bool _fetched; // If we did the LSCOL for this folder already
bool _fetching; // Whether a LSCOL job is currently running
bool _hasError; // If the last fetching job ended in an error
QString _lastErrorString;
bool _fetchingLabel; // Whether a 'fetching in progress' label is shown.
bool _isUndecided; // undecided folders are the big folders that the user has not accepted yet
+41 -15
Ver Arquivo
@@ -92,9 +92,9 @@ ownCloudGui::ownCloudGui(Application *parent) :
this,SLOT(slotSyncStateChange(Folder*)));
connect( AccountManager::instance(), SIGNAL(accountAdded(AccountState*)),
SLOT(setupContextMenu()));
SLOT(setupContextMenuIfVisible()));
connect( AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
SLOT(setupContextMenu()));
SLOT(setupContextMenuIfVisible()));
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
SLOT(slotShowTrayMessage(QString,QString)));
@@ -193,7 +193,7 @@ void ownCloudGui::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
void ownCloudGui::slotSyncStateChange( Folder* folder )
{
slotComputeOverallSyncStatus();
setupContextMenu();
setupContextMenuIfVisible();
if( !folder ) {
return; // Valid, just a general GUI redraw was needed.
@@ -215,7 +215,7 @@ void ownCloudGui::slotSyncStateChange( Folder* folder )
void ownCloudGui::slotFoldersChanged()
{
slotComputeOverallSyncStatus();
setupContextMenu();
setupContextMenuIfVisible();
}
void ownCloudGui::slotOpenPath(const QString &path)
@@ -225,7 +225,7 @@ void ownCloudGui::slotOpenPath(const QString &path)
void ownCloudGui::slotAccountStateChanged()
{
setupContextMenu();
setupContextMenuIfVisible();
slotComputeOverallSyncStatus();
}
@@ -450,9 +450,13 @@ void ownCloudGui::setupContextMenu()
_tray->hide();
}
_contextMenu->clear();
slotRebuildRecentMenus();
} else {
_contextMenu.reset(new QMenu());
// Update the context menu whenever we're about to show it
// to the user.
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(setupContextMenu()));
_recentActionsMenu = new QMenu(tr("Recent Changes"), _contextMenu.data());
// this must be called only once after creating the context menu, or
// it will trigger a bug in Ubuntu's SNI bridge patch (11.10, 12.04).
@@ -477,6 +481,8 @@ void ownCloudGui::setupContextMenu()
#endif
}
_contextMenu->setTitle(Theme::instance()->appNameGUI() );
slotRebuildRecentMenus();
// We must call deleteLater because we might be called from the press in one of the actions.
foreach (auto menu, _accountMenus) { menu->deleteLater(); }
_accountMenus.clear();
@@ -552,6 +558,11 @@ void ownCloudGui::setupContextMenu()
}
}
void ownCloudGui::setupContextMenuIfVisible()
{
if (_contextMenu && _contextMenu->isVisible())
setupContextMenu();
}
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
{
@@ -658,18 +669,29 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
} else if (progress.totalSize() == 0 ) {
quint64 currentFile = progress.currentFile();
quint64 totalFileCount = qMax(progress.totalFiles(), currentFile);
_actionStatus->setText( tr("Syncing %1 of %2 (%3 left)")
.arg( currentFile ).arg( totalFileCount )
.arg( Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) ) );
QString msg;
if (progress.trustEta()) {
msg = tr("Syncing %1 of %2 (%3 left)")
.arg( currentFile ).arg( totalFileCount )
.arg( Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) );
} else {
msg = tr("Syncing %1 of %2")
.arg( currentFile ).arg( totalFileCount );
}
_actionStatus->setText( msg );
} else {
QString totalSizeStr = Utility::octetsToString( progress.totalSize() );
_actionStatus->setText( tr("Syncing %1 (%2 left)")
.arg( totalSizeStr, Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) ) );
QString msg;
if (progress.trustEta()) {
msg = tr("Syncing %1 (%2 left)")
.arg( totalSizeStr, Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) );
} else {
msg = tr("Syncing %1")
.arg( totalSizeStr );
}
_actionStatus->setText( msg );
}
_actionRecent->setIcon( QIcon() ); // Fixme: Set a "in-progress"-item eventually.
if (!progress._lastCompletedItem.isEmpty()
@@ -700,7 +722,11 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
}
_recentItemsActions.append(action);
slotRebuildRecentMenus();
// Update the "Recent" menu if the context menu is being shown,
// otherwise it'll be updated later, when the context menu is opened.
if (_contextMenu && _contextMenu->isVisible()) {
slotRebuildRecentMenus();
}
}
if (progress.isUpdatingEstimates()
+1
Ver Arquivo
@@ -57,6 +57,7 @@ signals:
public slots:
void setupContextMenu();
void setupContextMenuIfVisible();
void slotComputeOverallSyncStatus();
void slotShowTrayMessage(const QString &title, const QString &msg);
void slotShowOptionalTrayMessage(const QString &title, const QString &msg);
+8 -1
Ver Arquivo
@@ -508,6 +508,10 @@ DetermineAuthTypeJob::DetermineAuthTypeJob(AccountPtr account, QObject *parent)
: AbstractNetworkJob(account, QString(), parent)
, _redirects(0)
{
// This job implements special redirect handling to detect redirections
// to pages that are indicative of Shibboleth-using servers. Hence we
// disable the standard job redirection handling here.
_followRedirects = false;
}
void DetermineAuthTypeJob::start()
@@ -535,12 +539,15 @@ bool DetermineAuthTypeJob::finished()
setupConnections(reply());
return false; // don't discard
} else {
#ifndef NO_SHIBBOLETH
QRegExp shibbolethyWords("SAML|wayf");
shibbolethyWords.setCaseSensitivity(Qt::CaseInsensitive);
if (redirection.toString().contains(shibbolethyWords)) {
emit authType(WizardCommon::Shibboleth);
} else {
} else
#endif
{
// TODO: Send an error.
// eh?
emit authType(WizardCommon::HttpCreds);
+2
Ver Arquivo
@@ -375,6 +375,7 @@ void ShareLinkWidget::slotCheckBoxShareLinkClicked()
_ui->checkBox_password->setText(tr("Public sh&aring requires a password"));
_ui->checkBox_expire->setEnabled(false);
_ui->checkBox_editing->setEnabled(false);
_ui->lineEdit_password->setEnabled(true);
_ui->lineEdit_password->setFocus();
_ui->pushButton_copy->hide();
_ui->pushButton_mail->hide();
@@ -443,6 +444,7 @@ void ShareLinkWidget::slotCheckBoxPasswordClicked()
_ui->lineEdit_password->show();
_ui->pushButton_setPassword->show();
_ui->lineEdit_password->setPlaceholderText(tr("Please Set Password"));
_ui->lineEdit_password->setEnabled(true);
_ui->lineEdit_password->setFocus();
} else {
setPassword(QString());
+8 -1
Ver Arquivo
@@ -81,6 +81,9 @@ QString SyncRunFileLog::instructionToStr( csync_instructions_e inst )
case CSYNC_INSTRUCTION_TYPE_CHANGE:
re = "INST_TYPE_CHANGE";
break;
case CSYNC_INSTRUCTION_UPDATE_METADATA:
re = "INST_METADATA";
break;
}
return re;
@@ -142,7 +145,11 @@ void SyncRunFileLog::logItem( const SyncFileItem& item )
const QChar L = QLatin1Char('|');
_out << ts << L;
_out << QString::number(item._requestDuration) << L;
_out << item._file << L;
if( item.log._instruction != CSYNC_INSTRUCTION_RENAME ) {
_out << item._file << L;
} else {
_out << item._file << QLatin1String(" -> ") << item._renameTarget << L;
}
_out << instructionToStr( item.log._instruction ) << L;
_out << directionToStr( item._direction ) << L;
_out << QString::number(item.log._modtime) << L;
+10 -6
Ver Arquivo
@@ -30,7 +30,6 @@ OwncloudHttpCredsPage::OwncloudHttpCredsPage(QWidget* parent)
: AbstractCredentialsWizardPage(),
_ui(),
_connected(false),
_checking(false),
_progressIndi(new QProgressIndicator (this))
{
_ui.setupUi(this);
@@ -133,14 +132,20 @@ bool OwncloudHttpCredsPage::validatePage()
if (!_connected) {
_ui.errorLabel->setVisible(false);
_checking = true;
startSpinner();
// Reset cookies to ensure the username / password is actually used
OwncloudWizard* ocWizard = qobject_cast< OwncloudWizard* >(wizard());
ocWizard->account()->clearCookieJar();
emit completeChanged();
emit connectToOCUrl(field("OCUrl").toString().simplified());
return false;
} else {
_checking = false;
// Reset, to require another connection attempt next time
_connected = false;
emit completeChanged();
stopSpinner();
return true;
@@ -153,9 +158,9 @@ int OwncloudHttpCredsPage::nextId() const
return WizardCommon::Page_AdvancedSetup;
}
void OwncloudHttpCredsPage::setConnected( bool comp )
void OwncloudHttpCredsPage::setConnected()
{
_connected = comp;
_connected = true;
stopSpinner ();
}
@@ -181,7 +186,6 @@ void OwncloudHttpCredsPage::setErrorString(const QString& err)
_ui.errorLabel->setVisible(true);
_ui.errorLabel->setText(err);
}
_checking = false;
emit completeChanged();
stopSpinner();
}
+1 -2
Ver Arquivo
@@ -40,7 +40,7 @@ public:
void cleanupPage() Q_DECL_OVERRIDE;
bool validatePage() Q_DECL_OVERRIDE;
int nextId() const Q_DECL_OVERRIDE;
void setConnected(bool connected);
void setConnected();
void setErrorString( const QString& err );
Q_SIGNALS:
@@ -53,7 +53,6 @@ private:
Ui_OwncloudHttpCredsPage _ui;
bool _connected;
bool _checking;
QProgressIndicator* _progressIndi;
OwncloudWizard* _ocWizard;
};
+15 -8
Ver Arquivo
@@ -20,7 +20,9 @@
#include "wizard/owncloudwizard.h"
#include "wizard/owncloudsetuppage.h"
#include "wizard/owncloudhttpcredspage.h"
#ifndef NO_SHIBBOLETH
#include "wizard/owncloudshibbolethcredspage.h"
#endif
#include "wizard/owncloudadvancedsetuppage.h"
#include "wizard/owncloudwizardresultpage.h"
@@ -39,7 +41,9 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
_account(0),
_setupPage(new OwncloudSetupPage(this)),
_httpCredsPage(new OwncloudHttpCredsPage(this)),
#ifndef NO_SHIBBOLETH
_shibbolethCredsPage(new OwncloudShibbolethCredsPage),
#endif
_advancedSetupPage(new OwncloudAdvancedSetupPage),
_resultPage(new OwncloudWizardResultPage),
_credentialsPage(0),
@@ -48,7 +52,9 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setPage(WizardCommon::Page_ServerSetup, _setupPage);
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
#ifndef NO_SHIBBOLETH
setPage(WizardCommon::Page_ShibbolethCreds, _shibbolethCredsPage);
#endif
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
setPage(WizardCommon::Page_Result, _resultPage);
@@ -61,7 +67,9 @@ 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)));
#ifndef NO_SHIBBOLETH
connect( _shibbolethCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
#endif
connect( _advancedSetupPage, SIGNAL(createLocalAndRemoteFolders(QString, QString)),
SIGNAL(createLocalAndRemoteFolders(QString, QString)));
connect(this, SIGNAL(customButtonClicked(int)), this, SIGNAL(skipFolderConfiguration()));
@@ -125,12 +133,14 @@ void OwncloudWizard::successfulStep()
switch (id) {
case WizardCommon::Page_HttpCreds:
_httpCredsPage->setConnected(true);
_httpCredsPage->setConnected();
break;
#ifndef NO_SHIBBOLETH
case WizardCommon::Page_ShibbolethCreds:
_shibbolethCredsPage->setConnected();
break;
#endif
case WizardCommon::Page_AdvancedSetup:
_advancedSetupPage->directoriesCreated();
@@ -148,9 +158,12 @@ void OwncloudWizard::successfulStep()
void OwncloudWizard::setAuthType(WizardCommon::AuthType type)
{
_setupPage->setAuthType(type);
#ifndef NO_SHIBBOLETH
if (type == WizardCommon::Shibboleth) {
_credentialsPage = _shibbolethCredsPage;
} else {
} else
#endif
{
_credentialsPage = _httpCredsPage;
}
next();
@@ -172,12 +185,6 @@ void OwncloudWizard::slotCurrentPageChanged( int id )
}
setOption(QWizard::HaveCustomButton1, id == WizardCommon::Page_AdvancedSetup);
if (id == WizardCommon::Page_AdvancedSetup) {
// Going back from this page messes the state as the account is created already
button(QWizard::BackButton)->setDisabled(true);
}
}
void OwncloudWizard::displayError( const QString& msg, bool retryHTTPonly )
+4
Ver Arquivo
@@ -25,7 +25,9 @@ namespace OCC {
class OwncloudSetupPage;
class OwncloudHttpCredsPage;
#ifndef NO_SHIBBOLETH
class OwncloudShibbolethCredsPage;
#endif
class OwncloudAdvancedSetupPage;
class OwncloudWizardResultPage;
class AbstractCredentials;
@@ -88,7 +90,9 @@ private:
AccountPtr _account;
OwncloudSetupPage* _setupPage;
OwncloudHttpCredsPage* _httpCredsPage;
#ifndef NO_SHIBBOLETH
OwncloudShibbolethCredsPage* _shibbolethCredsPage;
#endif
OwncloudAdvancedSetupPage* _advancedSetupPage;
OwncloudWizardResultPage* _resultPage;
AbstractCredentialsWizardPage* _credentialsPage;
+1 -1
Ver Arquivo
@@ -581,7 +581,7 @@ csync_vio_handle_t* DiscoveryJob::remote_vio_opendir_hook (const char *url,
discoveryJob->_vioMutex.lock();
const QString qurl = QString::fromUtf8(url);
emit discoveryJob->doOpendirSignal(qurl, directoryResult.data());
discoveryJob->_vioWaitCondition.wait(&discoveryJob->_vioMutex, 30000);
discoveryJob->_vioWaitCondition.wait(&discoveryJob->_vioMutex, ULONG_MAX); // FIXME timeout?
discoveryJob->_vioMutex.unlock();
qDebug() << discoveryJob << url << "...Returned from main thread";
+9 -1
Ver Arquivo
@@ -12,6 +12,7 @@
*/
#include "excludedfiles.h"
#include "utility.h"
#include <QFileInfo>
@@ -45,6 +46,13 @@ void ExcludedFiles::addExcludeFilePath(const QString& path)
_excludeFiles.insert(path);
}
#ifdef WITH_UNIT_TESTING
void ExcludedFiles::addExcludeExpr(const QString &expr)
{
_csync_exclude_add(_excludesPtr, expr.toLatin1().constData());
}
#endif
bool ExcludedFiles::reloadExcludes()
{
c_strlist_destroy(*_excludesPtr);
@@ -63,7 +71,7 @@ bool ExcludedFiles::isExcluded(
const QString& basePath,
bool excludeHidden) const
{
if (!filePath.startsWith(basePath)) {
if (!filePath.startsWith(basePath, Utility::fsCasePreserving() ? Qt::CaseInsensitive : Qt::CaseSensitive)) {
// Mark paths we're not responsible for as excluded...
return true;
}
+4
Ver Arquivo
@@ -57,6 +57,10 @@ public:
const QString& basePath,
bool excludeHidden) const;
#ifdef WITH_UNIT_TESTING
void addExcludeExpr(const QString &expr);
#endif
public slots:
/**
* Reloads the exclude patterns from the registered paths.
+18 -26
Ver Arquivo
@@ -201,12 +201,12 @@ bool PropagateItemJob::checkForProblemsWithShared(int httpStatusCode, const QStr
downloadItem->_instruction = CSYNC_INSTRUCTION_SYNC;
}
downloadItem->_direction = SyncFileItem::Down;
newJob = new PropagateDownloadFileQNAM(_propagator, downloadItem);
newJob = new PropagateDownloadFile(_propagator, downloadItem);
} else {
// Directories are harder to recover.
// But just re-create the directory, next sync will be able to recover the files
SyncFileItemPtr mkdirItem(new SyncFileItem(*_item));
mkdirItem->_instruction = CSYNC_INSTRUCTION_SYNC;
mkdirItem->_instruction = CSYNC_INSTRUCTION_NEW;
mkdirItem->_direction = SyncFileItem::Down;
newJob = new PropagateLocalMkdir(_propagator, mkdirItem);
// Also remove the inodes and fileid from the db so no further renames are tried for
@@ -265,20 +265,14 @@ PropagateItemJob* OwncloudPropagator::createJob(const SyncFileItemPtr &item) {
} //fall through
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_CONFLICT:
if (item->_isDirectory) {
// Should we set the mtime?
return 0;
}
{
if (item->_direction != SyncFileItem::Up) {
auto job = new PropagateDownloadFileQNAM(this, item);
job->setDeleteExistingFolder(deleteExisting);
return job;
} else {
auto job = new PropagateUploadFileQNAM(this, item);
job->setDeleteExisting(deleteExisting);
return job;
}
if (item->_direction != SyncFileItem::Up) {
auto job = new PropagateDownloadFile(this, item);
job->setDeleteExistingFolder(deleteExisting);
return job;
} else {
auto job = new PropagateUploadFile(this, item);
job->setDeleteExisting(deleteExisting);
return job;
}
case CSYNC_INSTRUCTION_RENAME:
if (item->_direction == SyncFileItem::Up) {
@@ -377,7 +371,8 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
// NOTE: Currently this means that we don't update those etag at all in this sync,
// but it should not be a problem, they will be updated in the next sync.
for (int i = 0; i < directories.size(); ++i) {
directories[i].second->_item->_should_update_metadata = false;
if (directories[i].second->_item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA)
directories[i].second->_item->_instruction = CSYNC_INSTRUCTION_NONE;
}
} else {
PropagateDirectory* currentDirJob = directories.top().second;
@@ -645,7 +640,6 @@ void PropagateDirectory::slotSubJobFinished(SyncFileItem::Status status)
(sender() == _firstJob.data() && status != SyncFileItem::Success && status != SyncFileItem::Restoration)) {
abort();
_state = Finished;
emit itemCompleted(*_item, *this);
emit finished(status);
return;
} else if (status == SyncFileItem::NormalError || status == SyncFileItem::SoftError) {
@@ -677,7 +671,12 @@ void PropagateDirectory::finalize()
_item->_file = _item->_renameTarget;
}
if (_item->_should_update_metadata && _item->_instruction != CSYNC_INSTRUCTION_REMOVE) {
// For new directories we always want to update the etag once
// the directory has been propagated. Otherwise the directory
// could appear locally without being added to the database.
if (_item->_instruction == CSYNC_INSTRUCTION_RENAME
|| _item->_instruction == CSYNC_INSTRUCTION_NEW
|| _item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) {
if (PropagateRemoteMkdir* mkdir = qobject_cast<PropagateRemoteMkdir*>(_firstJob.data())) {
// special case from MKDIR, get the fileId from the job there
if (_item->_fileId.isEmpty() && !mkdir->_item->_fileId.isEmpty()) {
@@ -694,13 +693,6 @@ void PropagateDirectory::finalize()
}
}
_state = Finished;
// Just to make sure that the SocketApi will know by looking in
// SyncEngine::_syncedItems that this folder is done synchronizing.
if (ok) {
_item->_status = SyncFileItem::Success;
}
emit itemCompleted(*_item, *this);
emit finished(_item->_status);
}
+2 -2
Ver Arquivo
@@ -378,8 +378,8 @@ private:
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// access to signals which are protected in Qt4
friend class PropagateDownloadFileQNAM;
friend class PropagateUploadFileQNAM;
friend class PropagateDownloadFile;
friend class PropagateUploadFile;
friend class PropagateLocalMkdir;
friend class PropagateLocalRename;
friend class PropagateRemoteMove;
+24 -19
Ver Arquivo
@@ -46,6 +46,8 @@ QString Progress::asResultString( const SyncFileItem& item)
return QCoreApplication::translate( "progress", "Filesystem access error");
case CSYNC_INSTRUCTION_ERROR:
return QCoreApplication::translate( "progress", "Error");
case CSYNC_INSTRUCTION_UPDATE_METADATA:
return QCoreApplication::translate( "progress", "Updated local metadata");
case CSYNC_INSTRUCTION_NONE:
case CSYNC_INSTRUCTION_EVAL:
return QCoreApplication::translate( "progress", "Unknown");
@@ -76,6 +78,8 @@ QString Progress::asActionString( const SyncFileItem &item )
return QCoreApplication::translate( "progress", "error");
case CSYNC_INSTRUCTION_ERROR:
return QCoreApplication::translate( "progress", "error");
case CSYNC_INSTRUCTION_UPDATE_METADATA:
return QCoreApplication::translate( "progress", "updating local metadata");
case CSYNC_INSTRUCTION_NONE:
case CSYNC_INSTRUCTION_EVAL:
break;
@@ -159,17 +163,10 @@ static bool shouldCountProgress(const SyncFileItem &item)
{
const auto instruction = item._instruction;
// Don't worry about directories that won't have propagation
// jobs associated with them.
if (item._isDirectory
&& (instruction == CSYNC_INSTRUCTION_NONE
|| instruction == CSYNC_INSTRUCTION_SYNC
|| instruction == CSYNC_INSTRUCTION_CONFLICT)) {
return false;
}
// Skip any ignored or error files, we do nothing with them.
if (instruction == CSYNC_INSTRUCTION_IGNORE
// Skip any ignored, error or non-propagated files and directories.
if (instruction == CSYNC_INSTRUCTION_NONE
|| instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|| instruction == CSYNC_INSTRUCTION_IGNORE
|| instruction == CSYNC_INSTRUCTION_ERROR) {
return false;
}
@@ -279,13 +276,6 @@ ProgressInfo::Estimates ProgressInfo::totalProgress() const
// assume the remaining transfer will be done with the highest speed
// we've seen.
// This assumes files and transfers finish as quickly as possible
// *but* note that maxPerSecond could be serious underestimates
// (if we never got to fully excercise transfer or files/second)
quint64 optimisticEta =
_fileProgress.remaining() / _maxFilesPerSecond * 1000
+ _sizeProgress.remaining() / _maxBytesPerSecond * 1000;
// Compute a value that is 0 when fps is <=L*max and 1 when fps is >=U*max
double fps = _fileProgress._progressPerSec;
double fpsL = 0.5;
@@ -309,11 +299,26 @@ ProgressInfo::Estimates ProgressInfo::totalProgress() const
double beOptimistic = nearMaxFps * slowTransfer;
size.estimatedEta = (1.0 - beOptimistic) * size.estimatedEta
+ beOptimistic * optimisticEta;
+ beOptimistic * optimisticEta();
return size;
}
quint64 ProgressInfo::optimisticEta() const
{
// This assumes files and transfers finish as quickly as possible
// *but* note that maxPerSecond could be serious underestimate
// (if we never got to fully excercise transfer or files/second)
return _fileProgress.remaining() / _maxFilesPerSecond * 1000
+ _sizeProgress.remaining() / _maxBytesPerSecond * 1000;
}
bool ProgressInfo::trustEta() const
{
return totalProgress().estimatedEta < 100 * optimisticEta();
}
ProgressInfo::Estimates ProgressInfo::fileProgress(const SyncFileItem &item) const
{
return _currentItems[item._file]._progress.estimates();
+16
Ver Arquivo
@@ -164,6 +164,22 @@ public:
*/
Estimates totalProgress() const;
/**
* Get the optimistic eta.
*
* This value is based on the highest observed transfer bandwidth
* and files-per-second speed.
*/
quint64 optimisticEta() const;
/**
* Whether the remaining-time estimate is trusted.
*
* We don't trust it if it is hugely above the optimistic estimate.
* See #5046.
*/
bool trustEta() const;
/**
* Get the current file completion estimate structure
*/
+14 -13
Ver Arquivo
@@ -304,7 +304,7 @@ QString GETFileJob::errorString() const
}
}
void PropagateDownloadFileQNAM::start()
void PropagateDownloadFile::start()
{
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
return;
@@ -418,7 +418,7 @@ void PropagateDownloadFileQNAM::start()
_job->start();
}
qint64 PropagateDownloadFileQNAM::committedDiskSpace() const
qint64 PropagateDownloadFile::committedDiskSpace() const
{
if (_state == Running) {
return qBound(0ULL, _item->_size - _resumeStart - _downloadProgress, _item->_size);
@@ -426,13 +426,13 @@ qint64 PropagateDownloadFileQNAM::committedDiskSpace() const
return 0;
}
void PropagateDownloadFileQNAM::setDeleteExistingFolder(bool enabled)
void PropagateDownloadFile::setDeleteExistingFolder(bool enabled)
{
_deleteExisting = enabled;
}
const char owncloudCustomSoftErrorStringC[] = "owncloud-custom-soft-error-string";
void PropagateDownloadFileQNAM::slotGetFinished()
void PropagateDownloadFile::slotGetFinished()
{
_propagator->_activeJobList.removeOne(this);
@@ -565,14 +565,14 @@ void PropagateDownloadFileQNAM::slotGetFinished()
validator->start(_tmpFile.fileName(), checksumHeader);
}
void PropagateDownloadFileQNAM::slotChecksumFail( const QString& errMsg )
void PropagateDownloadFile::slotChecksumFail( const QString& errMsg )
{
FileSystem::remove(_tmpFile.fileName());
_propagator->_anotherSyncNeeded = true;
done(SyncFileItem::SoftError, errMsg ); // tr("The file downloaded with a broken checksum, will be redownloaded."));
}
void PropagateDownloadFileQNAM::deleteExistingFolder()
void PropagateDownloadFile::deleteExistingFolder()
{
QString existingDir = _propagator->getFilePath(_item->_file);
if (!QFileInfo(existingDir).isDir()) {
@@ -637,8 +637,9 @@ static void handleRecallFile(const QString &fn)
QString rpath = makeRecallFileName(fpath);
qDebug() << "Copy recall file: " << fpath << " -> " << rpath;
QString error;
FileSystem::uncheckedRenameReplace(fpath, rpath, &error);
// Remove the target first, QFile::copy will not overwrite it.
FileSystem::remove(rpath);
QFile::copy(fpath, rpath);
}
}
@@ -653,7 +654,7 @@ static void preserveGroupOwnership(const QString& fileName, const QFileInfo& fi)
}
} // end namespace
void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
void PropagateDownloadFile::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
{
const auto theContentChecksumType = contentChecksumType();
@@ -674,7 +675,7 @@ void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &
computeChecksum->start(_tmpFile.fileName());
}
void PropagateDownloadFileQNAM::contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
void PropagateDownloadFile::contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
{
_item->_contentChecksum = checksum;
_item->_contentChecksumType = checksumType;
@@ -682,7 +683,7 @@ void PropagateDownloadFileQNAM::contentChecksumComputed(const QByteArray &checks
downloadFinished();
}
void PropagateDownloadFileQNAM::downloadFinished()
void PropagateDownloadFile::downloadFinished()
{
QString fn = _propagator->getFilePath(_item->_file);
@@ -805,7 +806,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
}
}
void PropagateDownloadFileQNAM::slotDownloadProgress(qint64 received, qint64)
void PropagateDownloadFile::slotDownloadProgress(qint64 received, qint64)
{
if (!_job) return;
_downloadProgress = received;
@@ -813,7 +814,7 @@ void PropagateDownloadFileQNAM::slotDownloadProgress(qint64 received, qint64)
}
void PropagateDownloadFileQNAM::abort()
void PropagateDownloadFile::abort()
{
if (_job && _job->reply())
_job->reply()->abort();
+3 -3
Ver Arquivo
@@ -103,13 +103,13 @@ private slots:
};
/**
* @brief The PropagateDownloadFileQNAM class
* @brief The PropagateDownloadFile class
* @ingroup libsync
*/
class PropagateDownloadFileQNAM : public PropagateItemJob {
class PropagateDownloadFile : public PropagateItemJob {
Q_OBJECT
public:
PropagateDownloadFileQNAM(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
PropagateDownloadFile(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
: PropagateItemJob(propagator, item), _resumeStart(0), _downloadProgress(0), _deleteExisting(false) {}
void start() Q_DECL_OVERRIDE;
qint64 committedDiskSpace() const Q_DECL_OVERRIDE;
+15 -15
Ver Arquivo
@@ -184,7 +184,7 @@ bool PollJob::finished()
return true;
}
void PropagateUploadFileQNAM::start()
void PropagateUploadFile::start()
{
if (_propagator->_abortRequested.fetchAndAddRelaxed(0)) {
return;
@@ -205,7 +205,7 @@ void PropagateUploadFileQNAM::start()
job->start();
}
void PropagateUploadFileQNAM::slotComputeContentChecksum()
void PropagateUploadFile::slotComputeContentChecksum()
{
if (_propagator->_abortRequested.fetchAndAddRelaxed(0)) {
return;
@@ -239,12 +239,12 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
computeChecksum->start(filePath);
}
void PropagateUploadFileQNAM::setDeleteExisting(bool enabled)
void PropagateUploadFile::setDeleteExisting(bool enabled)
{
_deleteExisting = enabled;
}
void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray& contentChecksumType, const QByteArray& contentChecksum)
void PropagateUploadFile::slotComputeTransmissionChecksum(const QByteArray& contentChecksumType, const QByteArray& contentChecksum)
{
_item->_contentChecksum = contentChecksum;
_item->_contentChecksumType = contentChecksumType;
@@ -276,7 +276,7 @@ void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray&
computeChecksum->start(filePath);
}
void PropagateUploadFileQNAM::slotStartUpload(const QByteArray& transmissionChecksumType, const QByteArray& transmissionChecksum)
void PropagateUploadFile::slotStartUpload(const QByteArray& transmissionChecksumType, const QByteArray& transmissionChecksum)
{
// Remove ourselfs from the list of active job, before any posible call to done()
// When we start chunks, we will add it again, once for every chunks.
@@ -299,7 +299,7 @@ void PropagateUploadFileQNAM::slotStartUpload(const QByteArray& transmissionChec
}
_stopWatch.addLapTime(QLatin1String("TransmissionChecksum"));
time_t prevModtime = _item->_modtime; // the _item value was set in PropagateUploadFileQNAM::start()
time_t prevModtime = _item->_modtime; // the _item value was set in PropagateUploadFile::start()
// but a potential checksum calculation could have taken some time during which the file could
// have been changed again, so better check again here.
@@ -476,7 +476,7 @@ void UploadDevice::setChoked(bool b) {
}
}
void PropagateUploadFileQNAM::startNextChunk()
void PropagateUploadFile::startNextChunk()
{
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
return;
@@ -607,7 +607,7 @@ void PropagateUploadFileQNAM::startNextChunk()
}
}
void PropagateUploadFileQNAM::slotPutFinished()
void PropagateUploadFile::slotPutFinished()
{
PUTFileJob *job = qobject_cast<PUTFileJob *>(sender());
Q_ASSERT(job);
@@ -785,7 +785,7 @@ void PropagateUploadFileQNAM::slotPutFinished()
finalize(*_item);
}
void PropagateUploadFileQNAM::finalize(const SyncFileItem &copy)
void PropagateUploadFile::finalize(const SyncFileItem &copy)
{
// Normally, copy == _item, but when it comes from the UpdateMTimeAndETagJob, we need to do
// some updates
@@ -807,7 +807,7 @@ void PropagateUploadFileQNAM::finalize(const SyncFileItem &copy)
done(SyncFileItem::Success);
}
void PropagateUploadFileQNAM::slotUploadProgress(qint64 sent, qint64 total)
void PropagateUploadFile::slotUploadProgress(qint64 sent, qint64 total)
{
// Completion is signaled with sent=0, total=0; avoid accidentally
// resetting progress due to the sent being zero by ignoring it.
@@ -840,7 +840,7 @@ void PropagateUploadFileQNAM::slotUploadProgress(qint64 sent, qint64 total)
emit progress(*_item, amount);
}
void PropagateUploadFileQNAM::startPollJob(const QString& path)
void PropagateUploadFile::startPollJob(const QString& path)
{
PollJob* job = new PollJob(_propagator->account(), path, _item,
_propagator->_journal, _propagator->_localDir, this);
@@ -855,7 +855,7 @@ void PropagateUploadFileQNAM::startPollJob(const QString& path)
job->start();
}
void PropagateUploadFileQNAM::slotPollFinished()
void PropagateUploadFile::slotPollFinished()
{
PollJob *job = qobject_cast<PollJob *>(sender());
Q_ASSERT(job);
@@ -871,12 +871,12 @@ void PropagateUploadFileQNAM::slotPollFinished()
finalize(*job->_item);
}
void PropagateUploadFileQNAM::slotJobDestroyed(QObject* job)
void PropagateUploadFile::slotJobDestroyed(QObject* job)
{
_jobs.erase(std::remove(_jobs.begin(), _jobs.end(), job) , _jobs.end());
}
void PropagateUploadFileQNAM::abort()
void PropagateUploadFile::abort()
{
foreach(auto *job, _jobs) {
if (job->reply()) {
@@ -887,7 +887,7 @@ void PropagateUploadFileQNAM::abort()
}
// This function is used whenever there is an error occuring and jobs might be in progress
void PropagateUploadFileQNAM::abortWithError(SyncFileItem::Status status, const QString &error)
void PropagateUploadFile::abortWithError(SyncFileItem::Status status, const QString &error)
{
_finished = true;
abort();
+3 -3
Ver Arquivo
@@ -155,10 +155,10 @@ signals:
};
/**
* @brief The PropagateUploadFileQNAM class
* @brief The PropagateUploadFile class
* @ingroup libsync
*/
class PropagateUploadFileQNAM : public PropagateItemJob {
class PropagateUploadFile : public PropagateItemJob {
Q_OBJECT
private:
@@ -191,7 +191,7 @@ private:
quint64 chunkSize() const { return _propagator->chunkSize(); }
public:
PropagateUploadFileQNAM(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
PropagateUploadFile(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
: PropagateItemJob(propagator, item), _startChunk(0), _currentChunk(0), _chunkCount(0), _transferId(0), _finished(false), _deleteExisting(false) {}
void start() Q_DECL_OVERRIDE;
+42 -53
Ver Arquivo
@@ -78,6 +78,10 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
{
qRegisterMetaType<SyncFileItem>("SyncFileItem");
qRegisterMetaType<SyncFileItem::Status>("SyncFileItem::Status");
qRegisterMetaType<SyncFileStatus>("SyncFileStatus");
// Everything in the SyncEngine expects a trailing slash for the localPath.
Q_ASSERT(localPath.endsWith(QLatin1Char('/')));
// We need to reconstruct the url because the path needs to be fully decoded, as csync will re-encode the path:
// Remember that csync will just append the filename to the path and pass it to the vio plugin.
@@ -391,8 +395,6 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
item->_remotePerm = QByteArray(file->remotePerm);
}
item->_should_update_metadata = item->_should_update_metadata || file->should_update_metadata;
/* The flag "serverHasIgnoredFiles" is true if item in question is a directory
* that has children which are ignored in sync, either because the files are
* matched by an ignore pattern, or because they are hidden.
@@ -510,10 +512,23 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
int re = 0;
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE: {
if (remote && item->_should_update_metadata && !isDirectory && item->_instruction == CSYNC_INSTRUCTION_NONE) {
// Any files that are instruction NONE?
if (!isDirectory && file->other.instruction == CSYNC_INSTRUCTION_NONE) {
_hasNoneFiles = true;
}
// No syncing or update to be done.
return re;
}
case CSYNC_INSTRUCTION_UPDATE_METADATA:
dir = SyncFileItem::None;
// For directories, metadata-only updates will be done after all their files are propagated.
if (!isDirectory) {
item->_isDirectory = isDirectory;
emit syncItemDiscovered(*item);
// Update the database now already: New remote fileid or Etag or RemotePerm
// Or for files that were detected as "resolved conflict".
// Or a local inode/mtime change (see localMetadataUpdate below)
// Or a local inode/mtime change
// In case of "resolved conflict": there should have been a conflict because they
// both were new, or both had their local mtime or remote etag modified, but the
@@ -525,47 +540,33 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
// quick to do and we don't want to create a potentially large number of
// mini-jobs later on, we just update metadata right now.
QString filePath = _localPath + item->_file;
if (remote) {
QString filePath = _localPath + item->_file;
// Even if the mtime is different on the server, we always want to keep the mtime from
// the file system in the DB, this is to avoid spurious upload on the next sync
item->_modtime = file->other.modtime;
// same for the size
item->_size = file->other.size;
// Even if the mtime is different on the server, we always want to keep the mtime from
// the file system in the DB, this is to avoid spurious upload on the next sync
item->_modtime = file->other.modtime;
// same for the size
item->_size = file->other.size;
// If the 'W' remote permission changed, update the local filesystem
SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
if (prev.isValid() && prev._remotePerm.contains('W') != item->_remotePerm.contains('W')) {
const bool isReadOnly = !item->_remotePerm.contains('W');
FileSystem::setFileReadOnlyWeak(filePath, isReadOnly);
// If the 'W' remote permission changed, update the local filesystem
SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
if (prev.isValid() && prev._remotePerm.contains('W') != item->_remotePerm.contains('W')) {
const bool isReadOnly = !item->_remotePerm.contains('W');
FileSystem::setFileReadOnlyWeak(filePath, isReadOnly);
}
_journal->setFileRecordMetadata(SyncJournalFileRecord(*item, filePath));
} else {
// The local tree is walked first and doesn't have all the info from the server.
// Update only outdated data from the disk.
_journal->updateLocalMetadata(item->_file, item->_modtime, item->_size, item->_inode);
}
_journal->setFileRecordMetadata(SyncJournalFileRecord(*item, filePath));
item->_should_update_metadata = false;
// Technically we're done with this item. See localMetadataUpdate hack below.
_syncItemMap.remove(key);
}
// Any files that are instruction NONE?
if (!isDirectory && file->other.instruction == CSYNC_INSTRUCTION_NONE) {
_hasNoneFiles = true;
}
// We want to still update etags of directories, other NONE
// items can be ignored.
bool directoryEtagUpdate = isDirectory && file->should_update_metadata;
bool localMetadataUpdate = !remote && file->should_update_metadata;
if (!directoryEtagUpdate) {
item->_isDirectory = isDirectory;
if (localMetadataUpdate) {
// Hack, we want a local metadata update to happen, but only if the
// remote tree doesn't ask us to do some kind of propagation.
_syncItemMap.insert(key, item);
}
emit syncItemDiscovered(*item);
// Technically we're done with this item.
return re;
}
break;
}
case CSYNC_INSTRUCTION_RENAME:
dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
item->_renameTarget = renameTarget;
@@ -862,6 +863,8 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
_hasNoneFiles = false;
_hasRemoveFile = false;
_hasForwardInTimeFiles = false;
_backInTimeFiles = 0;
bool walkOk = true;
_seenFiles.clear();
_temporarilyUnavailablePaths.clear();
@@ -1176,9 +1179,8 @@ void SyncEngine::checkForPermission()
if (perms.isNull()) {
// No permissions set
break;
} if (!(*it)->_isDirectory && !perms.contains("W")) {
} if (!perms.contains("W")) {
qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
(*it)->_should_update_metadata = true;
(*it)->_instruction = CSYNC_INSTRUCTION_CONFLICT;
(*it)->_direction = SyncFileItem::Down;
(*it)->_isRestoration = true;
@@ -1200,7 +1202,6 @@ void SyncEngine::checkForPermission()
}
if (!perms.contains("D")) {
qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
(*it)->_should_update_metadata = true;
(*it)->_instruction = CSYNC_INSTRUCTION_NEW;
(*it)->_direction = SyncFileItem::Down;
(*it)->_isRestoration = true;
@@ -1219,7 +1220,6 @@ void SyncEngine::checkForPermission()
}
qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
(*it)->_should_update_metadata = true;
(*it)->_instruction = CSYNC_INSTRUCTION_NEW;
(*it)->_direction = SyncFileItem::Down;
@@ -1368,7 +1368,6 @@ void SyncEngine::restoreOldFiles()
break;
case CSYNC_INSTRUCTION_REMOVE:
qDebug() << "restoreOldFiles: RESTORING" << (*it)->_file;
(*it)->_should_update_metadata = true;
(*it)->_instruction = CSYNC_INSTRUCTION_NEW;
(*it)->_direction = SyncFileItem::Up;
break;
@@ -1383,16 +1382,6 @@ void SyncEngine::restoreOldFiles()
}
}
SyncFileItem* SyncEngine::findSyncItem(const QString &fileName) const
{
Q_FOREACH(const SyncFileItemPtr &item, _syncedItems) {
// Directories will appear in this list as well, and will get their status set once all children have been propagated
if ((item->_file == fileName || (!item->_renameTarget.isEmpty() && item->_renameTarget == fileName)))
return item.data();
}
return 0;
}
void SyncEngine::slotAddTouchedFile(const QString& fn)
{
QString file = QDir::cleanPath(fn);
-2
Ver Arquivo
@@ -85,8 +85,6 @@ public:
/* Return true if we detected that another sync is needed to complete the sync */
bool isAnotherSyncNeeded() { return _anotherSyncNeeded; }
SyncFileItem* findSyncItem(const QString &fileName) const;
/** Get the ms since a file was touched, or -1 if it wasn't.
*
* Thread-safe.
+1 -2
Ver Arquivo
@@ -66,7 +66,7 @@ public:
SyncFileItem() : _type(UnknownType), _direction(None), _isDirectory(false),
_serverHasIgnoredFiles(false), _hasBlacklistEntry(false),
_errorMayBeBlacklisted(false), _status(NoStatus),
_isRestoration(false), _should_update_metadata(false),
_isRestoration(false),
_httpErrorCode(0), _requestDuration(0), _affectedItems(1),
_instruction(CSYNC_INSTRUCTION_NONE), _modtime(0), _size(0), _inode(0)
{
@@ -156,7 +156,6 @@ public:
// Variables useful to report to the user
Status _status BITFIELD(4);
bool _isRestoration BITFIELD(1); // The original operation was forbidden, and this is a restoration
bool _should_update_metadata BITFIELD(1);
quint16 _httpErrorCode;
QString _errorString; // Contains a string only in case of error
QByteArray _responseTimeStamp;
+2 -2
Ver Arquivo
@@ -32,7 +32,7 @@ void SyncFileStatus::set(SyncFileStatusTag tag)
_tag = tag;
}
SyncFileStatus::SyncFileStatusTag SyncFileStatus::tag()
SyncFileStatus::SyncFileStatusTag SyncFileStatus::tag() const
{
return _tag;
}
@@ -42,7 +42,7 @@ void SyncFileStatus::setSharedWithMe(bool isShared)
_sharedWithMe = isShared;
}
bool SyncFileStatus::sharedWithMe()
bool SyncFileStatus::sharedWithMe() const
{
return _sharedWithMe;
}
+14 -2
Ver Arquivo
@@ -14,6 +14,8 @@
#ifndef SYNCFILESTATUS_H
#define SYNCFILESTATUS_H
#include <QMetaType>
#include <QObject>
#include <QString>
#include "owncloudlib.h"
@@ -39,10 +41,10 @@ public:
SyncFileStatus(SyncFileStatusTag);
void set(SyncFileStatusTag tag);
SyncFileStatusTag tag();
SyncFileStatusTag tag() const;
void setSharedWithMe( bool isShared );
bool sharedWithMe();
bool sharedWithMe() const;
QString toSocketAPIString() const;
private:
@@ -50,6 +52,16 @@ private:
bool _sharedWithMe;
};
inline bool operator==(const SyncFileStatus &a, const SyncFileStatus &b) {
return a.tag() == b.tag() && a.sharedWithMe() == b.sharedWithMe();
}
inline bool operator!=(const SyncFileStatus &a, const SyncFileStatus &b) {
return !(a == b);
}
}
Q_DECLARE_METATYPE(OCC::SyncFileStatus)
#endif // SYNCFILESTATUS_H
+93 -43
Ver Arquivo
@@ -56,7 +56,8 @@ static SyncFileStatus::SyncFileStatusTag lookupProblem(const QString &pathToMatc
static inline bool showErrorInSocketApi(const SyncFileItem& item)
{
const auto status = item._status;
return status == SyncFileItem::NormalError
return item._instruction == CSYNC_INSTRUCTION_ERROR
|| status == SyncFileItem::NormalError
|| status == SyncFileItem::FatalError
|| item._hasBlacklistEntry;
}
@@ -64,7 +65,8 @@ static inline bool showErrorInSocketApi(const SyncFileItem& item)
static inline bool showWarningInSocketApi(const SyncFileItem& item)
{
const auto status = item._status;
return status == SyncFileItem::FileIgnored
return item._instruction == CSYNC_INSTRUCTION_IGNORE
|| status == SyncFileItem::FileIgnored
|| status == SyncFileItem::Conflict
|| status == SyncFileItem::Restoration;
}
@@ -76,28 +78,18 @@ SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
SLOT(slotAboutToPropagate(SyncFileItemVector&)));
connect(syncEngine, SIGNAL(itemCompleted(const SyncFileItem&, const PropagatorJob&)),
SLOT(slotItemCompleted(const SyncFileItem&)));
connect(syncEngine, SIGNAL(finished(bool)), SLOT(slotSyncFinished()));
connect(syncEngine, SIGNAL(started()), SLOT(slotSyncEngineRunningChanged()));
connect(syncEngine, SIGNAL(finished(bool)), SLOT(slotSyncEngineRunningChanged()));
}
SyncFileItem SyncFileStatusTracker::rootSyncFileItem()
{
SyncFileItem fakeRootItem;
// It's is not entirely correct to use the sync's status as we'll show the root folder as
// syncing even though no child might end up being propagated, but will give us something
// better than always UpToDate for now.
fakeRootItem._status = _syncEngine->isSyncRunning() ? SyncFileItem::NoStatus : SyncFileItem::Success;
fakeRootItem._isDirectory = true;
return fakeRootItem;
}
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
{
Q_ASSERT(!relativePath.endsWith(QLatin1Char('/')));
if (relativePath.isEmpty()) {
// This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so create one manually.
return syncFileItemStatus(rootSyncFileItem());
// This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so resolve manually.
return resolveSyncAndErrorStatus(QString(), NotShared);
}
// The SyncEngine won't notify us at all for CSYNC_FILE_SILENTLY_EXCLUDED
@@ -115,18 +107,14 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
if ( _dirtyPaths.contains(relativePath) )
return SyncFileStatus::StatusSync;
SyncFileItem* item = _syncEngine->findSyncItem(relativePath);
if (item) {
return syncFileItemStatus(*item);
}
// If we're not currently syncing that file, look it up in the database to know if it's shared
// First look it up in the database to know if it's shared
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath);
if (rec.isValid()) {
return syncFileItemStatus(rec.toSyncFileItem());
return resolveSyncAndErrorStatus(relativePath, rec._remotePerm.contains("S") ? Shared : NotShared);
}
// Must be a new file, wait for the filesystem watcher to trigger a sync
return SyncFileStatus();
// Must be a new file not yet in the database, check if it's syncing or has an error.
return resolveSyncAndErrorStatus(relativePath, NotShared, PathUnknown);
}
void SyncFileStatusTracker::slotPathTouched(const QString& fileName)
@@ -140,21 +128,74 @@ void SyncFileStatusTracker::slotPathTouched(const QString& fileName)
emit fileStatusChanged(fileName, SyncFileStatus::StatusSync);
}
void SyncFileStatusTracker::incSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange)
{
// Will return 0 (and increase to 1) if the path wasn't in the map yet
int count = _syncCount[relativePath]++;
if (!count) {
if (emitStatusChange)
emit fileStatusChanged(getSystemDestination(relativePath), fileStatus(relativePath));
// We passed from OK to SYNC, increment the parent to keep it marked as
// SYNC while we propagate ourselves and our own children.
Q_ASSERT(!relativePath.endsWith('/'));
int lastSlashIndex = relativePath.lastIndexOf('/');
if (lastSlashIndex != -1)
incSyncCount(relativePath.left(lastSlashIndex), EmitStatusChange);
else if (!relativePath.isEmpty())
incSyncCount(QString(), EmitStatusChange);
}
}
void SyncFileStatusTracker::decSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange)
{
int count = --_syncCount[relativePath];
if (!count) {
// Remove from the map, same as 0
_syncCount.remove(relativePath);
if (emitStatusChange)
emit fileStatusChanged(getSystemDestination(relativePath), fileStatus(relativePath));
// We passed from SYNC to OK, decrement our parent.
Q_ASSERT(!relativePath.endsWith('/'));
int lastSlashIndex = relativePath.lastIndexOf('/');
if (lastSlashIndex != -1)
decSyncCount(relativePath.left(lastSlashIndex), EmitStatusChange);
else if (!relativePath.isEmpty())
decSyncCount(QString(), EmitStatusChange);
}
}
void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
{
Q_ASSERT(_syncCount.isEmpty());
std::map<QString, SyncFileStatus::SyncFileStatusTag> oldProblems;
std::swap(_syncProblems, oldProblems);
foreach (const SyncFileItemPtr &item, items) {
// qDebug() << Q_FUNC_INFO << "Investigating" << item->destination() << item->_status;
// qDebug() << Q_FUNC_INFO << "Investigating" << item->destination() << item->_status << item->_instruction;
if (showErrorInSocketApi(*item)) {
_syncProblems[item->_file] = SyncFileStatus::StatusError;
invalidateParentPaths(item->destination());
} else if (showWarningInSocketApi(*item)) {
_syncProblems[item->_file] = SyncFileStatus::StatusWarning;
}
// Mark this path as syncing for instructions that will result in propagation,
// but DontEmitStatusChange since we're going to emit for ourselves using the
// info in the SyncFileItem we received, parents will still be emit if needed.
if (item->_instruction != CSYNC_INSTRUCTION_NONE
&& item->_instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
&& item->_instruction != CSYNC_INSTRUCTION_IGNORE
&& item->_instruction != CSYNC_INSTRUCTION_ERROR) {
incSyncCount(item->destination(), DontEmitStatusChange);
}
_dirtyPaths.remove(item->destination());
emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item));
emit fileStatusChanged(getSystemDestination(item->destination()), resolveSyncAndErrorStatus(item->destination(), item->_remotePerm.contains("S") ? Shared : NotShared));
}
// Some metadata status won't trigger files to be synced, make sure that we
@@ -180,7 +221,7 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item)
{
// qDebug() << Q_FUNC_INFO << item.destination() << item._status;
// qDebug() << Q_FUNC_INFO << item.destination() << item._status << item._instruction;
if (showErrorInSocketApi(item)) {
_syncProblems[item._file] = SyncFileStatus::StatusError;
@@ -191,37 +232,46 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item)
_syncProblems.erase(item._file);
}
emit fileStatusChanged(getSystemDestination(item.destination()), syncFileItemStatus(item));
// decSyncCount calls *must* be symetric with incSyncCount calls in slotAboutToPropagate
if (item._instruction != CSYNC_INSTRUCTION_NONE
&& item._instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
&& item._instruction != CSYNC_INSTRUCTION_IGNORE
&& item._instruction != CSYNC_INSTRUCTION_ERROR) {
decSyncCount(item.destination(), DontEmitStatusChange);
}
emit fileStatusChanged(getSystemDestination(item.destination()), resolveSyncAndErrorStatus(item.destination(), item._remotePerm.contains("S") ? Shared : NotShared));
}
void SyncFileStatusTracker::slotSyncFinished()
{
// Clear the sync counts to reduce the impact of unsymetrical inc/dec calls (e.g. when directory job abort)
QHash<QString, int> oldSyncCount;
std::swap(_syncCount, oldSyncCount);
for (auto it = oldSyncCount.begin(); it != oldSyncCount.end(); ++it)
emit fileStatusChanged(getSystemDestination(it.key()), fileStatus(it.key()));
}
void SyncFileStatusTracker::slotSyncEngineRunningChanged()
{
emit fileStatusChanged(_syncEngine->localPath(), syncFileItemStatus(rootSyncFileItem()));
emit fileStatusChanged(_syncEngine->localPath(), resolveSyncAndErrorStatus(QString(), NotShared));
}
SyncFileStatus SyncFileStatusTracker::syncFileItemStatus(const SyncFileItem& item)
SyncFileStatus SyncFileStatusTracker::resolveSyncAndErrorStatus(const QString &relativePath, SharedFlag isShared, PathKnownFlag isPathKnown)
{
// Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate)
// Mark any directory in the SyncEngine's items as syncing, this is currently how we mark parent directories
// of currently syncing items since the PropagateDirectory job will mark the directorie's SyncFileItem::_status as Success
// once all child jobs have been completed.
bool waitingForPropagation = (item._isDirectory || item._direction != SyncFileItem::None) && item._status == SyncFileItem::NoStatus;
SyncFileStatus status(SyncFileStatus::StatusUpToDate);
if (waitingForPropagation) {
// If it's a new file and that we're not syncing it yet,
// don't show any icon and wait for the filesystem watcher to trigger a sync.
SyncFileStatus status(isPathKnown ? SyncFileStatus::StatusUpToDate : SyncFileStatus::StatusNone);
if (_syncCount.value(relativePath)) {
status.set(SyncFileStatus::StatusSync);
} else if (showErrorInSocketApi(item)) {
status.set(SyncFileStatus::StatusError);
} else if (showWarningInSocketApi(item)) {
status.set(SyncFileStatus::StatusWarning);
} else {
// After a sync finished, we need to show the users issues from that last sync like the activity list does.
// Also used for parent directories showing a warning for an error child.
SyncFileStatus::SyncFileStatusTag problemStatus = lookupProblem(item.destination(), _syncProblems);
SyncFileStatus::SyncFileStatusTag problemStatus = lookupProblem(relativePath, _syncProblems);
if (problemStatus != SyncFileStatus::StatusNone)
status.set(problemStatus);
}
if (item._remotePerm.contains("S"))
if (isShared)
status.setSharedWithMe(true);
return status;
+8 -2
Ver Arquivo
@@ -46,19 +46,25 @@ signals:
private slots:
void slotAboutToPropagate(SyncFileItemVector& items);
void slotItemCompleted(const SyncFileItem& item);
void slotSyncFinished();
void slotSyncEngineRunningChanged();
private:
SyncFileStatus syncFileItemStatus(const SyncFileItem& item);
SyncFileItem rootSyncFileItem();
enum SharedFlag { NotShared = 0, Shared };
enum PathKnownFlag { PathUnknown = 0, PathKnown };
enum EmitStatusChangeFlag { DontEmitStatusChange = 0, EmitStatusChange };
SyncFileStatus resolveSyncAndErrorStatus(const QString &relativePath, SharedFlag isShared, PathKnownFlag isPathKnown = PathKnown);
void invalidateParentPaths(const QString& path);
QString getSystemDestination(const QString& relativePath);
void incSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange);
void decSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange);
SyncEngine* _syncEngine;
std::map<QString, SyncFileStatus::SyncFileStatusTag> _syncProblems;
QSet<QString> _dirtyPaths;
QHash<QString, int> _syncCount;
};
}
+41
Ver Arquivo
@@ -385,6 +385,12 @@ bool SyncJournalDb::checkConnect()
" SET contentChecksum = ?2, contentChecksumTypeId = ?3"
" WHERE phash == ?1;");
_setFileRecordLocalMetadataQuery.reset(new SqlQuery(_db));
_setFileRecordLocalMetadataQuery->prepare(
"UPDATE metadata"
" SET inode=?2, modtime=?3, filesize=?4"
" WHERE phash == ?1;");
_getDownloadInfoQuery.reset(new SqlQuery(_db) );
_getDownloadInfoQuery->prepare( "SELECT tmpfile, etag, errorcount FROM "
"downloadinfo WHERE path=?1" );
@@ -473,6 +479,7 @@ void SyncJournalDb::close()
_getFileRecordQuery.reset(0);
_setFileRecordQuery.reset(0);
_setFileRecordChecksumQuery.reset(0);
_setFileRecordLocalMetadataQuery.reset(0);
_getDownloadInfoQuery.reset(0);
_setDownloadInfoQuery.reset(0);
_deleteDownloadInfoQuery.reset(0);
@@ -964,6 +971,40 @@ bool SyncJournalDb::updateFileRecordChecksum(const QString& filename,
return true;
}
bool SyncJournalDb::updateLocalMetadata(const QString& filename,
qint64 modtime, quint64 size, quint64 inode)
{
QMutexLocker locker(&_mutex);
qlonglong phash = getPHash(filename);
if( !checkConnect() ) {
qDebug() << "Failed to connect database.";
return false;
}
auto & query = _setFileRecordLocalMetadataQuery;
query->reset_and_clear_bindings();
query->bindValue(1, QString::number(phash));
query->bindValue(2, inode);
query->bindValue(3, modtime);
query->bindValue(4, size);
if( !query->exec() ) {
qWarning() << "Error SQL statement updateLocalMetadata: "
<< query->lastQuery() << " :"
<< query->error();
return false;
}
qDebug() << query->lastQuery() << phash << inode
<< modtime << size;
query->reset_and_clear_bindings();
return true;
}
bool SyncJournalDb::setFileRecordMetadata(const SyncJournalFileRecord& record)
{
SyncJournalFileRecord existing = getFileRecord(record._path);
+3
Ver Arquivo
@@ -52,6 +52,8 @@ public:
bool updateFileRecordChecksum(const QString& filename,
const QByteArray& contentChecksum,
const QByteArray& contentChecksumType);
bool updateLocalMetadata(const QString& filename,
qint64 modtime, quint64 size, quint64 inode);
bool exists();
void walCheckpoint();
@@ -188,6 +190,7 @@ private:
QScopedPointer<SqlQuery> _getFileRecordQuery;
QScopedPointer<SqlQuery> _setFileRecordQuery;
QScopedPointer<SqlQuery> _setFileRecordChecksumQuery;
QScopedPointer<SqlQuery> _setFileRecordLocalMetadataQuery;
QScopedPointer<SqlQuery> _getDownloadInfoQuery;
QScopedPointer<SqlQuery> _setDownloadInfoQuery;
QScopedPointer<SqlQuery> _deleteDownloadInfoQuery;
+4
Ver Arquivo
@@ -42,6 +42,10 @@ owncloud_add_test(FileSystem "")
owncloud_add_test(ChecksumValidator "")
owncloud_add_test(ExcludedFiles "")
if(HAVE_QT5 AND NOT BUILD_WITH_QT4)
owncloud_add_test(SyncEngine "syncenginetestutils.h")
owncloud_add_test(SyncFileStatusTracker "syncenginetestutils.h")
endif(HAVE_QT5 AND NOT BUILD_WITH_QT4)
SET(FolderMan_SRC ../src/gui/folderman.cpp)
list(APPEND FolderMan_SRC ../src/gui/folder.cpp )
+693
Ver Arquivo
@@ -0,0 +1,693 @@
/*
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
*/
#pragma once
#include "account.h"
#include "creds/abstractcredentials.h"
#include "filesystem.h"
#include "syncengine.h"
#include "syncjournaldb.h"
#include <QDir>
#include <QNetworkReply>
#include <QtTest>
static const QUrl sRootUrl("owncloud://somehost/owncloud/remote.php/webdav/");
namespace {
QString generateEtag() {
return QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch(), 16);
}
class PathComponents : public QStringList {
public:
PathComponents(const QString &path) : QStringList{path.split('/', QString::SkipEmptyParts)} { }
PathComponents(const QStringList &pathComponents) : QStringList{pathComponents} { }
PathComponents parentDirComponents() const {
return PathComponents{mid(0, size() - 1)};
}
PathComponents subComponents() const { return PathComponents{mid(1)}; }
QString pathRoot() const { return first(); }
QString fileName() const { return last(); }
};
}
class FileModifier
{
public:
virtual ~FileModifier() { }
virtual void remove(const QString &relativePath) = 0;
virtual void insert(const QString &relativePath, qint64 size = 64, char contentChar = 'W') = 0;
virtual void setContents(const QString &relativePath, char contentChar) = 0;
virtual void appendByte(const QString &relativePath) = 0;
virtual void mkdir(const QString &relativePath) = 0;
};
class DiskFileModifier : public FileModifier
{
QDir _rootDir;
public:
DiskFileModifier(const QString &rootDirPath) : _rootDir(rootDirPath) { }
void remove(const QString &relativePath) override {
QFileInfo fi{_rootDir.filePath(relativePath)};
if (fi.isFile())
QVERIFY(_rootDir.remove(relativePath));
else
QVERIFY(QDir{fi.filePath()}.removeRecursively());
}
void insert(const QString &relativePath, qint64 size = 64, char contentChar = 'W') override {
QFile file{_rootDir.filePath(relativePath)};
QVERIFY(!file.exists());
file.open(QFile::WriteOnly);
file.write(QByteArray{}.fill(contentChar, size));
file.close();
// Set the mtime 30 seconds in the past, for some tests that need to make sure that the mtime differs.
OCC::FileSystem::setModTime(file.fileName(), OCC::Utility::qDateTimeToTime_t(QDateTime::currentDateTime().addSecs(-30)));
}
void setContents(const QString &relativePath, char contentChar) override {
QFile file{_rootDir.filePath(relativePath)};
QVERIFY(file.exists());
qint64 size = file.size();
file.open(QFile::WriteOnly);
file.write(QByteArray{}.fill(contentChar, size));
}
void appendByte(const QString &relativePath) override {
QFile file{_rootDir.filePath(relativePath)};
QVERIFY(file.exists());
file.open(QFile::ReadWrite);
QByteArray contents = file.read(1);
file.seek(file.size());
file.write(contents);
}
void mkdir(const QString &relativePath) override {
_rootDir.mkpath(relativePath);
}
};
class FileInfo : public FileModifier
{
public:
static FileInfo A12_B12_C12_S12() {
FileInfo fi{QString{}, {
{QStringLiteral("A"), {
{QStringLiteral("a1"), 4},
{QStringLiteral("a2"), 4}
}},
{QStringLiteral("B"), {
{QStringLiteral("b1"), 16},
{QStringLiteral("b2"), 16}
}},
{QStringLiteral("C"), {
{QStringLiteral("c1"), 24},
{QStringLiteral("c2"), 24}
}},
}};
FileInfo sharedFolder{QStringLiteral("S"), {
{QStringLiteral("s1"), 32},
{QStringLiteral("s2"), 32}
}};
sharedFolder.isShared = true;
sharedFolder.children[QStringLiteral("s1")].isShared = true;
sharedFolder.children[QStringLiteral("s2")].isShared = true;
fi.children.insert(sharedFolder.name, std::move(sharedFolder));
return fi;
}
FileInfo() = default;
FileInfo(const QString &name) : name{name} { }
FileInfo(const QString &name, qint64 size) : name{name}, isDir{false}, size{size} { }
FileInfo(const QString &name, qint64 size, char contentChar) : name{name}, isDir{false}, size{size}, contentChar{contentChar} { }
FileInfo(const QString &name, const std::initializer_list<FileInfo> &children) : name{name} {
QString p = path();
for (const auto &source : children) {
auto &dest = this->children[source.name] = source;
dest.parentPath = p;
}
}
void remove(const QString &relativePath) override {
const PathComponents pathComponents{relativePath};
FileInfo *parent = findInvalidatingEtags(pathComponents.parentDirComponents());
Q_ASSERT(parent);
parent->children.erase(std::find_if(parent->children.begin(), parent->children.end(),
[&pathComponents](const FileInfo &fi){ return fi.name == pathComponents.fileName(); }));
}
void insert(const QString &relativePath, qint64 size = 64, char contentChar = 'W') override {
create(relativePath, size, contentChar);
}
void setContents(const QString &relativePath, char contentChar) override {
FileInfo *file = findInvalidatingEtags(relativePath);
Q_ASSERT(file);
file->contentChar = contentChar;
}
void appendByte(const QString &relativePath) override {
FileInfo *file = findInvalidatingEtags(relativePath);
Q_ASSERT(file);
file->size += 1;
}
void mkdir(const QString &relativePath) override {
createDir(relativePath);
}
FileInfo *find(const PathComponents &pathComponents, const bool invalidateEtags = false) {
if (pathComponents.isEmpty()) {
if (invalidateEtags)
etag = generateEtag();
return this;
}
QString childName = pathComponents.pathRoot();
auto it = children.find(childName);
if (it != children.end()) {
auto file = it->find(pathComponents.subComponents(), invalidateEtags);
if (file && invalidateEtags)
// Update parents on the way back
etag = file->etag;
return file;
}
return nullptr;
}
FileInfo *createDir(const QString &relativePath) {
const PathComponents pathComponents{relativePath};
FileInfo *parent = findInvalidatingEtags(pathComponents.parentDirComponents());
Q_ASSERT(parent);
FileInfo &child = parent->children[pathComponents.fileName()] = FileInfo{pathComponents.fileName()};
child.parentPath = parent->path();
child.etag = generateEtag();
return &child;
}
FileInfo *create(const QString &relativePath, qint64 size, char contentChar) {
const PathComponents pathComponents{relativePath};
FileInfo *parent = findInvalidatingEtags(pathComponents.parentDirComponents());
Q_ASSERT(parent);
FileInfo &child = parent->children[pathComponents.fileName()] = FileInfo{pathComponents.fileName(), size};
child.parentPath = parent->path();
child.contentChar = contentChar;
child.etag = generateEtag();
return &child;
}
bool operator<(const FileInfo &other) const {
return name < other.name;
}
bool operator==(const FileInfo &other) const {
// Consider files to be equal between local<->remote as a user would.
return name == other.name
&& isDir == other.isDir
&& size == other.size
&& contentChar == other.contentChar
&& children == other.children;
}
QString path() const {
return (parentPath.isEmpty() ? QString() : (parentPath + '/')) + name;
}
QString name;
bool isDir = true;
bool isShared = false;
QDateTime lastModified = QDateTime::currentDateTime().addDays(-7);
QString etag = generateEtag();
qint64 size = 0;
char contentChar = 'W';
// Sorted by name to be able to compare trees
QMap<QString, FileInfo> children;
QString parentPath;
private:
FileInfo *findInvalidatingEtags(const PathComponents &pathComponents) {
return find(pathComponents, true);
}
};
class FakePropfindReply : public QNetworkReply
{
Q_OBJECT
public:
QByteArray payload;
FakePropfindReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent)
: QNetworkReply{parent} {
setRequest(request);
setUrl(request.url());
setOperation(op);
open(QIODevice::ReadOnly);
// Don't care about the request and just return a full propfind
const QString davUri{QStringLiteral("DAV:")};
const QString ocUri{QStringLiteral("http://owncloud.org/ns")};
QBuffer buffer{&payload};
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter xml( &buffer );
xml.writeNamespace(davUri, "d");
xml.writeNamespace(ocUri, "oc");
xml.writeStartDocument();
xml.writeStartElement(davUri, QStringLiteral("multistatus"));
auto writeFileResponse = [&](const FileInfo &fileInfo) {
xml.writeStartElement(davUri, QStringLiteral("response"));
xml.writeTextElement(davUri, QStringLiteral("href"), "/owncloud/remote.php/webdav/" + fileInfo.path());
xml.writeStartElement(davUri, QStringLiteral("propstat"));
xml.writeStartElement(davUri, QStringLiteral("prop"));
if (fileInfo.isDir) {
xml.writeStartElement(davUri, QStringLiteral("resourcetype"));
xml.writeEmptyElement(davUri, QStringLiteral("collection"));
xml.writeEndElement(); // resourcetype
} else
xml.writeEmptyElement(davUri, QStringLiteral("resourcetype"));
auto gmtDate = fileInfo.lastModified.toTimeZone(QTimeZone("GMT"));
auto stringDate = gmtDate.toString("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.writeEndElement(); // prop
xml.writeTextElement(davUri, QStringLiteral("status"), "HTTP/1.1 200 OK");
xml.writeEndElement(); // propstat
xml.writeEndElement(); // response
};
Q_ASSERT(request.url().path().startsWith(sRootUrl.path()));
QString fileName = request.url().path().mid(sRootUrl.path().length());
const FileInfo *fileInfo = remoteRootFileInfo.find(fileName);
writeFileResponse(*fileInfo);
foreach(const FileInfo &childFileInfo, fileInfo->children)
writeFileResponse(childFileInfo);
xml.writeEndElement(); // multistatus
xml.writeEndDocument();
QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection);
}
Q_INVOKABLE void respond() {
setHeader(QNetworkRequest::ContentLengthHeader, payload.size());
setHeader(QNetworkRequest::ContentTypeHeader, "application/xml; charset=utf-8");
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 207);
setFinished(true);
emit metaDataChanged();
if (bytesAvailable())
emit readyRead();
emit finished();
}
void abort() override { }
qint64 bytesAvailable() const override { return payload.size() + QIODevice::bytesAvailable(); }
qint64 readData(char *data, qint64 maxlen) override {
qint64 len = std::min(qint64{payload.size()}, maxlen);
strncpy(data, payload.constData(), len);
payload.remove(0, len);
return len;
}
};
class FakePutReply : public QNetworkReply
{
Q_OBJECT
FileInfo *fileInfo;
public:
FakePutReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &putPayload, QObject *parent)
: QNetworkReply{parent} {
setRequest(request);
setUrl(request.url());
setOperation(op);
open(QIODevice::ReadOnly);
Q_ASSERT(request.url().path().startsWith(sRootUrl.path()));
QString fileName = request.url().path().mid(sRootUrl.path().length());
if ((fileInfo = remoteRootFileInfo.find(fileName))) {
fileInfo->size = putPayload.size();
fileInfo->contentChar = putPayload.at(0);
} else {
// Assume that the file is filled with the same character
fileInfo = remoteRootFileInfo.create(fileName, putPayload.size(), putPayload.at(0));
}
if (!fileInfo) {
abort();
return;
}
QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection);
}
Q_INVOKABLE void respond() {
setRawHeader("OC-ETag", fileInfo->etag.toLatin1());
setRawHeader("ETag", fileInfo->etag.toLatin1());
setRawHeader("X-OC-MTime", "accepted"); // Prevents Q_ASSERT(!_runningNow) since we'll call PropagateItemJob::done twice in that case.
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200);
emit metaDataChanged();
emit finished();
}
void abort() override { }
qint64 readData(char *, qint64) override { return 0; }
};
class FakeMkcolReply : public QNetworkReply
{
Q_OBJECT
FileInfo *fileInfo;
public:
FakeMkcolReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent)
: QNetworkReply{parent} {
setRequest(request);
setUrl(request.url());
setOperation(op);
open(QIODevice::ReadOnly);
Q_ASSERT(request.url().path().startsWith(sRootUrl.path()));
QString fileName = request.url().path().mid(sRootUrl.path().length());
fileInfo = remoteRootFileInfo.createDir(fileName);
if (!fileInfo) {
abort();
return;
}
QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection);
}
Q_INVOKABLE void respond() {
// FIXME: setRawHeader("OC-FileId", fileInfo->???);
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 201);
emit metaDataChanged();
emit finished();
}
void abort() override { }
qint64 readData(char *, qint64) override { return 0; }
};
class FakeDeleteReply : public QNetworkReply
{
Q_OBJECT
public:
FakeDeleteReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent)
: QNetworkReply{parent} {
setRequest(request);
setUrl(request.url());
setOperation(op);
open(QIODevice::ReadOnly);
Q_ASSERT(request.url().path().startsWith(sRootUrl.path()));
QString fileName = request.url().path().mid(sRootUrl.path().length());
remoteRootFileInfo.remove(fileName);
QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection);
}
Q_INVOKABLE void respond() {
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 204);
emit metaDataChanged();
emit finished();
}
void abort() override { }
qint64 readData(char *, qint64) override { return 0; }
};
class FakeGetReply : public QNetworkReply
{
Q_OBJECT
public:
const FileInfo *fileInfo;
QByteArray payload;
FakeGetReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent)
: QNetworkReply{parent} {
setRequest(request);
setUrl(request.url());
setOperation(op);
open(QIODevice::ReadOnly);
Q_ASSERT(request.url().path().startsWith(sRootUrl.path()));
QString fileName = request.url().path().mid(sRootUrl.path().length());
fileInfo = remoteRootFileInfo.find(fileName);
QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection);
}
Q_INVOKABLE void respond() {
payload.fill(fileInfo->contentChar, fileInfo->size);
setHeader(QNetworkRequest::ContentLengthHeader, payload.size());
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200);
setRawHeader("OC-ETag", fileInfo->etag.toLatin1());
setRawHeader("ETag", fileInfo->etag.toLatin1());
emit metaDataChanged();
if (bytesAvailable())
emit readyRead();
emit finished();
}
void abort() override { }
qint64 bytesAvailable() const override { return payload.size() + QIODevice::bytesAvailable(); }
qint64 readData(char *data, qint64 maxlen) override {
qint64 len = std::min(qint64{payload.size()}, maxlen);
strncpy(data, payload.constData(), len);
payload.remove(0, len);
return len;
}
};
class FakeErrorReply : public QNetworkReply
{
Q_OBJECT
public:
FakeErrorReply(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent)
: QNetworkReply{parent} {
setRequest(request);
setUrl(request.url());
setOperation(op);
open(QIODevice::ReadOnly);
QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection);
}
Q_INVOKABLE void respond() {
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 500);
emit metaDataChanged();
emit finished();
}
void abort() override { }
qint64 readData(char *, qint64) override { return 0; }
};
class FakeQNAM : public QNetworkAccessManager
{
FileInfo _remoteRootFileInfo;
QStringList _errorPaths;
public:
FakeQNAM(FileInfo initialRoot) : _remoteRootFileInfo{std::move(initialRoot)} { }
FileInfo &currentRemoteState() { return _remoteRootFileInfo; }
QStringList &errorPaths() { return _errorPaths; }
protected:
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
QIODevice *outgoingData = 0) {
const QString fileName = request.url().path().mid(sRootUrl.path().length());
if (_errorPaths.contains(fileName))
return new FakeErrorReply{op, request, this};
auto verb = request.attribute(QNetworkRequest::CustomVerbAttribute);
if (verb == QLatin1String("PROPFIND"))
// Ignore outgoingData always returning somethign good enough, works for now.
return new FakePropfindReply{_remoteRootFileInfo, op, request, this};
else if (verb == QLatin1String("GET"))
return new FakeGetReply{_remoteRootFileInfo, op, request, this};
else if (verb == QLatin1String("PUT"))
return new FakePutReply{_remoteRootFileInfo, op, request, outgoingData->readAll(), this};
else if (verb == QLatin1String("MKCOL"))
return new FakeMkcolReply{_remoteRootFileInfo, op, request, this};
else if (verb == QLatin1String("DELETE"))
return new FakeDeleteReply{_remoteRootFileInfo, op, request, this};
else {
qDebug() << verb << outgoingData;
Q_UNREACHABLE();
}
}
};
class FakeCredentials : public OCC::AbstractCredentials
{
QNetworkAccessManager *_qnam;
public:
FakeCredentials(QNetworkAccessManager *qnam) : _qnam{qnam} { }
virtual bool changed(AbstractCredentials *) const { return false; }
virtual QString authType() const { return "test"; }
virtual QString user() const { return "admin"; }
virtual QNetworkAccessManager* getQNAM() const { return _qnam; }
virtual bool ready() const { return true; }
virtual void fetchFromKeychain() { }
virtual void askFromUser() { }
virtual bool stillValid(QNetworkReply *) { return true; }
virtual void persist() { }
virtual void invalidateToken() { }
virtual void forgetSensitiveData() { }
};
class FakeFolder
{
QTemporaryDir _tempDir;
DiskFileModifier _localModifier;
// FIXME: Clarify ownership, double delete
FakeQNAM *_fakeQnam;
OCC::AccountPtr _account;
std::unique_ptr<OCC::SyncJournalDb> _journalDb;
std::unique_ptr<OCC::SyncEngine> _syncEngine;
public:
FakeFolder(const FileInfo &fileTemplate)
: _localModifier(_tempDir.path())
{
// Needs to be done once
OCC::SyncEngine::minimumFileAgeForUpload = 0;
csync_set_log_level(11);
QDir rootDir{_tempDir.path()};
toDisk(rootDir, fileTemplate);
_fakeQnam = new FakeQNAM(fileTemplate);
_account = OCC::Account::create();
_account->setUrl(QUrl(QStringLiteral("http://admin:admin@localhost/owncloud")));
_account->setCredentials(new FakeCredentials{_fakeQnam});
_journalDb.reset(new OCC::SyncJournalDb(localPath()));
_syncEngine.reset(new OCC::SyncEngine(_account, localPath(), sRootUrl, "", _journalDb.get()));
// A new folder will update the local file state database on first sync.
// To have a state matching what users will encounter, we have to a sync
// using an identical local/remote file tree first.
syncOnce();
}
OCC::SyncEngine &syncEngine() const { return *_syncEngine; }
FileModifier &localModifier() { return _localModifier; }
FileModifier &remoteModifier() { return _fakeQnam->currentRemoteState(); }
FileInfo currentLocalState() {
QDir rootDir{_tempDir.path()};
FileInfo rootTemplate;
fromDisk(rootDir, rootTemplate);
return rootTemplate;
}
FileInfo currentRemoteState() { return _fakeQnam->currentRemoteState(); }
QStringList &serverErrorPaths() { return _fakeQnam->errorPaths(); }
QString localPath() const {
// SyncEngine wants a trailing slash
if (_tempDir.path().endsWith('/'))
return _tempDir.path();
return _tempDir.path() + '/';
}
void scheduleSync() {
// Have to be done async, else, an error before exec() does not terminate the event loop.
QMetaObject::invokeMethod(_syncEngine.get(), "startSync", Qt::QueuedConnection);
}
void execUntilBeforePropagation() {
QSignalSpy spy(_syncEngine.get(), SIGNAL(aboutToPropagate(SyncFileItemVector&)));
QVERIFY(spy.wait());
}
void execUntilItemCompleted(const QString &relativePath) {
QSignalSpy spy(_syncEngine.get(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
QElapsedTimer t;
t.start();
while (t.elapsed() < 5000) {
spy.clear();
QVERIFY(spy.wait());
for(const QList<QVariant> &args : spy) {
auto item = args[0].value<OCC::SyncFileItem>();
if (item.destination() == relativePath)
return;
}
}
QVERIFY(false);
}
void execUntilFinished() {
QSignalSpy spy(_syncEngine.get(), SIGNAL(finished(bool)));
QVERIFY(spy.wait());
}
void syncOnce() {
scheduleSync();
execUntilFinished();
}
private:
static void toDisk(QDir &dir, const FileInfo &templateFi) {
foreach (const FileInfo &child, templateFi.children) {
if (child.isDir) {
QDir subDir(dir);
dir.mkdir(child.name);
subDir.cd(child.name);
toDisk(subDir, child);
} else {
QFile file{dir.filePath(child.name)};
file.open(QFile::WriteOnly);
file.write(QByteArray{}.fill(child.contentChar, child.size));
file.close();
OCC::FileSystem::setModTime(file.fileName(), OCC::Utility::qDateTimeToTime_t(child.lastModified));
}
}
}
static void fromDisk(QDir &dir, FileInfo &templateFi) {
foreach (const QFileInfo &diskChild, dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
if (diskChild.isDir()) {
QDir subDir = dir;
subDir.cd(diskChild.fileName());
templateFi.children.insert(diskChild.fileName(), FileInfo{diskChild.fileName()});
fromDisk(subDir, templateFi.children.last());
} else {
QFile f{diskChild.filePath()};
f.open(QFile::ReadOnly);
char contentChar = f.read(1).at(0);
templateFi.children.insert(diskChild.fileName(), FileInfo{diskChild.fileName(), diskChild.size(), contentChar});
}
}
}
};
// QTest::toString overloads
namespace OCC {
inline char *toString(const SyncFileStatus &s) {
return QTest::toString(QString("SyncFileStatus(" + s.toSocketAPIString() + ")"));
}
}
inline void addFiles(QStringList &dest, const FileInfo &fi)
{
if (fi.isDir) {
dest += QString("%1 - dir").arg(fi.name);
foreach (const FileInfo &fi, fi.children)
addFiles(dest, fi);
} else {
dest += QString("%1 - %2 %3-bytes").arg(fi.name).arg(fi.size).arg(fi.contentChar);
}
}
inline char *toString(const FileInfo &fi)
{
QStringList files;
foreach (const FileInfo &fi, fi.children)
addFiles(files, fi);
return QTest::toString(QString("FileInfo with %1 files(%2)").arg(files.size()).arg(files.join(", ")));
}
+125
Ver Arquivo
@@ -0,0 +1,125 @@
/*
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
*/
#include <QtTest>
#include "syncenginetestutils.h"
using namespace OCC;
bool itemDidComplete(const QSignalSpy &spy, const QString &path)
{
for(const QList<QVariant> &args : spy) {
SyncFileItem item = args[0].value<SyncFileItem>();
if (item.destination() == path)
return true;
}
return false;
}
bool itemDidCompleteSuccessfully(const QSignalSpy &spy, const QString &path)
{
for(const QList<QVariant> &args : spy) {
SyncFileItem item = args[0].value<SyncFileItem>();
if (item.destination() == path)
return item._status == SyncFileItem::Success;
}
return false;
}
class TestSyncEngine : public QObject
{
Q_OBJECT
private slots:
void testFileDownload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
fakeFolder.remoteModifier().insert("A/a0");
fakeFolder.syncOnce();
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "A/a0"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testFileUpload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
fakeFolder.localModifier().insert("A/a0");
fakeFolder.syncOnce();
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "A/a0"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testDirDownload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
fakeFolder.remoteModifier().mkdir("Y");
fakeFolder.remoteModifier().mkdir("Z");
fakeFolder.remoteModifier().insert("Z/d0");
fakeFolder.syncOnce();
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "Y"));
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "Z"));
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "Z/d0"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testDirUpload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
fakeFolder.localModifier().mkdir("Y");
fakeFolder.localModifier().mkdir("Z");
fakeFolder.localModifier().insert("Z/d0");
fakeFolder.syncOnce();
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "Y"));
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "Z"));
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "Z/d0"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testLocalDelete() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
fakeFolder.remoteModifier().remove("A/a1");
fakeFolder.syncOnce();
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "A/a1"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testRemoteDelete() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
fakeFolder.localModifier().remove("A/a1");
fakeFolder.syncOnce();
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "A/a1"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testEmlLocalChecksum() {
FakeFolder fakeFolder{FileInfo{}};
fakeFolder.localModifier().insert("a1.eml", 64, 'A');
fakeFolder.localModifier().insert("a2.eml", 64, 'A');
fakeFolder.localModifier().insert("a3.eml", 64, 'A');
// Upload and calculate the checksums
// fakeFolder.syncOnce();
fakeFolder.syncOnce();
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
// Touch the file without changing the content, shouldn't upload
fakeFolder.localModifier().setContents("a1.eml", 'A');
// Change the content/size
fakeFolder.localModifier().setContents("a2.eml", 'B');
fakeFolder.localModifier().appendByte("a3.eml");
fakeFolder.syncOnce();
QVERIFY(!itemDidComplete(completeSpy, "a1.eml"));
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "a2.eml"));
QVERIFY(itemDidCompleteSuccessfully(completeSpy, "a3.eml"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
};
QTEST_GUILESS_MAIN(TestSyncEngine)
#include "testsyncengine.moc"
+404
Ver Arquivo
@@ -0,0 +1,404 @@
/*
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
*/
#include <QtTest>
#include "syncenginetestutils.h"
using namespace OCC;
class StatusPushSpy : public QSignalSpy
{
SyncEngine &_syncEngine;
public:
StatusPushSpy(SyncEngine &syncEngine)
: QSignalSpy(&syncEngine.syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString&, SyncFileStatus)))
, _syncEngine(syncEngine)
{ }
SyncFileStatus statusOf(const QString &relativePath) const {
QFileInfo file(_syncEngine.localPath(), relativePath);
// Start from the end to get the latest status
for (int i = size() - 1; i >= 0; --i) {
if (QFileInfo(at(i)[0].toString()) == file)
return at(i)[1].value<SyncFileStatus>();
}
return SyncFileStatus();
}
};
class TestSyncFileStatusTracker : public QObject
{
Q_OBJECT
void verifyThatPushMatchesPull(const FakeFolder &fakeFolder, const StatusPushSpy &statusSpy) {
QString root = fakeFolder.localPath();
QDirIterator it(root, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString filePath = it.next().mid(root.size());
SyncFileStatus pushedStatus = statusSpy.statusOf(filePath);
if (pushedStatus != SyncFileStatus())
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus(filePath), pushedStatus);
}
}
private slots:
void parentsGetSyncStatusUploadDownload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.localModifier().appendByte("B/b1");
fakeFolder.remoteModifier().appendByte("C/c1");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B/b1"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("C/c1"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("B/b2"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("C/c2"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B/b1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("C/c1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void parentsGetSyncStatusNewFileUploadDownload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.localModifier().insert("B/b0");
fakeFolder.remoteModifier().insert("C/c0");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("C/c0"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("B/b1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("C/c1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("C/c0"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void parentsGetSyncStatusNewDirDownload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.remoteModifier().mkdir("D");
fakeFolder.remoteModifier().insert("D/d0");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D/d0"), SyncFileStatus(SyncFileStatus::StatusSync));
fakeFolder.execUntilItemCompleted("D");
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D/d0"), SyncFileStatus(SyncFileStatus::StatusSync));
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("D"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("D/d0"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void parentsGetSyncStatusNewDirUpload() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.localModifier().mkdir("D");
fakeFolder.localModifier().insert("D/d0");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D/d0"), SyncFileStatus(SyncFileStatus::StatusSync));
fakeFolder.execUntilItemCompleted("D");
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("D/d0"), SyncFileStatus(SyncFileStatus::StatusSync));
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("D"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("D/d0"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void parentsGetSyncStatusDeleteUpDown() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.remoteModifier().remove("B/b1");
fakeFolder.localModifier().remove("C/c1");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusSync));
// Discovered as remotely removed, pending for local removal.
QCOMPARE(statusSpy.statusOf("B/b1"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("B/b2"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("C/c2"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void warningStatusForExcludedFile() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.syncEngine().excludedFiles().addExcludeExpr("A/a1");
fakeFolder.syncEngine().excludedFiles().addExcludeExpr("B");
fakeFolder.localModifier().appendByte("A/a1");
fakeFolder.localModifier().appendByte("B/b1");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusWarning));
QEXPECT_FAIL("", "csync will stop at ignored directories without traversing children, so we don't currently push the status for newly ignored children of an ignored directory.", Continue);
QCOMPARE(statusSpy.statusOf("B/b1"), SyncFileStatus(SyncFileStatus::StatusWarning));
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusWarning));
QEXPECT_FAIL("", "csync will stop at ignored directories without traversing children, so we don't currently push the status for newly ignored children of an ignored directory.", Continue);
QCOMPARE(statusSpy.statusOf("B/b1"), SyncFileStatus(SyncFileStatus::StatusWarning));
QEXPECT_FAIL("", "csync will stop at ignored directories without traversing children, so we don't currently push the status for newly ignored children of an ignored directory.", Continue);
QCOMPARE(statusSpy.statusOf("B/b2"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
statusSpy.clear();
// Clears the exclude expr above
fakeFolder.syncEngine().excludedFiles().reloadExcludes();
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B/b1"), SyncFileStatus(SyncFileStatus::StatusSync));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B/b1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void parentsGetWarningStatusForError() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.serverErrorPaths().append("A/a1");
fakeFolder.serverErrorPaths().append("B/b0");
fakeFolder.localModifier().appendByte("A/a1");
fakeFolder.localModifier().insert("B/b0");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusSync));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a2"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusError));
statusSpy.clear();
// Remove the error and start a second sync, the blacklist should kick in
fakeFolder.serverErrorPaths().clear();
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
// A/a1 and B/b0 should be on the black list for the next few seconds
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusError));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a2"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusError));
statusSpy.clear();
// Start a third sync, this time together with a real file to sync
fakeFolder.localModifier().appendByte("C/c1");
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
// The root should show SYNC even though there is an error underneath,
// since C/c1 is syncing and the SYNC status has priority.
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("C/c1"), SyncFileStatus(SyncFileStatus::StatusSync));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a2"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(statusSpy.statusOf("C"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("C/c1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
statusSpy.clear();
// Another sync after clearing the blacklist entry, everything should return to order.
fakeFolder.syncEngine().journal()->wipeErrorBlacklistEntry("A/a1");
fakeFolder.syncEngine().journal()->wipeErrorBlacklistEntry("B/b0");
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusSync));
statusSpy.clear();
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("A"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("A/a1"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("B/b0"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void parentsGetWarningStatusForError_SibblingStartsWithPath() {
// A is a parent of A/a1, but A/a is not even if it's a substring of A/a1
FakeFolder fakeFolder{{QString{},{
{QStringLiteral("A"), {
{QStringLiteral("a"), 4},
{QStringLiteral("a1"), 4}
}}}}};
fakeFolder.serverErrorPaths().append("A/a1");
fakeFolder.localModifier().appendByte("A/a1");
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
// The SyncFileStatusTraker won't push any status for all of them, test with a pull.
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus(""), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a1"), SyncFileStatus(SyncFileStatus::StatusSync));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
fakeFolder.execUntilFinished();
// We use string matching for paths in the implementation,
// an error should affect only parents and not every path that starts with the problem path.
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus(""), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A"), SyncFileStatus(SyncFileStatus::StatusWarning));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a1"), SyncFileStatus(SyncFileStatus::StatusError));
QCOMPARE(fakeFolder.syncEngine().syncFileStatusTracker().fileStatus("A/a"), SyncFileStatus(SyncFileStatus::StatusUpToDate));
}
void sharedStatus() {
SyncFileStatus sharedUpToDateStatus(SyncFileStatus::StatusUpToDate);
sharedUpToDateStatus.setSharedWithMe(true);
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.remoteModifier().insert("S/s0");
fakeFolder.remoteModifier().appendByte("S/s1");
StatusPushSpy statusSpy(fakeFolder.syncEngine());
fakeFolder.scheduleSync();
fakeFolder.execUntilBeforePropagation();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
// We don't care about the shared flag for the sync status,
// Mac and Windows won't show it and we can't know it for new files.
QCOMPARE(statusSpy.statusOf("S").tag(), SyncFileStatus::StatusSync);
QCOMPARE(statusSpy.statusOf("S/s0").tag(), SyncFileStatus::StatusSync);
QCOMPARE(statusSpy.statusOf("S/s1").tag(), SyncFileStatus::StatusSync);
fakeFolder.execUntilFinished();
verifyThatPushMatchesPull(fakeFolder, statusSpy);
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusUpToDate));
QCOMPARE(statusSpy.statusOf("S"), sharedUpToDateStatus);
QEXPECT_FAIL("", "We currently only know if a new file is shared on the second sync, after a PROPFIND.", Continue);
QCOMPARE(statusSpy.statusOf("S/s0"), sharedUpToDateStatus);
QCOMPARE(statusSpy.statusOf("S/s1"), sharedUpToDateStatus);
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
};
QTEST_GUILESS_MAIN(TestSyncFileStatusTracker)
#include "testsyncfilestatustracker.moc"
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="ca" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="ca" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -750,102 +750,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation>(copia de seguretat)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation>(copia de seguretat %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Estat indefinit.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<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="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>S&apos;està preparant per la sincronització.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>S&apos;està sincronitzant.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>La darrera sincronització va ser correcta.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Error de configuració.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Cancel·la usuari.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>La sincronització està en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sync està pausat)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<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="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2543,17 +2543,22 @@ No és aconsellada usar-la.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Autenticat</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Es requereix nova acreditació</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>La vostra sessió ha vençut. Heu d&apos;acreditar-vos de nou per continuar usant el client.</translation>
</message>
@@ -2866,12 +2871,12 @@ No és aconsellada usar-la.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation type="unfinished"/>
</message>
@@ -2986,54 +2991,54 @@ No és aconsellada usar-la.</translation>
<translation>No es pot obrir el diari de sincronització</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>El nom del fitxer conté al menys un caràcter invàlid</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>S&apos;ignora degut al filtre a «Trieu què sincronitzar»</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>No es permet pujar aquest fitxer perquè només és de lectura en el servidor, es restaura</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>No es permet l&apos;eliminació, es restaura</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Fitxers locals i carpeta compartida esborrats.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>No es permet moure&apos;l, l&apos;element es restaura</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>No es permet moure perquè %1 només és de lectura</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>el destí</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>l&apos;origen</translation>
</message>
@@ -3286,7 +3291,7 @@ No és aconsellada usar-la.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Versió %2. Per més informació visiteu &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Per Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz i altres.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;amb llicència GNU General Public License (GPL) versió 2.0&lt;br/&gt;ownCloud i el logo d&apos;ownCloud són marques registrades d&apos;ownCloud, Inc. als Estats Units, altres països, o ambdós.&lt;/p&gt;</translation>
@@ -3500,7 +3505,7 @@ No és aconsellada usar-la.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>
+46 -41
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="cs_CZ" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="cs_CZ" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -752,102 +752,102 @@ Pokračováním v synchronizaci způsobí přepsání všech vašich souborů st
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation> (záloha)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation> (záloha %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Nedefinovaný stav.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>Čeká na spuštění synchronizace.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Příprava na synchronizaci.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Synchronizace probíhá.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>Poslední synchronizace byla úspěšná.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Chyba nastavení.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Zrušení uživatelem.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>Synchronizace pozastavena.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronizace je pozastavena)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Nebyl vybrán platný adresář!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<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="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation>Místní adresář %1 je již použit pro synchronizaci odesílání. Zvolte prosím jiný!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target already contains 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 již obsahuje adresář použitý pro synchronizaci adresáře. Vyberte prosím jiný!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2545,17 +2545,22 @@ Nedoporučuje se jí používat.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - ověření</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation>Ladící zobrazení šifry SSL</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Vyžadováno opětovné ověření</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Vaše sezení vypršelo. Chcete-li pokračovat v práci, musíte se znovu přihlásit.</translation>
</message>
@@ -2868,12 +2873,12 @@ Nedoporučuje se jí používat.</translation>
<translation>Je dostupných pouze %1, pro spuštění je potřeba alespoň %2</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation>Není povoleno, protože nemáte oprávnění vytvořit nadřazený adresář</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation>Není povoleno, protože nemáte oprávnění přidávat soubory do tohoto adresáře</translation>
</message>
@@ -2988,54 +2993,54 @@ Nedoporučuje se jí používat.</translation>
<translation>Nelze otevřít synchronizační žurnál</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Jméno souboru obsahuje aelspoň jeden neplatný znak</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>Ignorováno podle nastavení &quot;vybrat co synchronizovat&quot;</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation>Není povoleno, protože nemáte oprávnění přidávat podadresáře do tohoto adresáře</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>Není povoleno nahrát tento soubor, protože je na serveru uložen pouze pro čtení, obnovuji</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Odstranění není povoleno, obnovuji</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Místní soubory a sdílený adresář byly odstraněny.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Přesun není povolen, položka obnovena</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Přesun není povolen, protože %1 je pouze pro čtení</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>cílové umístění</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>zdroj</translation>
</message>
@@ -3288,7 +3293,7 @@ Nedoporučuje se jí používat.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Verze %2. Pro další informace navštivte &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz a další.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licencováno pod GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud a ownCloud logo jsou registrované obchodní známky ownCloud, Inc. ve Spojených státech, ostatních zemích nebo obojí&lt;/p&gt;</translation>
@@ -3502,7 +3507,7 @@ Nedoporučuje se jí používat.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation>QT_LAYOUT_DIRECTION</translation>
</message>
@@ -3517,7 +3522,7 @@ Nedoporučuje se jí používat.</translation>
<message numerus="yes">
<location filename="../src/libsync/utility.cpp" line="469"/>
<source>%n day(s) ago</source>
<translation><numerusform>před %n dnyëm</numerusform><numerusform>před %n dny</numerusform><numerusform>před %n dny</numerusform></translation>
<translation><numerusform>před %n dnem</numerusform><numerusform>před %n dny</numerusform><numerusform>před %n dny</numerusform></translation>
</message>
<message numerus="yes">
<location filename="../src/libsync/utility.cpp" line="477"/>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="de_DE" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="de_DE" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -751,102 +751,102 @@ Wenn diese Synchronisation fortgesetzt wird, werden Dateien eventuell von älter
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation>(Sicherung)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation>(Sicherung %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Undefinierter Zustand.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>Wartet auf Beginn der Synchronistation</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Synchronisation wird vorbereitet.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Synchronisation läuft.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>Die letzte Synchronisation war erfolgreich.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Installationsfehler.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Benutzer-Abbruch</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>Synchronisation wurde angehalten.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronisation ist pausiert)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Kein gültige Ordner gewählt!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<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="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation>Der lokale Ordner %1 wird bereits als Synchronisationsordner benutzt. Bitte wählen Sie einen anderen!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target already contains 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 beinhaltet schon einen Ordner, der in einer anderen Synchronisation liegt. Bitte wählen Sie einen anderen lokalen Ordner aus!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2543,17 +2543,22 @@ Es ist nicht ratsam, diese zu benutzen.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Authentifikation</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation>Debug-Ansicht der SSL-Chiffren</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Erneute Authentifizierung erforderlich</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Ihre Sitzung ist abgelaufen. Sie müssen sich zur weiteren Nutzung des Clients neu Anmelden.</translation>
</message>
@@ -2866,12 +2871,12 @@ Es ist nicht ratsam, diese zu benutzen.</translation>
<translation>Nur %1 sind verfügbar. Zum Beginnen werden mindestens %2 benötigt.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation>Nicht erlaubt, da Sie keine Rechte zur Erstellung von Unterordnern haben</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation>Nicht erlaubt, da Sie keine Rechte zum Hinzufügen von Dateien in diesen Ordner haben</translation>
</message>
@@ -2986,54 +2991,54 @@ Es ist nicht ratsam, diese zu benutzen.</translation>
<translation>Synchronisationsbericht kann nicht geöffnet werden</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Der Dateiname enthält mindestens ein ungültiges Zeichen</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>Aufgrund der »Zu synchronisierende Elemente auswählen«-Sperrliste ignoriert</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation>Nicht erlaubt, da Sie keine Rechte zur Erstellung von Unterordnern haben</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>Das Hochladen dieser Datei ist nicht erlaubt, da die Datei auf dem Server schreibgeschützt ist, Wiederherstellung</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Löschen nicht erlaubt, Wiederherstellung</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Lokale Dateien und Freigabeordner wurden entfernt.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Verschieben nicht erlaubt, Element wiederhergestellt</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Verschieben nicht erlaubt, da %1 schreibgeschützt ist</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>Das Ziel</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>Die Quelle</translation>
</message>
@@ -3286,7 +3291,7 @@ Es ist nicht ratsam, diese zu benutzen.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Version %2. Weitere Informationen unter &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Von Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz und anderen.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Lizensiert unter den Bedingungen der GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud und das ownCloud Logo sind eingetragene Warenzeichen der ownCloud Inc. in den USA, anderen Ländern, oder beidem.&lt;/p&gt;</translation>
@@ -3500,7 +3505,7 @@ Es ist nicht ratsam, diese zu benutzen.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation>QT_LAYOUT_DIRECTION</translation>
</message>
+57 -52
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="el" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="el" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -68,12 +68,12 @@
<message>
<location filename="../src/gui/notificationwidget.ui" line="56"/>
<source>Lorem ipsum dolor sit amet</source>
<translation type="unfinished"/>
<translation>Ξεσκεπάζω την ψυχοφθόρα βδελυγμία</translation>
</message>
<message>
<location filename="../src/gui/notificationwidget.ui" line="69"/>
<source>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod temporm </source>
<translation type="unfinished"/>
<translation>Ξεσκεπάζω την ψυχοφθόρα βδελυγμία</translation>
</message>
<message>
<location filename="../src/gui/notificationwidget.ui" line="89"/>
@@ -193,7 +193,7 @@
<message>
<location filename="../src/gui/accountsettings.cpp" line="527"/>
<source>The server version %1 is old and unsupported! Proceed at your own risk.</source>
<translation type="unfinished"/>
<translation>Η έκδοση του διακομιστή %1 είναι παλιά και δεν υποστηρίζεται! Προχωρείστε με δική σας ευθύνη.</translation>
</message>
<message>
<location filename="../src/gui/accountsettings.cpp" line="529"/>
@@ -330,12 +330,12 @@
<message>
<location filename="../src/gui/activityitemdelegate.cpp" line="145"/>
<source>%1 on %2</source>
<translation type="unfinished"/>
<translation>%1 σε %2</translation>
</message>
<message>
<location filename="../src/gui/activityitemdelegate.cpp" line="147"/>
<source>%1 on %2 (disconnected)</source>
<translation type="unfinished"/>
<translation>%1 σε %2 (αποσυνδεδεμένο)</translation>
</message>
</context>
<context>
@@ -354,7 +354,7 @@
<message>
<location filename="../src/gui/activitywidget.cpp" line="530"/>
<source>List of ignored or erroneous files</source>
<translation type="unfinished"/>
<translation>Κατάλογος αρχείων που αγνοούνται ή περιέχουν σφάλματα</translation>
</message>
<message>
<location filename="../src/gui/activitywidget.cpp" line="534"/>
@@ -375,22 +375,22 @@
<location filename="../src/gui/activitywidget.cpp" line="580"/>
<source>Not Synced (%1)</source>
<extracomment>%1 is the number of not synced files.</extracomment>
<translation type="unfinished"/>
<translation>Δεν είναι συγχρονισμένα (%1)</translation>
</message>
<message>
<location filename="../src/gui/activitywidget.cpp" line="596"/>
<source>The server activity list has been copied to the clipboard.</source>
<translation type="unfinished"/>
<translation>Ο κατάλογος δραστηριοτήτων του διακομιστή έχει αντιγραφθεί στο Πρόχειρο</translation>
</message>
<message>
<location filename="../src/gui/activitywidget.cpp" line="600"/>
<source>The sync activity list has been copied to the clipboard.</source>
<translation type="unfinished"/>
<translation>Ο κατάλογος της δραστηριότητας συγχρονισμού έχει αντιγραφθεί στο Πρόχειρο</translation>
</message>
<message>
<location filename="../src/gui/activitywidget.cpp" line="603"/>
<source>The list of unsynched items has been copied to the clipboard.</source>
<translation type="unfinished"/>
<translation>Ο κατάλογος των μη-συγχρονισμένων αρχείων έχει αντιγραφθεί στο Πρόχειρο</translation>
</message>
<message>
<location filename="../src/gui/activitywidget.cpp" line="608"/>
@@ -430,12 +430,12 @@
<message>
<location filename="../src/gui/activitywidget.cpp" line="139"/>
<source>Action Required: Notifications</source>
<translation type="unfinished"/>
<translation>Απαιτείται ενέργεια: Ειδοποιήσεις</translation>
</message>
<message>
<location filename="../src/gui/activitywidget.cpp" line="144"/>
<source>&lt;br/&gt;Account %1 does not have activities enabled.</source>
<translation type="unfinished"/>
<translation>&lt;br/&gt;Ο λογαριασμός %1 δεν έχει ενεργοποιήσει τις δραστηριότητες.</translation>
</message>
<message numerus="yes">
<location filename="../src/gui/activitywidget.cpp" line="351"/>
@@ -750,102 +750,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<translation>Βρέθηκε ένα παλαιότερο αρχείο συγχρονισμού &apos;%1&apos;, αλλά δεν μπόρεσε να αφαιρεθεί. Παρακαλώ βεβαιωθείτε ότι καμμία εφαρμογή δεν το χρησιμοποιεί αυτή τη στιγμή.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation>(αντίγραφο ασφαλείας)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation>(αντίγραοφ ασφαλέιας %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Απροσδιόριστη Κατάσταση.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>Αναμονή έναρξης συγχρονισμού.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Προετοιμασία για συγχρονισμό.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Ο συγχρονισμός εκτελείται.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>Ο τελευταίος συγχρονισμός ήταν επιτυχής.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>Ο τελευταίος συγχρονισμός ήταν επιτυχής, αλλά υπήρχαν προειδοποιήσεις σε συγκεκριμένα αρχεία.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Σφάλμα Ρύθμισης.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Ματαίωση από Χρήστη.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>Παύση συγχρονισμού.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Παύση συγχρονισμού)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Δεν επιλέχθηκε έγκυρος φάκελος!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<source>The selected path is not a folder!</source>
<translation>Η επιλεγμένη διαδρομή δεν είναι φάκελος!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<source>You have no permission to write to the selected folder!</source>
<translation>Δεν έχετε δικαιώματα εγγραφής στον επιλεγμένο φάκελο!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation>Ο τοπικός φάκελος %1 χρησιμοποιείται ήδη σε μια σύνδεση συγχρονισμού φακέλου. Παρακαλώ επιλέξτε άλλον!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2543,17 +2543,22 @@ It is not advisable to use it.</source>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Πιστοποίηση</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Απαιτείται επανάληψη πιστοποίησης</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Η συνεδρία σας έληξε. Πρέπει να εισέλθετε ξανά για να συνεχίσετε να χρησιμοποιείτε το πρόγραμμα.</translation>
</message>
@@ -2866,12 +2871,12 @@ It is not advisable to use it.</source>
<translation>Μόνο %1 είναι διαθέσιμα, απαιτούνται τουλάχιστον %2 για την εκκίνηση</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation>Δεν επιτρέπεται επειδή δεν έχετε δικαιώματα να προσθέσετε γονικό κατάλογο</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation>Δεν επιτρέπεται επειδή δεν έχετε δικαιώματα να προσθέσετε αρχεία σε αυτόν τον φάκελο</translation>
</message>
@@ -2986,54 +2991,54 @@ It is not advisable to use it.</source>
<translation>Αδυναμία ανοίγματος του αρχείου συγχρονισμού</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Το όνομα αρχείου περιέχει έναν τουλάχιστον μη έγκυρο χαρακτήρα</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>Αγνοήθηκε εξαιτίας της μαύρης λίστας &quot;διάλεξε τι να συγχρονιστεί&quot;</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation>Δεν επιτρέπεται επειδή δεν έχετε δικαιώματα να προσθέσετε υποφακέλους σε αυτό τον φάκελο</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>Δεν επιτρέπεται να μεταφορτώσετε αυτό το αρχείο επειδή είναι μόνο για ανάγνωση στο διακομιστή, αποκατάσταση σε εξέλιξη</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Δεν επιτρέπεται η αφαίρεση, αποκατάσταση σε εξέλιξη</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Οι τοπικοί φάκελοι και ο φάκελος κοινής χρήσης αφαιρέθηκαν.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Η μετακίνηση δεν επιτρέπεται, το αντικείμενο αποκαταστάθηκε</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Η μετακίνηση δεν επιτρέπεται επειδή το %1 είναι μόνο για ανάγνωση</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>ο προορισμός</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>η προέλευση</translation>
</message>
@@ -3286,7 +3291,7 @@ It is not advisable to use it.</source>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Έκδοση %2. Για περισσότερες πληροφορίες επισκεφθείτε &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Των Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz και άλλων.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Πνευματικά δικαιώματα ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Αδειοδότηση υπό την GNU General Public License (GPL) Έκδοση 2.0&lt;br/&gt;το ownCloud και το λογότυπο ownCloud είναι σήματα κατατεθέντα της ownCloud, Inc. στις Η.Π.Α., σε άλλες χώρες ή και στα δύο&lt;/p&gt;</translation>
@@ -3500,7 +3505,7 @@ It is not advisable to use it.</source>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>
+45 -40
Ver Arquivo
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="en_US">
<TS version="2.1" language="en_US">
<context>
<name>FileSystem</name>
<message>
@@ -776,102 +776,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2564,17 +2564,22 @@ It is not advisable to use it.</source>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation type="unfinished"></translation>
</message>
@@ -2885,12 +2890,12 @@ It is not advisable to use it.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation type="unfinished"></translation>
</message>
@@ -3005,54 +3010,54 @@ It is not advisable to use it.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation type="unfinished"></translation>
</message>
@@ -3305,7 +3310,7 @@ It is not advisable to use it.</source>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
@@ -3519,7 +3524,7 @@ It is not advisable to use it.</source>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"></translation>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="es" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="es" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -752,102 +752,102 @@ Continuar con la sincronización hará que todos los archivos sean sobreescritos
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation>(copia de seguridad)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation>(copia de seguridad %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Estado no definido.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>Esperando para comenzar la sincronización.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Preparándose para sincronizar.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Sincronización en funcionamiento.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<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="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Error de configuración.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Interrumpido por el usuario.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>La sincronización está en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sincronización en pausa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>¡La carpeta seleccionada no es válida!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<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="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation>El directorio local %1 ya se usa en una conexión de sincronización de directorios. Por favor, elija otro.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target already contains 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 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2544,17 +2544,22 @@ No se recomienda usarla.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Autenticar</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation>Vista depuradador Chipher SSL</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Debe volver a autenticarse</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Su sesión ha caducado. Necesita volver a iniciarla para continuar usando el cliente.</translation>
</message>
@@ -2867,12 +2872,12 @@ No se recomienda usarla.</translation>
<translation>Solo %1 disponible, se necesita por lo menos %2 para comenzar</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation>No permitido porque no tienes permiso para añadir un directorio padre</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation>No permitido porque no tienes permiso para añadir archivos a ese directorio</translation>
</message>
@@ -2987,54 +2992,54 @@ No se recomienda usarla.</translation>
<translation>No es posible abrir el diario de sincronización</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Nombre de archivo contiene al menos un caracter no válido</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>Ignorado porque se encuentra en la lista negra de &quot;elija qué va a sincronizar&quot;</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation>No permitido porque no tienes permiso para añadir subdirectorios a ese directorio</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>No está permitido subir este archivo porque es de solo lectura en el servidor, restaurando.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>No está permitido borrar, restaurando.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Se han eliminado los archivos locales y la carpeta compartida.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>No está permitido mover, elemento restaurado.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>No está permitido mover, porque %1 es de sólo lectura.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>destino</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>origen</translation>
</message>
@@ -3287,7 +3292,7 @@ No se recomienda usarla.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Versión %2. Para más información, visite &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Creado por Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz y otros.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Está bajo la Licencia General Pública (GPL, en inglés) GNU Versión 2.0&lt;br/&gt;ownCloud y el logo de ownCloud son marcas registradas de ownCloud, Inc. en los Estados Unidos, otros países, o ambos.&lt;/p&gt;</translation>
@@ -3501,7 +3506,7 @@ No se recomienda usarla.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation>QT_LAYOUT_DIRECTION</translation>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="es_AR" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="es_AR" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -747,102 +747,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Estado no definido.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Preparando la sincronización.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Sincronización en funcionamiento.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>La última sincronización fue exitosa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Error de configuración.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Interrumpir.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>La sincronización está en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sincronización en pausa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2532,17 +2532,22 @@ It is not advisable to use it.</source>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Autenticarse</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation type="unfinished"/>
</message>
@@ -2853,12 +2858,12 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation type="unfinished"/>
</message>
@@ -2973,54 +2978,54 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation type="unfinished"/>
</message>
@@ -3273,7 +3278,7 @@ It is not advisable to use it.</source>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation type="unfinished"/>
@@ -3488,7 +3493,7 @@ It is not advisable to use it.</source>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="et_EE" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="et_EE" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -747,102 +747,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation>(varukoopia)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation> (varukoopia %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Määramata staatus.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>Oodatakse sünkroonimise alustamist.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Valmistun sünkroniseerima.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Sünkroniseerimine on käimas.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>Viimane sünkroniseerimine oli edukas.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Seadistamise viga.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Kasutaja tühistamine.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>Sünkroniseerimine on peatatud.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sünkroniseerimine on peatatud)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Sobilikku kausta pole valitud!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<source>The selected path is not a folder!</source>
<translation>Valitud asukoht pole kaust!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2533,17 +2533,22 @@ Selle kasutamine pole soovitatav.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - autentimine</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Vajalik on uuesti autentimine</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Sinu sessioon on aegunud. Sa pead kliendi kasutamiseks uuesti sisse logima.</translation>
</message>
@@ -2856,12 +2861,12 @@ Selle kasutamine pole soovitatav.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation type="unfinished"/>
</message>
@@ -2976,54 +2981,54 @@ Selle kasutamine pole soovitatav.</translation>
<translation>Ei suuda avada sünkroniseeringu zurnaali</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Faili nimesonvähemalt üks keelatud märk</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>&quot;Vali, mida sünkroniseerida&quot; musta nimekirja tõttu vahele jäetud</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>Pole lubatud üles laadida, kuna tegemist on ainult-loetava serveriga, taastan</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Eemaldamine pole lubatud, taastan</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Kohalikud failid ja jagatud kaustad eemaldatud.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Liigutamine pole lubatud, üksus taastatud</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Liigutamien pole võimalik kuna %1 on ainult lugemiseks</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>sihtkoht</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>allikas</translation>
</message>
@@ -3276,7 +3281,7 @@ Selle kasutamine pole soovitatav.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation type="unfinished"/>
@@ -3490,7 +3495,7 @@ Selle kasutamine pole soovitatav.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="eu" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="eu" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -747,102 +747,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Definitu gabeko egoera.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>Itxoiten sinkronizazioa hasteko.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Sinkronizazioa prestatzen.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Sinkronizazioa martxan da.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>Azkeneko sinkronizazioa ongi burutu zen.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Konfigurazio errorea.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Erabiltzaileak bertan behera utzi.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>Sinkronizazioa pausatuta dago.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Sinkronizazioa pausatuta dago)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Ez da karpeta egokirik hautatu!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<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="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2539,17 +2539,22 @@ Ez da gomendagarria erabltzea.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Berautentikatzea beharrezkoa</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation type="unfinished"/>
</message>
@@ -2860,12 +2865,12 @@ Ez da gomendagarria erabltzea.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation type="unfinished"/>
</message>
@@ -2980,54 +2985,54 @@ Ez da gomendagarria erabltzea.</translation>
<translation>Ezin da sinkronizazio egunerokoa ireki</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Fitxategi izenak behintzat baliogabeko karaktere bat du</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Ezabatzeko baimenik gabe, berrezartzen</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Mugitzea ez dago baimenduta, elementua berrezarri da</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Mugitzea ez dago baimenduta %1 irakurtzeko bakarrik delako</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>helburua</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>jatorria</translation>
</message>
@@ -3280,7 +3285,7 @@ Ez da gomendagarria erabltzea.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;%2 Bertsioa. Informazio gehiago eskuratzeko ikusi &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Egileak: Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz eta bestea batzuk.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;GNU General Public License (GPL) 2.0 bertsioaren lizentziapean banatuta.&lt;br/&gt;ownCloud eta ownCloud-en Logoa ownCloud, Inc. enpresaren marka erregistratuak dira Estatu Batuetan, beste herrialdeetan edo bietan.&lt;/p&gt;</translation>
@@ -3494,7 +3499,7 @@ Ez da gomendagarria erabltzea.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="fa" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="fa" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -747,102 +747,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation> (backup)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation> (پشتیبان %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>موقعیت تعریف نشده</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>آماده سازی برای همگام سازی کردن.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>همگام سازی در حال اجراست</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>آخرین همگام سازی موفقیت آمیز بود</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>خطا در پیکر بندی.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>خارج کردن کاربر.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>همگام سازی فعلا متوقف شده است</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (همگامسازی موقتا متوقف شده است)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>هیچ پوشهی معتبری انتخاب نشده است!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<source>You have no permission to write to the selected folder!</source>
<translation>شما اجازه نوشتن در پوشه های انتخاب شده را ندارید!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2532,17 +2532,22 @@ It is not advisable to use it.</source>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation type="unfinished"/>
</message>
@@ -2853,12 +2858,12 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation type="unfinished"/>
</message>
@@ -2973,54 +2978,54 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>نام فایل دارای حداقل یک کاراکتر نامعتبر است</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation>با توجه به عدم اجازهی شما به ایجاد زیرپوشه به پوشه مجاز نیست</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>آپلود این فایل با توجه به فقط-خواندنی بودن آن در سرور مجاز نیست، در حال بازگرداندن</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>حذف مجاز نیست، در حال بازگردادن</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>فایلهای محلی و پوشهی اشتراک حذف شد.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>انتقال مجاز نیست، مورد بازگردانده شد</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>مقصد</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>مبدا</translation>
</message>
@@ -3273,7 +3278,7 @@ It is not advisable to use it.</source>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation type="unfinished"/>
@@ -3487,7 +3492,7 @@ It is not advisable to use it.</source>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="fi_FI" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="fi_FI" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -748,102 +748,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation> (varmuuskopio)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation> (varmuuskopio %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Määrittelemätön tila.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>Odotetaan synkronoinnin aloitusta.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Valmistellaan synkronointia.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Synkronointi on meneillään.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>Viimeisin synkronointi suoritettiin onnistuneesti.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Asetusvirhe.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>Synkronointi on keskeytetty.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synkronointi on keskeytetty)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Kelvollista kansiota ei ole valittu!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<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="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation>Paikallinen kansio %1 on jo käytössä kansion synkronointiyhteydessä. Valitse toinen kansio!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2540,17 +2540,22 @@ Osoitteen käyttäminen ei ole suositeltavaa.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Tunnistaudu</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Tunnistaudu uudelleen</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Istunto on vanhentunut. Kirjaudu uudelleen jatkaaksesi sovelluksen käyttämistä.</translation>
</message>
@@ -2863,12 +2868,12 @@ Osoitteen käyttäminen ei ole suositeltavaa.</translation>
<translation>Vain %1 on käytettävissä, käynnistymiseen tarvitaan %2</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation>Ei sallittu, koska käyttöoikeutesi eivät riitä ylätason kansion lisäämiseen</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation>Ei sallittu, koska käyttöoikeutesi eivät riitä tiedostojen lisäämiseen kyseiseen kansioon</translation>
</message>
@@ -2983,54 +2988,54 @@ Osoitteen käyttäminen ei ole suositeltavaa.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Tiedoston nimi sisältää ainakin yhden virheellisen merkin</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation>Ei sallittu, koska oikeutesi eivät riitä alikansioiden lisäämiseen kyseiseen kansioon</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Poistaminen ei ole sallittua, palautetaan</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Paikalliset tiedostot ja jakokansio poistettu.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Siirtäminen ei ole sallittua, kohde palautettu</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Siirto ei ole sallittu, koska %1 on &quot;vain luku&quot;-tilassa</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>kohde</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>lähde</translation>
</message>
@@ -3283,7 +3288,7 @@ Osoitteen käyttäminen ei ole suositeltavaa.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Versio %2. Lisätietoja osoitteessa &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Tehnyt Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz ja muut.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Tekijänoikeus ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Lisensoitu GNU General Public License (GPL), versio 2.0 -lisenssillä&lt;br/&gt;ownCloud ja ownCloudin logo ovat ownCloud, Incin rekisteröimiä tavaramerkkejä Yhdysvalloissa ja muissa maissa.&lt;/p&gt;</translation>
@@ -3497,7 +3502,7 @@ Osoitteen käyttäminen ei ole suositeltavaa.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="fr" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="fr" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -752,102 +752,102 @@ Continuer la synchronisation comme d&apos;habitude fera en sorte que tous les fi
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation>(sauvegarde)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation>(sauvegarde %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Statut indéfini.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation>En attente de synchronisation.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Préparation de la synchronisation.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>La synchronisation est en cours.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>Dernière synchronisation effectuée avec succès</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation>La dernière synchronisation s&apos;est achevée avec succès mais avec des avertissement à propos de certains fichiers.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Erreur d&apos;installation.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Abandon par l&apos;utilisateur.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>La synchronisation est en pause.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (Synchronisation en pause)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Aucun dossier valable sélectionné !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<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="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation>Le dossier local %1 est déjà utilisé pour une synchronisation de dossiers. Veuillez en choisir un autre !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target already contains 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 contient un dossier déjà utilisé pour une synchronisation de dossier. Veuillez en choisir un autre !</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2545,17 +2545,22 @@ Il est déconseillé de l&apos;utiliser.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Authentifier</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation>Vue de débug Chipher SSL</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>Nouvelle authentification nécessaire</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Votre session a expiré. Vous devez vous connecter à nouveau pour continuer à utiliser le client.</translation>
</message>
@@ -2868,12 +2873,12 @@ Il est déconseillé de l&apos;utiliser.</translation>
<translation>Seulement %1 disponibles, il faut au moins %2 pour démarrer</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation>Non autorisé car vous n&apos;avez pas la permission d&apos;ajouter un dossier parent</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation>Non autorisé car vous n&apos;avez pas la permission d&apos;ajouter des fichiers dans ce dossier</translation>
</message>
@@ -2988,54 +2993,54 @@ Il est déconseillé de l&apos;utiliser.</translation>
<translation>Impossible d&apos;ouvrir le journal de synchronisation</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>Le nom de fichier contient au moins un caractère non valable</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>Ignoré à cause de la liste noire &quot;Choisir le contenu à synchroniser&quot;.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation>Non autorisé car vous n&apos;avez pas la permission d&apos;ajouter des sous-dossiers dans ce dossier</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>Non autorisé à envoyer ce fichier car il est en lecture seule sur le serveur. Restauration</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Non autorisé à supprimer. Restauration</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Fichiers locaux et répertoire de partage supprimés.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Déplacement non autorisé, élément restauré</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Déplacement non autorisé car %1 est en mode lecture seule</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>la destination</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>la source</translation>
</message>
@@ -3288,7 +3293,7 @@ Il est déconseillé de l&apos;utiliser.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Version %2. Pour plus d&apos;informations, consultez &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</translation>
@@ -3502,7 +3507,7 @@ Il est déconseillé de l&apos;utiliser.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation>QT_LAYOUT_DIRECTION</translation>
</message>
+45 -40
Ver Arquivo
@@ -1,4 +1,4 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="gl" version="2.0">
<?xml version="1.0" ?><!DOCTYPE TS><TS language="gl" version="2.1">
<context>
<name>FileSystem</name>
<message>
@@ -748,102 +748,102 @@ Continuing the sync as normal will cause all your files to be overwritten by an
<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="926"/>
<location filename="../src/gui/folderman.cpp" line="927"/>
<source> (backup)</source>
<translation>(copia de seguranza)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="931"/>
<location filename="../src/gui/folderman.cpp" line="932"/>
<source> (backup %1)</source>
<translation>(copia de seguranza %1)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1138"/>
<location filename="../src/gui/folderman.cpp" line="1139"/>
<source>Undefined State.</source>
<translation>Estado sen definir.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1141"/>
<location filename="../src/gui/folderman.cpp" line="1142"/>
<source>Waiting to start syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1144"/>
<location filename="../src/gui/folderman.cpp" line="1145"/>
<source>Preparing for sync.</source>
<translation>Preparando para sincronizar.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1147"/>
<location filename="../src/gui/folderman.cpp" line="1148"/>
<source>Sync is running.</source>
<translation>Estase sincronizando.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1150"/>
<location filename="../src/gui/folderman.cpp" line="1151"/>
<source>Last Sync was successful.</source>
<translation>A última sincronización fíxose correctamente.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1155"/>
<location filename="../src/gui/folderman.cpp" line="1156"/>
<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="1158"/>
<location filename="../src/gui/folderman.cpp" line="1159"/>
<source>Setup Error.</source>
<translation>Erro de configuración.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1161"/>
<location filename="../src/gui/folderman.cpp" line="1162"/>
<source>User Abort.</source>
<translation>Interrompido polo usuario.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1164"/>
<location filename="../src/gui/folderman.cpp" line="1165"/>
<source>Sync is paused.</source>
<translation>Sincronización en pausa.</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1170"/>
<location filename="../src/gui/folderman.cpp" line="1171"/>
<source>%1 (Sync is paused)</source>
<translation>%1 (sincronización en pausa)</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1178"/>
<location filename="../src/gui/folderman.cpp" line="1179"/>
<source>No valid folder selected!</source>
<translation>Non seleccionou ningún cartafol correcto!</translation>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1189"/>
<location filename="../src/gui/folderman.cpp" line="1190"/>
<source>The selected path is not a folder!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1193"/>
<location filename="../src/gui/folderman.cpp" line="1194"/>
<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="1208"/>
<location filename="../src/gui/folderman.cpp" line="1209"/>
<source>The local folder %1 is already used in a folder sync connection. Please pick another one!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/folderman.cpp" line="1213"/>
<location filename="../src/gui/folderman.cpp" line="1214"/>
<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="1220"/>
<location filename="../src/gui/folderman.cpp" line="1221"/>
<source>The local folder %1 is a symbolic link. The link target 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="1227"/>
<location filename="../src/gui/folderman.cpp" line="1228"/>
<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="1233"/>
<location filename="../src/gui/folderman.cpp" line="1234"/>
<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>
@@ -2539,17 +2539,22 @@ Recomendámoslle que non o use.</translation>
<context>
<name>OCC::ShibbolethWebView</name>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="79"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="81"/>
<source>%1 - Authenticate</source>
<translation>%1 - Autenticado</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="91"/>
<source>SSL Chipher Debug View</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Reauthentication required</source>
<translation>É necesario volver autenticarse</translation>
</message>
<message>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="85"/>
<location filename="../src/gui/creds/shibboleth/shibbolethwebview.cpp" line="99"/>
<source>Your session has expired. You need to re-login to continue to use the client.</source>
<translation>Caducou a sesión. É necesario que volva a acceder para seguir usando o cliente. </translation>
</message>
@@ -2862,12 +2867,12 @@ Recomendámoslle que non o use.</translation>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1132"/>
<location filename="../src/libsync/syncengine.cpp" line="1134"/>
<source>Not allowed because you don&apos;t have permission to add parent folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1139"/>
<location filename="../src/libsync/syncengine.cpp" line="1141"/>
<source>Not allowed because you don&apos;t have permission to add files in that folder</source>
<translation type="unfinished"/>
</message>
@@ -2982,54 +2987,54 @@ Recomendámoslle que non o use.</translation>
<translation>Non foi posíbel abrir o rexistro de sincronización</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="887"/>
<location filename="../src/libsync/syncengine.cpp" line="889"/>
<source>File name contains at least one invalid character</source>
<translation>O nome de ficheiro contén algún carácter incorrecto</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1091"/>
<location filename="../src/libsync/syncengine.cpp" line="1098"/>
<location filename="../src/libsync/syncengine.cpp" line="1093"/>
<location filename="../src/libsync/syncengine.cpp" line="1100"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation>Ignorado por mor da lista negra de «escolla que sincronizar»</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1117"/>
<location filename="../src/libsync/syncengine.cpp" line="1119"/>
<source>Not allowed because you don&apos;t have permission to add subfolders to that folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1159"/>
<location filename="../src/libsync/syncengine.cpp" line="1161"/>
<source>Not allowed to upload this file because it is read-only on the server, restoring</source>
<translation>Non está permitido o envío xa que o ficheiro é de lectura no servidor, restaurando</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1176"/>
<location filename="../src/libsync/syncengine.cpp" line="1196"/>
<location filename="../src/libsync/syncengine.cpp" line="1178"/>
<location filename="../src/libsync/syncengine.cpp" line="1198"/>
<source>Not allowed to remove, restoring</source>
<translation>Non está permitido retiralo, restaurando</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1209"/>
<location filename="../src/libsync/syncengine.cpp" line="1211"/>
<source>Local files and share folder removed.</source>
<translation>Retirados os ficheiros locais e o cartafol compartido.</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1265"/>
<location filename="../src/libsync/syncengine.cpp" line="1267"/>
<source>Move not allowed, item restored</source>
<translation>Nos está permitido movelo, elemento restaurado</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1276"/>
<location filename="../src/libsync/syncengine.cpp" line="1278"/>
<source>Move not allowed because %1 is read-only</source>
<translation>Bon está permitido movelo xa que %1 é de lectura</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the destination</source>
<translation>o destino</translation>
</message>
<message>
<location filename="../src/libsync/syncengine.cpp" line="1277"/>
<location filename="../src/libsync/syncengine.cpp" line="1279"/>
<source>the source</source>
<translation>a orixe</translation>
</message>
@@ -3282,7 +3287,7 @@ Recomendámoslle que non o use.</translation>
</context>
<context>
<name>OCC::ownCloudTheme</name>
<message utf8="true">
<message>
<location filename="../src/libsync/owncloudtheme.cpp" line="47"/>
<source>&lt;p&gt;Version %2. For more information visit &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licensed under the GNU General Public License (GPL) Version 2.0&lt;br/&gt;ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.&lt;/p&gt;</source>
<translation>&lt;p&gt;Versión %2. Para obter máis información visite &lt;a href=&quot;%3&quot;&gt;%4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Por Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz e outros.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;Copyright ownCloud, Inc.&lt;/p&gt;&lt;p&gt;Licenciado baixo a Licenza Publica Xeral (GPL) GNU Version 2.0&lt;br/&gt;ownCloud e o logotipo ownCloud son marcas rexistradas da ownCloud, Inc. nos EE.UU de Norte América, noutros países ou en ambos.&lt;/p&gt;</translation>
@@ -3496,7 +3501,7 @@ Recomendámoslle que non o use.</translation>
<context>
<name>QApplication</name>
<message>
<location filename="../src/gui/application.cpp" line="593"/>
<location filename="../src/gui/application.cpp" line="599"/>
<source>QT_LAYOUT_DIRECTION</source>
<translation type="unfinished"/>
</message>

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais