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

Compare commits

...

153 Commits

Author SHA1 Message Date
Klaas Freitag
131747ea4b Bumped version to 1.7.1 beta1 2014-12-09 15:25:37 +01:00
Jenkins for ownCloud
a7f1f886d3 [tx-robot] updated from transifex 2014-12-09 01:25:28 -05:00
Klaas Freitag
72a90199db Wizard: Removed superflous text, as it is already in the header.
This fixes mirall#2358
2014-12-08 11:12:15 +01:00
Jenkins for ownCloud
e69702799f [tx-robot] updated from transifex 2014-12-08 01:25:21 -05:00
Jenkins for ownCloud
118aead9b9 [tx-robot] updated from transifex 2014-12-07 01:25:25 -05:00
Klaas Freitag
49bb861045 Removed useless debug output 2014-12-06 12:37:53 +01:00
Klaas Freitag
1d6661e7e4 Fix the number of displayed items in progress display for removes.
This fixes mirall#1132

A variable that counts the affected items of the propagator operation
done on a item was added to SyncFileItem. Usually that is 1 because
most operations affect only the item itself. But for removes, the
number can be higher for directories (one remove removes a whole tree).

Some rearrangements were needed.
2014-12-06 12:31:45 +01:00
Jenkins for ownCloud
a43173fa90 [tx-robot] updated from transifex 2014-12-06 01:25:23 -05:00
Jenkins for ownCloud
d2a24b5186 [tx-robot] updated from transifex 2014-12-05 01:25:29 -05:00
Christian Kamm
40f44c2389 DB: Delete corrupt database. #2547
* Also use readonly DB access for SocketAPI.
2014-12-04 15:35:55 +01:00
Olivier Goffart
441b5bd1dc Setup Wizard: remove all folder definition before starting a new sync
Issue #1989
2014-12-04 15:18:27 +01:00
Christian Kamm
dc2f0d59cb FolderWizard: Clean up naming of 'add folder' button. #2371 2014-12-04 10:47:26 +01:00
Christian Kamm
4dcfacf2d5 Fix compile. :/ 2014-12-04 09:59:24 +01:00
Christian Kamm
b7485106ef NetworkJobs: Set timeout to 5 minutes everywhere. 2014-12-04 09:54:17 +01:00
Christian Kamm
f82893496b Fix typo. 2014-12-04 09:54:15 +01:00
Christian Kamm
c418e58f88 Etag job scheduling: Silence warnings, make prettier. 2014-12-04 09:52:13 +01:00
Jenkins for ownCloud
3020dc75ab [tx-robot] updated from transifex 2014-12-04 01:25:22 -05:00
Klaas Freitag
9ea359de52 GUI: Check if there are sync folders configured and how proper msg.
This fixes #2264
2014-12-03 17:11:42 +01:00
Klaas Freitag
c5daf7d1b6 Mac installer: Make the installer background brandable for MacOSX. 2014-12-03 14:37:59 +01:00
Christian Kamm
b7d7f424c5 FolderMan: only touch _currentSyncFolder when done #2407
Also simplity terminateSyncProcess() to always terminate the
*current* sync run. Only one can be running at a time anyway.
2014-12-03 13:46:37 +01:00
Daniel Molkentin
e1fa6f1a0d fix_frameworks is no longer required
This is taken care of by macdeployqt.py, which is
run during "make install"
2014-12-03 13:41:12 +01:00
Olivier Goffart
a23e0fef8d Update binary submodule 2014-12-03 11:18:01 +01:00
Olivier Goffart
0fd0b08c09 Windows shell integration: Always release the lock before calling win32 API
May help for 2515
2014-12-03 09:11:38 +01:00
Jenkins for ownCloud
ce1690b450 [tx-robot] updated from transifex 2014-12-03 01:25:27 -05:00
Markus Goetz
46bd473664 Folders: Move ETag check scheduling to FolderMan
Only 1 check per time is able to run now.
For #2553
Might improve #2479 #2485 #2534
2014-12-02 22:32:54 +01:00
Olivier Goffart
8fbb55a0c8 Wizard: Fix escaping of error message.
An url can contains % signs, so if it does, the errors formating was wrong
because of the use of QString::args

Also, the error is in html format, and we need to let the message box know
that, otherwise we will just see <br/>
2014-12-02 10:22:46 +01:00
Olivier Goffart
f046a7e7fe Wizard: Attempts to really close the database when starting the backup
Still for issue #1989
2014-12-02 10:22:46 +01:00
Olivier Goffart
b154e1baa1 Nautilus shell integration: Use fallback when XDG_RUNTIME_DIR is not defined
Same fallback as in Qt5

Task #2477
2014-12-01 12:06:09 +01:00
Jenkins for ownCloud
119a9983a9 [tx-robot] updated from transifex 2014-11-30 01:25:22 -05:00
Jenkins for ownCloud
2e06b4be66 [tx-robot] updated from transifex 2014-11-29 01:25:23 -05:00
Jenkins for ownCloud
0ec2e71f58 [tx-robot] updated from transifex 2014-11-28 01:25:25 -05:00
Olivier Goffart
2ed2ef3b28 Propagator QNAM: Fix resuming
We forgot to account the fact that we could have been resuming when
comparing the size of the Content-lenght to the size of the temporary file
2014-11-27 14:50:49 +01:00
Olivier Goffart
e7e91b6931 Revert "Folder: Don't blindly trigger sync on first EtagJob result"
We need to do a sync even if the etag was empty because we do not know
if this is because the etag really changed or because it was new.

Also, some part of the code rely on this fact to schedule a sync.

The fact that there is two sync with 30 sec at the beginning is not
a big problem, because we also need to do the sync the put the directory
etag in the db.

This reverts commit 1c001ee138.
2014-11-27 12:50:36 +01:00
Olivier Goffart
1f9d02e7fa Shibboleth: Fix our implemtnation of CookieJar::deleteCookie
It was deleting too many cookies.
That function is virtual in Qt5 and is used when adding cookie.
But some Shibboleth have several cookies with the same name, and we need to keep them.

Our implementaiton was meant to delete all the shiboleth cookies when we want to log out
2014-11-27 12:26:59 +01:00
Jenkins for ownCloud
2ee70db7cd [tx-robot] updated from transifex 2014-11-26 01:25:24 -05:00
Klaas Freitag
3e34d000f2 Propagator: Add the chunk size to PUT requests. 2014-11-25 10:21:33 +01:00
Jenkins for ownCloud
7f520a6f28 [tx-robot] updated from transifex 2014-11-24 01:25:22 -05:00
Jenkins for ownCloud
23f72ecf7b [tx-robot] updated from transifex 2014-11-23 01:25:22 -05:00
Jenkins for ownCloud
8c57e7621b [tx-robot] updated from transifex 2014-11-22 01:25:37 -05:00
Markus Goetz
1c001ee138 Folder: Don't blindly trigger sync on first EtagJob result
For #2352
2014-11-21 16:47:15 +01:00
Markus Goetz
fab82107bb OS X: Don't use hardcoded name in packages file 2014-11-21 16:34:30 +01:00
Olivier Goffart
41568c885d Propagator: only check the content-lenght if it is there
If content-lenght is 0, don't chack it is the size we recieved.
It can be zero when using HTTP chunk encoding.

Also do not remove the temporary file so it can be re-used on the next sync
and ask for a new sync immediatly to re-do the sync.

Fixup the fix to task #2528
2014-11-21 11:03:14 +01:00
Jenkins for ownCloud
dba2efe367 [tx-robot] updated from transifex 2014-11-21 02:52:45 -05:00
Christian Kamm
e3b07f569a FolderWatcherTest: Use Utility::usleep. 2014-11-21 08:21:36 +01:00
Klaas Freitag
65a307970b Propagator: Compare the actual file size with the request content length
The values must match. Otherwise the request did succeed, but the file
was not downloaded completely.

This fixes https://github.com/owncloud/mirall/issues/2528
2014-11-20 18:49:34 +01:00
Christian Kamm
3e3ca14b4c Print ssl library version only on Qt >=5.0.0. 2014-11-20 13:46:44 +01:00
Christian Kamm
d4e0941c27 Windows filewatcher: switch to ReadDirectoryChangesW.
Based on danimo's #2454 fix for #2455 and related to #2297.
2014-11-20 12:36:17 +01:00
Christian Kamm
9dc57359b9 csync db files: Hide after some commit/transactions. #2461
The shm and wal files are only created later.
2014-11-20 12:30:04 +01:00
Jenkins for ownCloud
06b31d7cf0 [tx-robot] updated from transifex 2014-11-20 01:25:20 -05:00
Christian Kamm
421a8cc6b7 Windows: Make unit tests compile. 2014-11-19 14:18:37 +01:00
Christian Kamm
3a448fda91 Windows mingw32: Fix finding of windres binary. 2014-11-19 14:16:56 +01:00
Markus Goetz
e890c4ae1b OS X: Move previous fix to proper location 2014-11-17 18:30:32 +01:00
Markus Goetz
7ada625161 OS X: Fix packages file 2014-11-17 17:48:29 +01:00
Olivier Goffart
7d8dd54b19 Merge pull request #2504 from owncloud/revert-2454-fswatcher_readdirectorychanges_port
Revert "WiP: switch to ReadDirectoryChangesW"
2014-11-17 11:11:39 +01:00
Olivier Goffart
0b275c4933 Revert "WiP: switch to ReadDirectoryChangesW" 2014-11-17 11:11:13 +01:00
Olivier Goffart
e529bbed90 Merge pull request #2454 from owncloud/fswatcher_readdirectorychanges_port
switch to ReadDirectoryChangesW
2014-11-17 09:43:29 +01:00
Jenkins for ownCloud
39e97779ec [tx-robot] updated from transifex 2014-11-17 01:25:22 -05:00
Jenkins for ownCloud
629d46ca25 [tx-robot] updated from transifex 2014-11-16 01:25:22 -05:00
Daniel Molkentin
c5a35ad56f Merge pull request #2499 from owncloud/revert-2412-nsis_shortcuts_all_users
Revert "Install shortcuts for all users"
2014-11-15 21:05:05 +01:00
Daniel Molkentin
1e94161ec1 Revert "Install shortcuts for all users" 2014-11-15 21:04:33 +01:00
Daniel Molkentin
6f78ff200c Merge pull request #2412 from owncloud/nsis_shortcuts_all_users
Install shortcuts for all users
2014-11-15 20:09:29 +01:00
Daniel Molkentin
02e96484a8 Install shortcuts for all users 2014-11-15 17:07:39 +01:00
Jenkins for ownCloud
67b0e4dd15 [tx-robot] updated from transifex 2014-11-15 01:25:23 -05:00
Markus Goetz
5b7ec19778 SyncEngine: Also output the neon version 2014-11-14 15:02:09 +01:00
Jenkins for ownCloud
e71c617bfd [tx-robot] updated from transifex 2014-11-14 01:25:20 -05:00
Jenkins for ownCloud
f1432992d3 [tx-robot] updated from transifex 2014-11-13 01:25:30 -05:00
Markus Goetz
348b7bf4eb SyncEngine: Output versions used 2014-11-12 09:21:37 +01:00
Markus Goetz
30479cc5a2 Wizard: Properly show error message 2014-11-12 09:21:37 +01:00
Jenkins for ownCloud
1ba1bdec2d [tx-robot] updated from transifex 2014-11-12 01:25:29 -05:00
Daniel Molkentin
8993af4378 Bump version in readme 2014-11-12 00:32:28 +01:00
Daniel Molkentin
9a58d0e559 Merge pull request #2469 from owncloud/fixing_indent
Fixing indent and make nautilus script python3 compatible.
2014-11-12 00:08:46 +01:00
Olivier Goffart
b04cb23ed5 t8.pl: fix the test for me
On localhost, the other file (the bigger one) was downloaded first
2014-11-11 16:38:20 +01:00
Jenkins for ownCloud
ced986e010 [tx-robot] updated from transifex 2014-11-11 01:25:22 -05:00
Jenkins for ownCloud
cde9b3ac85 [tx-robot] updated from transifex 2014-11-10 01:25:22 -05:00
hefee
f9dfdd58df Fixing indent and make nautilus script python3 compatible. 2014-11-09 16:59:01 +01:00
Jenkins for ownCloud
c9f9388ef6 [tx-robot] updated from transifex 2014-11-09 01:25:21 -05:00
Jenkins for ownCloud
b8cb180e4b [tx-robot] updated from transifex 2014-11-08 01:25:22 -05:00
Daniel Molkentin
e579504181 Merge pull request #2370 from owncloud/icons-overlay-doc
Add section on Overlay Icons to 'Using the Synchronization Client'
2014-11-07 16:52:26 +01:00
Daniel Molkentin
7c034b427e Handle invalid handle & fix an issue found during code review 2014-11-07 14:52:31 +01:00
Jenkins for ownCloud
08868594ae [tx-robot] updated from transifex 2014-11-07 01:25:32 -05:00
Daniel Molkentin
cc6e548a78 Merge pull request #2419 from owncloud/updater
Update and correct doc/autoupdate.rst
2014-11-06 19:53:33 +01:00
Daniel Molkentin
17a4299f74 Fix nautilus python integration 2014-11-06 19:26:43 +01:00
Daniel Molkentin
776f4dc316 v1.7.0 2014-11-06 15:53:17 +01:00
Daniel Molkentin
5db55d9e29 Prettify Changelog 2014-11-06 15:41:23 +01:00
Christian Kamm
5c9564ac08 Add to 1.7 changelog. 2014-11-06 15:31:09 +01:00
Daniel Molkentin
5c5a89c1a4 Revert "Bump binary directory to current master"
This reverts commit af4e9c30f5.

This is consistent with 176413d312.
2014-11-06 15:21:39 +01:00
Daniel Molkentin
176413d312 Revert "Windows Shell Integration: Show status icon for root folder"
This reverts commit 5805ffebec.

There is no good way to fix this on the Mirall side without risk.
Delay until after 1.7.0
2014-11-06 15:18:54 +01:00
Olivier Goffart
b70ecc3dd3 Never overwrite the mtime from the local file system in the db when updating the metadata
Attempt to fix #2431
2014-11-06 15:13:10 +01:00
Daniel Molkentin
89670e5ce4 Folderwatcher_win: handle conversion error 2014-11-06 12:54:33 +01:00
Christian Kamm
174e1acbc7 Folder::wipe(): Remove partial downloads and -shm,-wal db files. 2014-11-06 12:49:02 +01:00
Christian Kamm
1f09a24a72 Resync button: Remove partial downloads too. #2445 2014-11-06 12:17:04 +01:00
Christian Kamm
eed91ddf46 Legacy propagator: Don't use mtime retrieved via _fstat64.
May be the cause of #2431
2014-11-06 12:16:55 +01:00
Daniel Molkentin
96a7118d05 WiP: switch to ReadDirectoryChangesW 2014-11-06 12:04:33 +01:00
Klaas Freitag
6eec896282 FolderWatcher: Check for hidden outside of loop 2014-11-06 09:23:30 +01:00
Klaas Freitag
a78bb252de Nautilus shell: Remove some useless logging. 2014-11-06 09:23:30 +01:00
Jenkins for ownCloud
0ba07f19f7 [tx-robot] updated from transifex 2014-11-06 01:25:24 -05:00
Christian Kamm
a49a6bfd88 Logging: Report setModTime failures.
Ths may be helpful for #2252 and maybe even #2431.
2014-11-05 13:20:19 +01:00
Christian Kamm
b87931c0a9 Logging: Print etags, not just result of comparison. 2014-11-05 13:08:53 +01:00
Christian Kamm
9b640d586b Wizard: Fix local folder warning in advanced setup wizard. #2362
The _oldLocalFolder should always be the previously configured
folder, not the one that was most recently chosen on the wizard
page.
2014-11-05 12:10:41 +01:00
Christian Kamm
7440ffc0e6 Download: Fix data loss when rename fails. #2428 2014-11-05 11:00:46 +01:00
Jenkins for ownCloud
63e901cd0b [tx-robot] updated from transifex 2014-11-05 01:25:23 -05:00
Daniel Molkentin
af4e9c30f5 Bump binary directory to current master 2014-11-04 09:33:04 +01:00
Daniel Molkentin
5805ffebec Windows Shell Integration: Show status icon for root folder 2014-11-04 09:30:29 +01:00
Jenkins for ownCloud
39bfacf1d5 [tx-robot] updated from transifex 2014-11-04 01:25:23 -05:00
Daniel Molkentin
8d30fc2718 Update binary subrepo to master 2014-11-03 22:51:55 +01:00
Daniel Molkentin
19daff36b0 Windows Overlay: Fix icon refresh
The condition for the refresh was inverse of what it should have been.
2014-11-03 20:46:35 +01:00
Daniel Molkentin
c34c8ff358 Windows Overlay: Use FLUSHNOW everywhere to speed up updates 2014-11-03 20:45:38 +01:00
Daniel Molkentin
af68cb6029 Move binary submodule to current master 2014-11-03 11:17:04 +01:00
Jenkins for ownCloud
6b6b212643 [tx-robot] updated from transifex 2014-11-03 01:25:21 -05:00
Jenkins for ownCloud
dd2a71fa8f [tx-robot] updated from transifex 2014-11-02 01:25:21 -04:00
Jenkins for ownCloud
cd72d133a3 [tx-robot] updated from transifex 2014-11-01 01:25:22 -04:00
Jenkins for ownCloud
d3662d0e34 [tx-robot] updated from transifex 2014-10-31 01:25:27 -04:00
Markus Goetz
cf6219bb6f NetworkJobs: Improve timeout handling and increase timeout by 5 sec 2014-10-30 11:54:58 +01:00
Christian Kamm
45eeb5065f Download: Avoid overwriting file with case conflict. #1914 2014-10-30 09:06:53 +01:00
Jenkins for ownCloud
f563eb1f63 [tx-robot] updated from transifex 2014-10-30 01:25:30 -04:00
Carla Schroder
2c1f31cecb Update autoupdate.rst
Corrected configuration file location
2014-10-29 09:56:17 -07:00
Klaas Freitag
1029f9521c tests: exit t5.pl if running against ownCloud 6
t5.pl checks the environment variable SERVER_VERSION and if that equals
"owncloud6" it bails out after a check of the sharing ocs api.
2014-10-29 14:24:36 +01:00
Klaas Freitag
825eca078d tests: make t1.pl work on jenkins, for that disable a size compare. 2014-10-29 14:01:58 +01:00
Olivier Goffart
1eccfb798f Add missing license headers
Part of #2068
2014-10-29 13:30:46 +01:00
Olivier Goffart
7810da51a8 Propagator: report error when deleting directories
Will help to understand why a directory cannot be removed

Will help for #2348
2014-10-29 12:23:48 +01:00
Olivier Goffart
a470138450 Windows Shell Integration: refresh the cache on UPDATE_VIEW
Attempt to fix #2383
2014-10-29 11:00:51 +01:00
Markus Goetz
7bad731ad2 CheckServerJob: Guard again null reply
Lucia had reported a crash in this function
2014-10-29 09:38:20 +01:00
Jenkins for ownCloud
eeb54290b3 [tx-robot] updated from transifex 2014-10-29 01:25:27 -04:00
Carla Schroder
94be12b9e4 Merge branch 'updater' of https://github.com/owncloud/mirall into updater 2014-10-28 15:01:34 -07:00
Carla Schroder
1862fb77ff Correct Linux section on disabling update notifications 2014-10-28 14:57:18 -07:00
Markus Goetz
782463589e ownSql: Also mention filename 2014-10-28 21:50:09 +01:00
Markus Goetz
ff570c4a6b ownSql: Don't set busy timeout on bad object 2014-10-28 21:46:30 +01:00
Carla Schroder
06b619f0ed Update autoupdate.rst
Typo correction
2014-10-28 12:19:05 -07:00
Carla Schroder
f5cc6cfd07 Fix typos and clean up wording 2014-10-28 11:56:49 -07:00
Carla Schroder
0f5cf00e35 Update The Automatic Updater manual page with current information 2014-10-28 11:52:58 -07:00
Klaas Freitag
105ff694f2 SyncEngine: Handle 503 condition as soft error to properly handle etags.
Otherwise the ETags could be removed from the db and cause file
deletes.
2014-10-28 17:13:21 +01:00
Jenkins for ownCloud
26ff6be63c [tx-robot] updated from transifex 2014-10-28 01:25:42 -04:00
Daniel Molkentin
47e3da9ebf Merge pull request #2414 from owncloud/fix_2365
Doc: Fix build documentation, adjust it to 1.7.
2014-10-27 16:15:14 -04:00
Daniel Molkentin
b7ce5ba82a Doc: Fix build documentation, adjust it to 1.7.
Fixes #2365
2014-10-27 16:14:32 -04:00
Olivier Goffart
5723abe6eb Merge remote-tracking branch 'origin/fix_service_unavailable' into 1.7 2014-10-27 20:49:46 +01:00
Daniel Molkentin
95a9b0427c doc: Fix markup in build.rst 2014-10-27 14:54:23 -04:00
Klaas Freitag
0692fea9d8 discovery: handle 503 reply code from server for directories
503 for directories means that the dir is a mounted directory from an
external mount which currently is not available. The directory is
ignored and not traversed into during discovery phase.
2014-10-27 19:21:12 +01:00
Markus Goetz
b0882a5cd2 Fix compile 2014-10-27 17:18:49 +01:00
Markus Goetz
4c1a0005e6 Make two more asserts usable in nondebug 2014-10-27 16:01:18 +01:00
Markus Goetz
05ceed926c SyncEngine: Log for an assert, return -1 for nondebug compile 2014-10-27 15:52:17 +01:00
Klaas Freitag
b691521662 tests: Fix CSync Journal test, use real CSYNC struct from csync_private.
This fixes bug #2396
2014-10-27 13:15:33 +01:00
Olivier Goffart
ce300d88ee Wizard: show the choice to start a clean sync if the directory exist even on new accounts
Task #2406
2014-10-27 13:05:17 +01:00
Brandon Coleman
05c0249672 correct spelling on user is empty error. 2014-10-27 07:59:31 -04:00
Brandon Coleman
2498c13078 options are required at the beginning of owncloudcmd.
Conflicts:
	src/owncloudcmd/owncloudcmd.cpp
2014-10-27 07:59:31 -04:00
Klaas Freitag
ab5dae741a Show GIT SHA sum in cmake output. 2014-10-27 11:54:22 +01:00
Olivier Goffart
cddad94e45 Selective Sync: change the label text
to specify that the files will be removed from the local folder

Task #2404
2014-10-27 11:33:25 +01:00
Jenkins for ownCloud
2f0a40c1c8 [tx-robot] updated from transifex 2014-10-27 01:25:20 -04:00
Jenkins for ownCloud
3b1ff5bf41 [tx-robot] updated from transifex 2014-10-26 01:25:20 -04:00
Daniel Molkentin
1bd1c61c3c Merge pull request #2399 from r2evans/patch-1
add 64-bit windows registry location
2014-10-25 10:31:04 -04:00
r2evans
9cd81d87b2 add 64-bit windows registry location 2014-10-25 07:25:18 -07:00
Jenkins for ownCloud
59efea1b0e [tx-robot] updated from transifex 2014-10-25 01:25:22 -04:00
Carla Schroder
b5da8423a6 Update navigating.rst 2014-10-22 19:24:19 -07:00
Carla Schroder
c3de0a2d4b Add section on Overlay Icons to 'Using the Synchronization Client' 2014-10-22 19:20:58 -07:00
111 changed files with 7092 additions and 5770 deletions

View File

@@ -14,6 +14,12 @@ if ( EXISTS ${OEM_THEME_DIR}/OEM.cmake )
else ()
include ( ${CMAKE_SOURCE_DIR}/OWNCLOUD.cmake )
endif()
# need this logic to not mess with re/uninstallations via macosx.pkgproj
if(${APPLICATION_REV_DOMAIN} STREQUAL "com.owncloud.desktopclient")
set(APPLICATION_REV_DOMAIN_INSTALLER "com.ownCloud.client")
else()
set(APPLICATION_REV_DOMAIN_INSTALLER ${APPLICATION_REV_DOMAIN})
endif()
if (NOT DEFINED APPLICATION_SHORTNAME)
set ( APPLICATION_SHORTNAME ${APPLICATION_NAME} )
@@ -52,6 +58,7 @@ if (${GIT_SHA1} STREQUAL "GITDIR-NOTFOUND")
set (GIT_SHA1 "${sha1_candidate}")
endif()
endif()
message(STATUS "GIT_SHA1 ${GIT_SHA1}")
endif()
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})

View File

@@ -2,18 +2,18 @@ ChangeLog
=========
version 1.7.0 (release 2014-10-xx)
* oC7 Sharing: Handle new sharing options of ownCloud 7 correctly.
* oC7 Sharing: Handle new sharing options of ownCloud 7 correctly.
* Added Selective sync: Ability to unselect server folders which are
excluded from syncing, plus GUI and setup GUI
* Added overlay icons for Windows Explorer, Mac OS Finder and GNOME Nautilus.
Information is provided by the client via a local socket / named pipe API
which provides information about the sync status of files.
* Improved local change detection: consider file size, detect files
with ongoing changes and do not upload immediately
* Improved HTTP request timeout handler: all successful requests reset
the timeout counter
* Improvements for syncing command line tool: netrc support, improved
SSL support, non interactive mode
* Added a socket based API to provide file management shells with status
information about the sync status of files. That is a prerequisite for
the overlay icons in the file managers.
* Permission system: ownCloud 7 delivers file and folder permissions,
added ability to deal with it for shared folders and more.
* Ignore handling: Do not recurse into ignored or excluded directories
@@ -23,9 +23,17 @@ version 1.7.0 (release 2014-10-xx)
* Blacklist improvements
* Improved logging: more useful meta info, removed noise
* Updated to latest Qt5 versions on Windows and OS X
* Fixed data loss when renaming a download temporary fails and there was
a conflict at the same time.
* Fixed missing warnings about reusing a sync folder when the back button
was used in the advanced folder setup wizard.
* The 'Retry Sync' button now also restarts all downloads.
* Clean up temporary downloads and some extra database files when wiping a
folder.
* OS X: Sparkle update to provide pkg format properly
* OS X: Change distribution format from dmg to pkg with new installer.
* Win: Fix handling of filenames with trailing dot or space
* Windows: Fix handling of filenames with trailing dot or space
* Windows: Don't use the wrong way to get file mtimes in the legacy propagator.
version 1.6.4 (release 2014-10-22)
* Fix startup logic, fixes bug #1989

View File

@@ -8,5 +8,9 @@ set( APPLICATION_UPDATE_URL "https://updates.owncloud.com/client/" CACHE string
set( THEME_CLASS "ownCloudTheme" )
set( APPLICATION_REV_DOMAIN "com.owncloud.desktopclient" )
set( WIN_SETUP_BITMAP_PATH "${CMAKE_SOURCE_DIR}/admin/win/nsi" )
set( MAC_INSTALLER_BACKGROUND_FILE "${CMAKE_SOURCE_DIR}/admin/osx/installer-background.png" CACHE STRING "The MacOSX installer background image")
# set( THEME_INCLUDE "${OEM_THEME_DIR}/mytheme.h" )
# set( APPLICATION_LICENSE "${OEM_THEME_DIR}/license.txt )

View File

@@ -18,7 +18,7 @@ It uses OCSync as its syncing backend.
## Building the source code
Please refer to doc/building.rst, or
[Building the Client](http://doc.owncloud.org/desktop/1.5/building.html)
[Building the Client](http://doc.owncloud.org/desktop/1.7/building.html)
in the ownCloud client manual.
## Authors

View File

@@ -1,10 +1,10 @@
set( MIRALL_VERSION_MAJOR 1 )
set( MIRALL_VERSION_MINOR 7 )
set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_VERSION_PATCH 1 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
set( MIRALL_VERSION_SUFFIX "rc1") #e.g. beta1, beta2, rc1
set( MIRALL_VERSION_SUFFIX "beta1") #e.g. beta1, beta2, rc1
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
if( NOT DEFINED MIRALL_VERSION_BUILD )

View File

@@ -1,3 +1,15 @@
# Check if varialbe MAC_INSTALLER_BACKGROUND_FILE is defined. That might come
# from the OEM.cmake for branded clients or from OWNCLOUD.cmake for the non
# branded client.
# Make sure that the MAC_INSTALLER_BACKGROUND_FILE contains the full path, ie.
# includes CMAKE_SOURCE_DIR or so.
if (DEFINED MAC_INSTALLER_BACKGROUND_FILE )
set(MAC_INSTALLER_DO_CUSTOM_BACKGROUND "1")
else()
set(MAC_INSTALLER_DO_CUSTOM_BACKGROUND "0")
endif()
configure_file(create_mac_pkg.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/create_mac.sh)
configure_file(macosx.pkgproj ${CMAKE_CURRENT_BINARY_DIR}/macosx.pkgproj)
configure_file(macosx.pkgproj ${CMAKE_CURRENT_BINARY_DIR}/macosx.pkgproj)

View File

@@ -485,9 +485,9 @@
<key>CONCLUSION_ACTION</key>
<integer>0</integer>
<key>IDENTIFIER</key>
<string>com.ownCloud.client</string>
<string>@APPLICATION_REV_DOMAIN_INSTALLER@</string>
<key>NAME</key>
<string>ownCloud Client</string>
<string>@APPLICATION_NAME@</string>
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>VERSION</key>
@@ -1055,12 +1055,12 @@
<key>BACKGROUND_PATH</key>
<dict>
<key>PATH</key>
<string>@CMAKE_SOURCE_DIR@/admin/osx/installer-background.png</string>
<string>@MAC_INSTALLER_BACKGROUND_FILE@</string>
<key>PATH_TYPE</key>
<integer>0</integer>
</dict>
<key>CUSTOM</key>
<integer>1</integer>
<integer>@MAC_INSTALLER_DO_CUSTOM_BACKGROUND@</integer>
<key>SCALING</key>
<integer>0</integer>
</dict>
@@ -1213,7 +1213,7 @@
<key>LANGUAGE</key>
<string>English</string>
<key>VALUE</key>
<string>ownCloud Client</string>
<string>@APPLICATION_NAME@ Client</string>
</dict>
</array>
</dict>
@@ -1413,7 +1413,7 @@
</dict>
</array>
<key>NAME</key>
<string>ownCloud Installer</string>
<string>@APPLICATION_NAME@ Installer</string>
<key>REFERENCE_FOLDER_PATH</key>
<string>@CMAKE_INSTALL_DIR@</string>
</dict>

View File

@@ -5,26 +5,6 @@
src_app="$1"
identity="$2"
QT_FMWK_VERSION="5"
fix_frameworks() {
TMP_APP=$1
QT_FMWK_PATH=$2
QT_FMWKS=$3/Qt*.framework
echo "Patching Qt frameworks..."
for FMWK in $QT_FMWKS; do
FMWK_NAME=`basename -s .framework $FMWK`
FMWK=`basename $FMWK`
FMWK_PATH="${TMP_APP}/Contents/Frameworks/${FMWK}"
mkdir -p "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources/"
cp -avf "${QT_FMWK_PATH}/${FMWK}/Contents/Info.plist" "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources"
(cd "${FMWK_PATH}" && ln -sf "Versions/${QT_FMWK_VERSION}/Resources" "Resources")
perl -pi -e "s/${FMWK_NAME}_debug/${FMWK_NAME}/" "${FMWK_PATH}/Resources/Info.plist"
done
}
fix_frameworks "$src_app" `qmake -query QT_INSTALL_LIBS` "$src_app"/Contents/Frameworks
codesign -s "$identity" --force --verbose=4 --deep "$src_app"
# Just for our debug purposes:

2
binary

Submodule binary updated: 18d9ac810b...139acd195b

View File

@@ -1,4 +1,4 @@
SET(WINDRES_EXECUTABLE ${CMAKE_RC_COMPILER})
SET(WINDRES_EXECUTABLE_BASE ${CMAKE_RC_COMPILER})
# This macro is taken from kdelibs/cmake/modules/KDE4Macros.cmake.
#
@@ -21,7 +21,7 @@ macro (KDE4_ADD_APP_ICON appsources pattern)
else(NOT WINCE)
find_program(PNG2ICO_EXECUTABLE NAMES png2ico PATHS ${HOST_BINDIR} NO_DEFAULT_PATH )
endif(NOT WINCE)
find_program(WINDRES_EXECUTABLE NAMES windres)
find_program(WINDRES_EXECUTABLE NAMES ${WINDRES_EXECUTABLE_BASE})
if(MSVC)
set(WINDRES_EXECUTABLE TRUE)
endif(MSVC)

View File

@@ -581,6 +581,17 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
if (asp < 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
}
} else if(errno == ERRNO_SERVICE_UNAVAILABLE) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Service was not available!");
if (ctx->current_fs) {
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
ctx->current_fs->error_status = CSYNC_STATUS_SERVICE_UNAVAILABLE;
/* If a directory has ignored files, put the flag on the parent directory as well */
if( previous_fs ) {
previous_fs->has_ignored_files = true;
}
goto done;
}
} else {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "opendir failed for %s - errno %d", uri, errno);
}

View File

@@ -96,6 +96,7 @@ hbf_transfer_t *hbf_init_transfer( const char *dest_uri ) {
transfer->block_size = DEFAULT_BLOCK_SIZE;
transfer->threshold = transfer->block_size;
transfer->modtime_accepted = 0;
transfer->oc_header_modtime = 0;
return transfer;
}
@@ -491,8 +492,8 @@ Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const cha
snprintf(buf, sizeof(buf), "%"PRId64, transfer->stat_size);
ne_add_request_header(req, "OC-Total-Length", buf);
if( transfer->modtime > 0 ) {
snprintf(buf, sizeof(buf), "%"PRId64, transfer->modtime);
if( transfer->oc_header_modtime > 0 ) {
snprintf(buf, sizeof(buf), "%"PRId64, transfer->oc_header_modtime);
ne_add_request_header(req, "X-OC-Mtime", buf);
}
@@ -502,6 +503,8 @@ Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const cha
if( transfer->block_cnt > 1 ) {
ne_add_request_header(req, "OC-Chunked", "1");
snprintf(buf, sizeof(buf), "%"PRId64, transfer->threshold);
ne_add_request_header(req, "OC-Chunk-Size", buf);
}
ne_add_request_header( req, "Content-Type", "application/octet-stream");

View File

@@ -92,6 +92,7 @@ struct hbf_transfer_s {
int64_t stat_size;
time_t modtime;
time_t oc_header_modtime;
int64_t block_size;
int64_t threshold;

View File

@@ -362,6 +362,8 @@ sub assertFile($$)
}
my $stat_ok = stat( $localFile2 );
print " *** STAT failed for $localFile2\n" unless( $stat_ok );
assert($stat_ok, "Stat failed for file $localFile");
my @info = stat( $localFile2 );
my $localModTime = $info[9];
assert( $remoteModTime == $localModTime, "Modified-Times differ: remote: $remoteModTime <-> local: $localModTime" );
@@ -371,7 +373,7 @@ sub assertFile($$)
my $remoteSize = $res->get_property( "getcontentlength" );
if( $remoteSize ) { # directories do not have a contentlength
print "Local versus Remote size: $localSize <-> $remoteSize\n";
assert( $localSize == $remoteSize, "File sizes differ" );
# assert( $localSize == $remoteSize, "File sizes differ" ); # FIXME enable this again but it causes trouble on Jenkins all the time.
}
}

View File

@@ -51,6 +51,11 @@ print "Created share with id <$shareId>\n";
assert( $shareId > 0 );
if( $ENV{SERVER_VERSION} eq "owncloud6" ) {
print "This test does not make more sense for ownCloud6, leaving for good!\n\n";
exit;
}
# put a couple of files into the shared directory in the sharer account
glob_put( 'sharing/*', $share_dir, $sharee);
@@ -62,7 +67,6 @@ moveRemoteFile( server() . $share_dir, localDir(), 1 );
printInfo("Initial sync, sync stuff down.");
csync();
assertLocalAndRemoteDir( '', 0 );
# Local file to a read/write share should be synced up

View File

@@ -35,7 +35,7 @@ print "Hello, this is t8, a tester for syncing of files on a case sensitive FS\n
# The test is run on a 'normal' file system, but we tell pwncloud that it is case preserving anyway
$ENV{OWNCLOUD_TEST_CASE_PRESERVING} = "1";
# FIXME! the code does not work with parallelism
# No parallelism for more deterministic action.
$ENV{OWNCLOUD_MAX_PARALLEL}="1";
initTesting();
@@ -112,6 +112,25 @@ assert( !-e localDir() . 'dir' );
# dir/NORMAL.dat is still on the server
printInfo( "Attempt downloading two clashing files in parallel" );
# Enable parallelism
$ENV{OWNCLOUD_MAX_PARALLEL}="2";
my $tmpdir2 = "/tmp/t8/parallel/";
mkdir($tmpdir2);
createLocalFile( $tmpdir2 . "FILE.dat", 23251233 );
createLocalFile( $tmpdir2 . "file.dat", 33 );
createRemoteDir( "parallel" );
glob_put( "$tmpdir2/*", "parallel" );
csync();
# only one file must exist
assert( (!-e localDir() . 'parallel/FILE.dat' ) or (!-e localDir() . 'parallel/file.dat') );
assert( (-e localDir() . 'parallel/FILE.dat' ) or (-e localDir() . 'parallel/file.dat') );
cleanup();
system("rm -r " . $tmpdir);

View File

@@ -1,16 +1,19 @@
The Automatic Updater
=====================
To ensure that you are always using the latest version of the ownCloud client,
an auto-update mechanism has been added in Version 1.5.1. The Automatic Updater
ensures that you automatically profit from the latest features and bugfixes.
The Automatic Updater ensures that you always have the
latest features and bugfixes for your ownCloud synchronization client.
.. note:: The Automatic Updater functions differently, depending on the operating system.
The Automatic Updater updates only on Mac OS X and Windows computers; Linux
users only need to use their normal package managers. However, on Linux systems
the Updater will check for updates and notify you when a new version is
available.
Basic Workflow
--------------
The following sections describe how to use the Automatic Updater on different operating systems:
The following sections describe how to use the Automatic Updater on different
operating systems:
Windows
^^^^^^^
@@ -36,7 +39,7 @@ process for Mac OS X applications.
Linux
^^^^^
Linux distributions provide their own update tool, so ownCloud clients that use
Linux distributions provide their own update tools, so ownCloud clients that use
the Linux operating system do not perform any updates on their own. Linux
operating systems do, however, check for the latest version of the ownCloud
client and passively notify the user (``Settings -> General -> Updates``) when
@@ -52,7 +55,7 @@ deployment tools and policies. To address this case, it is possible to disable
the auto-updater entirely. The following sections describe how to disable the
auto-update mechanism for different operating systems.
Preventing Automatic Updates in Windows Environents
Preventing Automatic Updates in Windows Environments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can prevent automatic updates from occuring in Windows environments using
@@ -61,9 +64,10 @@ update check mechanism whereas the second method prevents any manual overrides.
To prevent automatic updates, but allow manual overrides:
1. Migrate to the following directory::
1. Migrate to the following directory:
HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud
a. (32-bit) ``HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud``
b. (64-bit) ``HKEY_LOCAL_MACHINE\Software\Wow6432Node\ownCloud\ownCloud``
2. Add the key ``skipUpdateCheck`` (of type DWORD).
@@ -73,7 +77,8 @@ To manually override this key, use the same value in ``HKEY_CURRENT_USER``.
To prevent automatic updates and disallow manual overrides:
.. note::This is the preferred method of controlling the updater behavior using Group Policies.
.. note::This is the preferred method of controlling the updater behavior using
Group Policies.
1. Migrate to the following directory::
@@ -111,16 +116,10 @@ to ``/Library/Preferences/com.owncloud.desktopclient.plist``.
Preventing Automatic Updates in Linux Environments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Because Linux does not provide automatic updating functionality, there is no
need to remove the automatic-update check. However, if you want to disable
this check:
Because the Linux client does not provide automatic updating functionality, there is no
need to remove the automatic-update check. However, if you want to disable it edit your desktop
client configuration file, ``$HOME/.local/share/data/ownCloud/owncloud.cfg``. Add these lines:
1. Locate and open the following file::
/etc/ownCloud/ownCloud.conf
2. Add the following content to the file::
[General]
skipUpdateCheck=true
[General]
skipUpdateCheck=true

View File

@@ -8,9 +8,9 @@ major platforms. You should read this section if you want to develop for the
desktop client.
.. note:: Building instruction are subject to change as development proceeds.
Please check the version for which you want to built.
Please check the version for which you want to build.
The instructions contained in this topic were updated to work with version 1.5 of the ownCloud Client.
The instructions contained in this topic were updated to work with version 1.7 of the ownCloud Client.
Linux
-----
@@ -24,6 +24,11 @@ Linux
3. Follow the `generic build instructions`_.
4. (Optional) Call ``make install`` to install the client to the ``/usr/local/bin`` directory.
.. note:: This step requires the ``mingw32-cross-nsis`` packages be installed on
Windows.
Mac OS X
--------
@@ -41,17 +46,30 @@ To set up your build enviroment for development using HomeBrew_:
1. Add the ownCloud repository using the following command::
brew tap owncloud/owncloud
brew tap owncloud/owncloud
2. Install any missing dependencies::
brew install $(brew deps mirall)
brew install $(brew deps mirall)
To build mirall, follow the `generic build instructions`_.
3. Add Qt from brew to the path::
.. note:: Because the product from the mirall build is an app bundle, do not
call ``make install`` at any time. Instead, call ``make package`` to create an
install-ready disk image.
export PATH=/usr/local/Cellar/qt5/5.x.y/bin/qmake
Where ``x.z`` is the current version of Qt 5 that brew has installed
on your machine.
5. For compilation of mirall, follow the `generic build instructions`_.
6. In the build directory, run ``admin/osx/create_mac.sh <build_dir>
<install_dir>``. If you have a developer signing certificate, you can specify
its Common Name as a third parameter (use quotes) to have the package
signed automatically.
.. note:: Contrary to earlier versions, ownCloud 1.7 and later are packaged
as a ``pkg`` installer. Do not call "make package" at any time when
compiling for OS X, as this will build a disk image, and will not
work correctly.
Windows (Cross-Compile)
-----------------------
@@ -63,15 +81,14 @@ have it installed already.
To cross-compile:
1. Add the following repositories using YaST or ``zypper ar`` (adjust when using openSUSE 12.2 or 13.1):
1. Add the following repositories using YaST or ``zypper ar`` (adjust when using openSUSE 12.2 or 13.1)::
- ``zypper ar http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_13.1/windows:mingw:win32.repo``
- ``zypper ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_13.1/windows:mingw.repo``
zypper ar http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_13.1/windows:mingw:win32.repo
zypper ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_13.1/windows:mingw.repo
2. Install the cross-compiler packages and the cross-compiled dependencies::
``zypper install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \
zypper install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \
mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \
mingw32-headers mingw32-runtime site-config mingw32-libqt4-sql \
mingw32-libqt4-sql-sqlite mingw32-sqlite mingw32-libsqlite-devel \
@@ -82,42 +99,44 @@ To cross-compile:
mingw32-libpng-devel mingw32-libsqlite mingw32-qtkeychain \
mingw32-qtkeychain-devel mingw32-dlfcn mingw32-libintl-devel \
mingw32-libneon-devel mingw32-libopenssl-devel mingw32-libproxy-devel \
mingw32-libxml2-devel mingw32-zlib-devel``
mingw32-libxml2-devel mingw32-zlib-devel
3. For the installer, install the NSIS installer package::
``zypper install mingw32-cross-nsis``
zypper install mingw32-cross-nsis
4. Install the following plugin::
``mingw32-cross-nsis-plugin-processes mingw32-cross-nsis-plugin-uac``
mingw32-cross-nsis-plugin-processes mingw32-cross-nsis-plugin-uac
.. note:: This plugin is typically required. However, due to a current bug
in ``mingw``, the plugins do not currently build properly from source.
5. Manually download and install the following files using ``rpm -ivh <package>``:
..note:: These files operate using openSUSE 12.2 and newer.
.. note:: These files also work for more recent openSUSE versions!
- ``rpm -ihv http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-processes-0-1.1.x86_64.rpm``
::
- ``rpm -ihv http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-uac-0-3.1.x86_64.rpm``
rpm -ivh http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-processes-0-1.1.x86_64.rpm
rpm -ivh http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-uac-0-3.1.x86_64.rpm
6. Follow the `generic build instructions`_
.. note:: When building for Windows platforms, you must specify a special
toolchain file that enables cmake to locate the platform-specific tools. To add
this parameter to the call to cmake, enter
``DCMAKE_TOOLCHAIN_FILE=../mirall/admin/win/Toolchain-mingw32-openSUSE.cmake``.
``-DCMAKE_TOOLCHAIN_FILE=../mirall/admin/win/Toolchain-mingw32-openSUSE.cmake``.
7. Build by running ``make``.
..note:: Using ``make package`` produces an NSIS-based installer, provided
.. note:: Using ``make package`` produces an NSIS-based installer, provided
the NSIS mingw32 packages are installed.
.. _`generic build instructions`:
Generic Build Instructions
--------------------------
.. _`generic build instructions`
Compared to previous versions, building Mirall has become easier. Unlike
earlier versions, CSync, which is the sync engine library of Mirall, is now
@@ -140,33 +159,32 @@ To build the most up to date version of the client:
``cd ../mirall-build``
``cmake -DCMAKE_BUILD_TYPE="Debug" ../mirall``
..note:: You must use absolute pathes for the ``include`` and ``library`` directories.
..note:: You must use absolute paths for the ``include`` and ``library``
directories.
..note:: On Mac OS X, you need to specify ``-DCMAKE_INSTALL_PREFIX=target``,
where ``target`` is a private location, i.e. in parallel to your build
dir by specifying ``../install``.
4. Call ``make``.
The owncloud binary appear in the ``bin`` directory.
5. (Optional) Call ``make install`` to install the client to the ``/usr/local/bin`` directory.
6. (Optional) Call ``make package`` to build an installer/app bundle
..note:: This step requires the ``mingw32-cross-nsis`` packages be installed on Windows.
The following are known cmake parameters:
* ``QTKEYCHAIN_LIBRARY=/path/to/qtkeychain.dylib -DQTKEYCHAIN_INCLUDE_DIR=/path/to/qtkeychain/``:
Used for stored credentials. When compiling with Qt5, the library is called ``qt5keychain.dylib.``
You need to compile QtKeychain with the same Qt version.
* ``WITH_DOC=TRUE``: Creates doc and manpages through running ``make``; also
* adds install statements, providing the ability to install using ``make
* install``.
* ``WITH_DOC=TRUE``: Creates doc and manpages through running ``make``; also adds install statements,
providing the ability to install using ``make install``.
* ``CMAKE_PREFIX_PATH=/path/to/Qt5.2.0/5.2.0/yourarch/lib/cmake/``: Builds using Qt5.
* ``BUILD_WITH_QT4=ON``: Builds using Qt4 (even if Qt5 is found).
* ``CMAKE_INSTALL_PREFIX=path``: Set an install prefix. This is mandatory on Mac OS
.. _`ownCloud repository from OBS`: http://software.opensuse.org/download/package?project=isv:ownCloud:devel&package=owncloud-client
.. _`ownCloud repository from OBS`: http://software.opensuse.org/download/package?project=isv:ownCloud:desktop&package=owncloud-client
.. _CSync: http://www.csync.org
.. _`Client Download Page`: http://owncloud.org/sync-clients/
.. _Git: http://git-scm.com
.. _MacPorts: http://www.macports.org
.. _Homebrew: http://mxcl.github.com/homebrew/
.. _QtKeychain https://github.com/frankosterfeld/qtkeychain
.. _QtKeychain: https://github.com/frankosterfeld/qtkeychain

BIN
doc/images/icon-error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
doc/images/icon-offline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
doc/images/icon-paused.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
doc/images/icon-syncing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -9,7 +9,35 @@ system tray (Windows, KDE), status bar (MAC OS X), or notification area
.. image:: images/icon.png
**ownCloud Desktop Client icon**
This is a status indicator which uses overlay icons to indicate the
current status of your synchronization. The green circle with the white checkmark
tells you that your synchronization is current and you are connected to your
ownCloud server.
.. image:: images/icon-syncing.png
The blue icon with the white semi-circles means synchronization is in progress.
.. image:: images/icon-paused.png
The yellow overlay icon with the parallel lines tells you your synchronization
has been paused. (Most likely by you, by opening the client and clicking
Account > Pause.)
.. image:: images/icon-offline.png
The gray icon with three white dots means your sync client has lost its
connection with your ownCloud server.
.. image:: images/icon-information.png
When you see a white circle with the letter "i" that is the informational icon,
so you should click it to see what it has to tell you.
.. image:: images/icon-error.png
The red circle with the white "x" indicates a configuration error, such as an
incorrect login or server URL.
Using the Desktop Client Menu
-----------------------------
@@ -24,10 +52,17 @@ following menu:
The Desktop Client menu provides the following options:
* ``Open ownCloud in browser``: Launches the ownCloud WEB interface.
* ``Open folder 'ownCloud'``: Opens the ownCloud local folder. If you have defined multiple synchronization targets, the window displays each local folder.
* **Disk space indicator**: Indicates the amount of space currently used on the server.
* Operation indicator: Displays the status of the current synchronization process or indicates ``Up to date`` if the server and client are in sync.
* **Recent Changes**: Displays the last six files modified by the synchronization operations and provides access to the current synchronization status listing all changes since the last restart of the ownCloud client.
* ``Open folder 'ownCloud'``: Opens the ownCloud local folder. If you have
defined multiple synchronization targets, the window displays each local
folder.
* **Disk space indicator**: Indicates the amount of space currently used on the
server.
* Operation indicator: Displays the status of the current synchronization
process or indicates ``Up to date`` if the server and client are in sync.
* **Recent Changes**: Displays the last six files modified by the
synchronization operations and provides access to the current
synchronization status listing all changes since the last restart of the
ownCloud client.
* ``Settings...``: Provides access to the settings menu.
* ``Help``: Opens a browser to display ownCloud Desktop Client Guide.
* ``Sign out``: Disables the client from continued synchronizations.
@@ -39,7 +74,9 @@ Using the Account Settings Window
.. index:: account settings, user, password, Server URL
The ``Account`` window provides a summary for general settings associated with the ownCloud account. This window enalbes you to manage any synchronized folders in the account and enables you to modify them.
The ``Account`` window provides a summary for general settings associated with
the ownCloud account. This window enalbes you to manage any synchronized
folders in the account and enables you to modify them.
To access and modify the account settings:
@@ -48,25 +85,37 @@ To access and modify the account settings:
The fields and options in this window include:
* ``Connected to <ownCloud instance> as <user>`` field: Indicates the ownCloud server to which the client is synchronizing and the user account on that server.
* ``Connected to <ownCloud instance> as <user>`` field: Indicates the ownCloud
server to which the client is synchronizing and the user account on that
server.
* ``Add Folder...`` button: Provides the ability to add another folder to the synchronization process (see ``Adding a Folder``).
* ``Add Folder...`` button: Provides the ability to add another folder to the
synchronization process (see ``Adding a Folder``).
* ``Pause/Resume`` button: Pauses the current sync (or prevents the client from starting a new sync) or resumes the sync process.
* ``Pause/Resume`` button: Pauses the current sync (or prevents the client from
starting a new sync) or resumes the sync process.
* ``Remove`` button: Removes the selected folder from the sync process. This button is used when you want to synchronize only a few folders and not the root folder. If only the root folder is available, you must first remove the root from the synchronization and then add individual folders that you want to synchronize as desired.
* ``Remove`` button: Removes the selected folder from the sync process. This
button is used when you want to synchronize only a few folders and not the
root folder. If only the root folder is available, you must first remove the
root from the synchronization and then add individual folders that you want
to synchronize as desired.
* ``Storage Usage`` field: Indicates the storage utilization on the ownCloud server.
* ``Storage Usage`` field: Indicates the storage utilization on the ownCloud
server.
* ``Edit Ignored Files`` button: Launches the Ignored Files Editor.
* ``Modify Account`` button: Enables you to change the ownCloud server to which you are synchronizing. This option launches the ``Setting up an Account`` windows (See ??).
* ``Modify Account`` button: Enables you to change the ownCloud server to which
you are synchronizing. This option launches the ``Setting up an Account``
dialog (see :doc:`accountsetup`).
Adding a Folder
^^^^^^^^^^^^^^^
The ``Add a Folder ...`` button enables you to add a new folder to the syncrhonization process.
The ``Add a Folder ...`` button enables you to add a new folder to the
syncrhonization process.
To add a new folder:
@@ -74,37 +123,35 @@ To add a new folder:
The ``Add Folder...`` window opens
.. image:: images/folderwizard_local.png
:scale: 50 %
.. image:: images/folderwizard_local.png
**``Add Folder...`` window (local folder)**
2. Specify a *unique* path and alias name to the folder or use the ``Choose...``
button to locate the new folder on your system to which you want to
synchronize.
2. Specify a *unique* path and alias name to the folder or use the ``Choose...`` button to locate the new folder on your system to which you want to synchronize.
..note:: Nested synchronizations are not supported. In other words, you
.. note:: Nested synchronizations are not supported. In other words, you
cannot add a folder that is already contained within another synchronized
folder. In addition, you cannot add a higher level (parent) folder that
contains a folder to which you are already synchronizing. By default, the
ownCloud Set Up Wizard syncrhonizes your entire ownCloud account to the root
folder of the ownCloud server. Due to this default setup, you must first remove
the top-level folder prior to specifying new synchronizations.
folder of the ownCloud server. Due to this default setup, you must first
remove the top-level folder prior to specifying new synchronizations.
3. Click 'Next' to continue.
A window opens prompting you to select a remote destination folder on the
ownCloud server to which you want to synchronize.
.. image:: images/folderwizard_remote.png
:scale: 50 %
.. image:: images/folderwizard_remote.png
**``Add Folder...`` window (remote destination)**
4. Select a folder on the ownCloud server to which you want to synchronize your
newly added folder.
4. Select a folder on the ownCloud server to which you want to synchronize your newly added folder.
..note:: A server folder can only be synchronized with a particular client once.
If you attempt to sync the root directory, you cannot sync with other folders
on the server. Similarly, if you sync with folder ``/a``, you cannot create
another sync with ``/a/b``, since ``b`` is already being synched.
..note:: A server folder can only be synchronized with a particular client
once. If you attempt to sync the root directory, you cannot sync with
other folders on the server. Similarly, if you sync with folder ``/a``, you
cannot create another sync with ``/a/b``, since ``b`` is already being
synched.
Editing Ignored Files
^^^^^^^^^^^^^^^^^^^^^
@@ -117,7 +164,8 @@ In addition to using standard characters, the Ignored Files Editor enables you
to use wild cards (for example, using an asterisk * to indicate multiple
characters or a question mark ? to incidate a single character).
For additional information about this editor, see `Using the Ignored Files Editor`_
For additional information about this editor, see `Using the Ignored Files
Editor`_
Using the Activity Settings Window
----------------------------------
@@ -131,9 +179,6 @@ manner due to containing special characters that cannot be stored on certain
file systems.
.. image:: images/settings_activity.png
:scale: 50 %
**Activity settings window**
You can open the Activity window in one of the following ways:
@@ -152,9 +197,6 @@ ownCloud Desktop Client and provides information about the software version,
its creator, and the existance of any updates.
.. image:: images/settings_general.png
:scale: 50 %
**General settings window**
The settings and information contained in this window are as follows:
@@ -170,12 +212,13 @@ The settings and information contained in this window are as follows:
* ``Use Monochrome Icons`` checkbox: Provides the option to check (enable) or
uncheck (disable) the use of monochrome (visually less obtrusive) icons.
.. note:: This option can be useful on MAC OSX platforms.
.. note:: This option can be useful on MAC OSX platforms.
* ``About`` field: Provides information about the software authors along with
pertinent build conditions.
.. note:: Information in this field can be valuable when submitting a support request.
.. note:: Information in this field can be valuable when submitting a support
request.
* ``Updates`` field: Provides information about any available updates for the
ownCloud Desktop Client.
@@ -190,9 +233,6 @@ well as limit the download and upload bandwidth utilization of file
synchronizations.
.. image:: images/settings_network.png
:scale: 50 %
**Network settings window**
Specifying Proxy Settings
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -202,20 +242,27 @@ that functions as an intermediary contact for requests from clients that are
seeking resources from other servers. For the ownCloud Desktop Client, you can
define the following proxy settings:
* ``No Proxy`` option: Specifies that the ownCloud Client circumvent the default proxy configured on the system.
* ``No Proxy`` option: Specifies that the ownCloud Client circumvent the default
proxy configured on the system.
* ``Use system proxy`` option: Default setting. Follows the systems proxy
settings. On Linux systems, this setting uses the value of the variable
``http_proxy``.
* ``Specify proxy manually as`` option: Enables you to specify
the following custom proxy settings:
- ``HTTP(S)``: Used when you are required to use an HTTP(S) proxy server (for example, Squid or Microsoft Forefront TMG).
- ``SOCKSv5``: Typically used in special company LAN setups, or in combination with the OpenSSH
- ``HTTP(S)``: Used when you are required to use an HTTP(S) proxy server (for
example, Squid or Microsoft Forefront TMG).
- ``SOCKSv5``: Typically used in special company LAN setups, or in combination
with the OpenSSH
dynamic application level forwarding feature (see ``ssh -D``).
- ``Host``: Host name or IP address of the proxy server along with the port number. HTTP proxies
typically listen over Ports 8080 (default) or 3128. SOCKS servers typically listen over port 1080.
* ``Proxy Server requires authentication`` checkbox: Provides the option to check (enable/require) or
uncheck (disable/not require) proxy server authentication. When not checked, the proxy server must
be configured to allow anonymous usage. When checked, a proxy server username and password is required.
- ``Host``: Host name or IP address of the proxy server along with the port
number. HTTP proxies typically listen over Ports 8080 (default) or 3128.
SOCKS servers typically listen over port 1080.
* ``Proxy Server requires authentication`` checkbox: Provides the option to
check (enable/require) or
uncheck (disable/not require) proxy server authentication. When not checked,
the proxy server must
be configured to allow anonymous usage. When checked, a proxy server username
and password is required.
Bandwidth Limiting
^^^^^^^^^^^^^^^^^^
@@ -265,13 +312,10 @@ can use the *Ignored Files Editor* that is embedded in the ownCloud Desktop
Client.
.. image:: images/ignored_files_editor.png
:scale: 50%
Ignored Files Editor window
The :guilabel:`Ignored Files Editor` enables you to define customized patterns that the
ownCloud Client uses to identify files and directories that you want to exclude
from the synchronization process. For your convenience, the editor is
The ``Ignored Files Editor`` enables you to define customized patterns
that the ownCloud Client uses to identify files and directories that you want
to exclude from the synchronization process. For your convenience, the editor is
pre-populated with a default list of typically ignore patterns. These patterns
are contained in a system file (typically ``sync-exclude.lst``) located in the
ownCloud Client application directory. You cannot modify these pre-populated

View File

@@ -18,6 +18,19 @@ import socket
from gi.repository import GObject, Nautilus
def get_runtime_dir():
"""Returns the value of $XDG_RUNTIME_DIR, a directory path.
If the value is not set, returns the same default as in Qt5
"""
try:
return os.environ['XDG_RUNTIME_DIR']
except KeyError:
fallback = '/tmp/runtime-' + os.environ['USER']
return fallback
class syncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
nautilusVFSFile_table = {}
@@ -38,21 +51,21 @@ class syncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
try:
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
postfix = "/"+self.appname+"/socket"
sock_file = os.environ["XDG_RUNTIME_DIR"]+postfix
sock_file = get_runtime_dir()+postfix
print ("XXXX " + sock_file + " <=> " + postfix)
if sock_file != postfix:
try:
print("Socket File: "+sock_file)
self.sock.connect(sock_file)
self.connected = True
print("Setting connected to %r" % self.connected )
self.watch_id = GObject.io_add_watch(self.sock, GObject.IO_IN, self.handle_notify)
do_reconnect = False
except Exception, e:
print("Could not connect to unix socket." + str(e))
else:
print("Sock-File not valid: "+sock_file)
except Exception, e:
try:
print("Socket File: "+sock_file)
self.sock.connect(sock_file)
self.connected = True
print("Setting connected to %r" % self.connected )
self.watch_id = GObject.io_add_watch(self.sock, GObject.IO_IN, self.handle_notify)
do_reconnect = False
except Exception as e:
print("Could not connect to unix socket." + str(e))
else:
print("Sock-File not valid: "+sock_file)
except Exception as e:
print("Connect could not be established, try again later " + str(e))
self.sock.close()
# print("Returning %r" % do_reconnect)
@@ -75,7 +88,7 @@ class syncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
return None
def askForOverlay(self, file):
# print("Asking for overlay for "+file)
# print("Asking for overlay for "+file)
if os.path.isdir(file):
folderStatus = self.sendCommand("RETRIEVE_FOLDER_STATUS:"+file+"\n");
@@ -85,15 +98,15 @@ class syncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
def invalidate_items_underneath(self, path):
update_items = []
if not self.nautilusVFSFile_table:
self.askForOverlay(path)
else:
for p in self.nautilusVFSFile_table:
if p == path or p.startswith(path):
item = self.nautilusVFSFile_table[p]['item']
update_items.append(item)
self.askForOverlay(path)
else:
for p in self.nautilusVFSFile_table:
if p == path or p.startswith(path):
item = self.nautilusVFSFile_table[p]['item']
update_items.append(item)
for item in update_items:
item.invalidate_extension_info()
for item in update_items:
item.invalidate_extension_info()
# Handles a single line of server respoonse and sets the emblem
def handle_server_response(self, l):
@@ -118,16 +131,16 @@ class syncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
# file = parts[1]
# print "Action for " + file + ": "+parts[0]
if action == 'STATUS':
newState = parts[1]
newState = parts[1]
emblem = Emblems[newState]
if emblem:
itemStore = self.find_item_for_file(parts[2])
if itemStore:
if( not itemStore['state'] or newState != itemStore['state'] ):
item = itemStore['item']
item.add_emblem(emblem)
# print "Setting emblem on " + parts[2]+ "<>"+emblem+"<>"
self.nautilusVFSFile_table[parts[2]] = {'item': item, 'state':newState}
if( not itemStore['state'] or newState != itemStore['state'] ):
item = itemStore['item']
item.add_emblem(emblem)
# print "Setting emblem on " + parts[2]+ "<>"+emblem+"<>"
self.nautilusVFSFile_table[parts[2]] = {'item': item, 'state':newState}
elif action == 'UPDATE_VIEW':
# Search all items underneath this path and invalidate them
@@ -195,4 +208,5 @@ class syncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
self.askForOverlay(filename)
break
else:
print("Not in scope:"+filename)
# print("Not in scope:"+filename)
pass

View File

@@ -1,3 +1,16 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <QApplication>
#include <QLocalSocket>
#include <QDir>

View File

@@ -1,3 +1,15 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "socketclient.h"

View File

@@ -1,3 +1,16 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef SOCKETCLIENT_H
#define SOCKETCLIENT_H

View File

@@ -1,3 +1,16 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "window.h"
#include "ui_window.h"

View File

@@ -1,3 +1,16 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef WINDOW_H
#define WINDOW_H

View File

@@ -16,6 +16,8 @@
#include "RemotePathChecker.h"
#include "StringUtil.h"
#include <shlobj.h>
#include <algorithm>
#include <iostream>
#include <sstream>
@@ -77,7 +79,7 @@ void RemotePathChecker::workerThreadLoop()
{ std::unique_lock<std::mutex> lock(_mutex);
_watchedDirectories.push_back(responsePath);
}
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, responsePath.data(), NULL);
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
} else if (StringUtil::begins_with(response, wstring(L"UNREGISTER_PATH:"))) {
wstring responsePath = response.substr(16); // length of UNREGISTER_PATH:
@@ -95,7 +97,7 @@ void RemotePathChecker::workerThreadLoop()
}
}
}
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, responsePath.data(), NULL);
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
} else if (StringUtil::begins_with(response, wstring(L"STATUS:")) ||
StringUtil::begins_with(response, wstring(L"BROADCAST:"))) {
@@ -116,14 +118,25 @@ void RemotePathChecker::workerThreadLoop()
bool changed = false;
{ std::unique_lock<std::mutex> lock(_mutex);
auto &it = _cache[responsePath];
changed = it == state;
changed = (it != state);
it = state;
}
if (changed) {
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
}
}
}
}
else if (StringUtil::begins_with(response, wstring(L"UPDATE_VIEW"))) {
std::unique_lock<std::mutex> lock(_mutex);
auto cache = _cache; // Make a copy of the cache under the mutex
lock.unlock();
// Request a status for all the items in the cache.
for (auto it = cache.begin(); it != cache.end(); ++it) {
if (!socket.SendMsg(wstring(L"RETRIEVE_FILE_STATUS:" + it->first + L'\n').data())) {
break;
}
}
}
}
if (socket.Event() == INVALID_HANDLE_VALUE) {
std::unique_lock<std::mutex> lock(_mutex);
@@ -181,6 +194,7 @@ bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, int* state)
}
_pending.push(filePath);
lock.unlock();
SetEvent(_newQueries);
return false;

View File

@@ -28,7 +28,7 @@ QString AbstractCredentials::keychainKey(const QString &url, const QString &user
return QString::null;
}
if( user.isEmpty() ) {
qDebug() << "Error: User is emty!";
qDebug() << "Error: User is empty!";
return QString::null;
}

View File

@@ -241,7 +241,19 @@ void ShibbolethCredentials::persist(Account* account)
void ShibbolethCredentials::invalidateToken(Account *account)
{
CookieJar *jar = static_cast<CookieJar*>(account->networkAccessManager()->cookieJar());
jar->deleteCookie(_shibCookie);
// Remove the _shibCookie
auto cookies = jar->allCookies();
for (auto it = cookies.begin(); it != cookies.end(); ) {
if (it->name() == _shibCookie.name()) {
it = cookies.erase(it);
} else {
++it;
}
}
jar->setAllCookies(cookies);
// Clear all other temporary cookies
jar->clearSessionCookies();
removeShibCookie(account);
_shibCookie = QNetworkCookie();

View File

@@ -40,7 +40,7 @@ Q_OBJECT
public:
ShibbolethCredentials();
/* create a credidentials for an already connected account */
/* create a credentials for an already connected account */
ShibbolethCredentials(const QNetworkCookie &cookie, Account *acc);
void syncContextPreInit(CSYNC* ctx) Q_DECL_OVERRIDE;

View File

@@ -71,7 +71,7 @@ public:
enum State { Disconnected = 0, /// no network connection
Connected, /// account is online
SignedOut, /// Disconnected + credential token has been discarded
InvalidCredidential /// The credidential are invalids and we are asking for them to the user
InvalidCredential /// The credentials are invalid and we are asking the user for them
};
QString davPath() const { return _davPath; }

View File

@@ -225,7 +225,7 @@ void Application::slotCheckConnection()
Account *account = AccountManager::instance()->account();
if( account ) {
if (account->state() == Account::InvalidCredidential
if (account->state() == Account::InvalidCredential
|| account->state() == Account::SignedOut) {
//Do not try to connect if we are logged out
if (!_userTriggeredConnect) {
@@ -252,14 +252,18 @@ void Application::slotCredentialsFetched()
{
Account *account = AccountManager::instance()->account();
Q_ASSERT(account);
if (!account) {
qDebug() << Q_FUNC_INFO << "No account!";
return;
}
disconnect(account->credentials(), SIGNAL(fetched()), this, SLOT(slotCredentialsFetched()));
if (!account->credentials()->ready()) {
// User canceled the connection or did not give a password
account->setState(Account::SignedOut);
return;
}
if (account->state() == Account::InvalidCredidential) {
// Then we ask again for the credidentials if they are wrong again
if (account->state() == Account::InvalidCredential) {
// Then we ask again for the credentials if they are wrong again
account->setState(Account::Disconnected);
}
slotCheckConnection();
@@ -277,12 +281,11 @@ void Application::slotToggleFolderman(int state)
_checkConnectionTimer.start();
// fall through
case Account::SignedOut:
case Account::InvalidCredidential:
case Account::InvalidCredential:
folderMan->setSyncEnabled(false);
folderMan->terminateSyncProcess();
break;
}
}
void Application::slotConnectionValidatorResult(ConnectionValidator::Status status)

View File

@@ -101,6 +101,10 @@ void ClientProxy::setCSyncProxy( const QUrl& url, CSYNC *csync_ctx )
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(url));
// We set at least one in Application
Q_ASSERT(proxies.count() > 0);
if (proxies.count() == 0) {
qDebug() << Q_FUNC_INFO << "No proxy!";
return;
}
QNetworkProxy proxy = proxies.first();
if (proxy.type() == QNetworkProxy::NoProxy) {
qDebug() << "Passing NO proxy to csync for" << url.toString();

View File

@@ -91,27 +91,11 @@ QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url) const
return cookies;
}
bool CookieJar::deleteCookie(const QNetworkCookie &delCookie)
{
QList<QNetworkCookie> cookies = allCookies();
bool removeSucceeded = false;
foreach(const QNetworkCookie &cookie, cookies) {
// ### cookies are not identical in attriutes, why?
if (cookie.name() == delCookie.name()) {
cookies.removeOne(cookie);
removeSucceeded = true;
}
}
setAllCookies(cookies);
return removeSucceeded;
}
void CookieJar::clearSessionCookies()
{
setAllCookies(removeExpired(allCookies()));
}
void CookieJar::save()
{
QFile file;

View File

@@ -29,13 +29,11 @@ public:
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url) Q_DECL_OVERRIDE;
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const Q_DECL_OVERRIDE;
bool deleteCookie(const QNetworkCookie & cookie)
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
Q_DECL_OVERRIDE //that function is not virtual in Qt4
#endif
;
void clearSessionCookies();
using QNetworkCookieJar::setAllCookies;
using QNetworkCookieJar::allCookies;
signals:
void newCookiesForUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url);
private:

View File

@@ -96,12 +96,18 @@ time_t FileSystem::getModTime(const QString &filename)
return result;
}
void FileSystem::setModTime(const QString& filename, time_t modTime)
bool FileSystem::setModTime(const QString& filename, time_t modTime)
{
struct timeval times[2];
times[0].tv_sec = times[1].tv_sec = modTime;
times[0].tv_usec = times[1].tv_usec = 0;
c_utimes(filename.toUtf8().data(), times);
int rc = c_utimes(filename.toUtf8().data(), times);
if (rc != 0) {
qDebug() << "Error setting mtime for" << filename
<< "failed: rc" << rc << ", errno:" << errno;
return false;
}
return true;
}
bool FileSystem::renameReplace(const QString& originFileName, const QString& destinationFileName, QString* errorString)

View File

@@ -40,7 +40,7 @@ void OWNCLOUDSYNC_EXPORT setFileHidden(const QString& filename, bool hidden);
*/
time_t OWNCLOUDSYNC_EXPORT getModTime(const QString &filename);
void setModTime(const QString &filename, time_t modTime);
bool setModTime(const QString &filename, time_t modTime);
/**
* Rename the file \a originFileName to \a destinationFileName, and overwrite the destination if it

View File

@@ -69,19 +69,11 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
qsrand(QTime::currentTime().msec());
_timeSinceLastSync.start();
MirallConfigFile cfg;
_syncResult.setStatus( SyncResult::NotYetStarted );
// check if the local path exists
checkLocalPath();
int polltime = cfg.remotePollInterval();
qDebug() << "setting remote poll timer interval to" << polltime << "msec";
_pollTimer.setInterval( polltime );
QObject::connect(&_pollTimer, SIGNAL(timeout()), this, SLOT(slotPollTimerTimeout()));
_pollTimer.start();
_syncResult.setFolder(alias);
}
@@ -234,7 +226,6 @@ void Folder::setSyncPaused( bool paused )
// do not stop or start the watcher here, that is done internally by
// folder class. Even if the watcher fires, the folder does not
// schedule itself because it checks the var. _enabled before.
_pollTimer.stop();
setSyncState(SyncResult::Paused);
}
}
@@ -255,20 +246,24 @@ void Folder::prepareToSync()
_syncResult.clearErrors();
}
void Folder::slotPollTimerTimeout()
void Folder::slotRunEtagJob()
{
qDebug() << "* Polling" << alias() << "for changes. (time since last sync:" << (_timeSinceLastSync.elapsed() / 1000) << "s)";
qDebug() << "* Trying to check" << alias() << "for changes via ETag check. (time since last sync:" << (_timeSinceLastSync.elapsed() / 1000) << "s)";
Account *account = AccountManager::instance()->account();
if (!account) {
qDebug() << Q_FUNC_INFO << "No valid account object";
qDebug() << Q_FUNC_INFO << alias() << "No valid account object, not trying to sync";
return;
}
if (!_requestEtagJob.isNull()) {
qDebug() << Q_FUNC_INFO << alias() << "has ETag job queued, not trying to sync";
return;
}
if (_paused || account->state() != Account::Connected) {
qDebug() << "Not syncing. :" << _paused << account->state();
qDebug() << "Not syncing. :" << alias() << _paused << account->state();
return;
}
@@ -306,17 +301,18 @@ void Folder::slotPollTimerTimeout()
// Do the ordinary etag check for the root folder and only schedule a real
// sync if it's different.
RequestEtagJob* job = new RequestEtagJob(account, remotePath(), this);
_requestEtagJob = new RequestEtagJob(account, remotePath(), this);
// check if the etag is different
QObject::connect(job, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
QObject::connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotNetworkUnavailable()));
job->start();
QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
QObject::connect(_requestEtagJob, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotNetworkUnavailable()));
FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob);
// The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null.
}
}
void Folder::etagRetreived(const QString& etag)
{
qDebug() << "* Compare etag with previous etag: " << (_lastEtag != etag);
qDebug() << "* Compare etag with previous etag: last:" << _lastEtag << ", received:" << etag;
// re-enable sync if it was disabled because network was down
FolderMan::instance()->setSyncEnabled(true);
@@ -506,6 +502,26 @@ void Folder::createGuiLog( const QString& filename, SyncFileStatus status, int c
}
}
int Folder::slotDiscardDownloadProgress()
{
// Delete from journal and from filesystem.
QDir folderpath(_path);
QSet<QString> keep_nothing;
const QVector<SyncJournalDb::DownloadInfo> deleted_infos =
_journal.getAndDeleteStaleDownloadInfos(keep_nothing);
foreach (const SyncJournalDb::DownloadInfo & deleted_info, deleted_infos) {
const QString tmppath = folderpath.filePath(deleted_info._tmpfile);
qDebug() << "Deleting temporary file: " << tmppath;
QFile::remove(tmppath);
}
return deleted_infos.size();
}
int Folder::downloadInfoCount()
{
return _journal.downloadInfoCount();
}
int Folder::blackListEntryCount()
{
return _journal.blackListEntryCount();
@@ -629,6 +645,9 @@ void Folder::wipe()
{
QString stateDbFile = path()+QLatin1String(".csync_journal.db");
// Delete files that have been partially downloaded.
slotDiscardDownloadProgress();
_journal.close(); // close the sync journal
QFile file(stateDbFile);
@@ -641,12 +660,11 @@ void Folder::wipe()
} else {
qDebug() << "WRN: statedb is empty, can not remove.";
}
// Check if the tmp database file also exists
QString ctmpName = path() + QLatin1String(".csync_journal.db.ctmp");
QFile ctmpFile( ctmpName );
if( ctmpFile.exists() ) {
ctmpFile.remove();
}
// Also remove other db related files
QFile::remove( stateDbFile + ".ctmp" );
QFile::remove( stateDbFile + "-shm" );
QFile::remove( stateDbFile + "-wal" );
}
bool Folder::setIgnoredFiles()
@@ -753,7 +771,6 @@ void Folder::startSync(const QStringList &pathList)
// disable events until syncing is done
// _watcher->setEventsEnabled(false);
_pollTimer.stop();
emit syncStarted();
}
@@ -884,9 +901,7 @@ void Folder::slotSyncFinished()
// We will make sure that the poll timer occurs soon enough.
// delay 1s, 4s, 9s
int c = _consecutiveFollowUpSyncs;
QTimer::singleShot(c*c * 1000, this, SLOT(slotPollTimerTimeout() ));
} else {
_pollTimer.start();
QTimer::singleShot(c*c * 1000, this, SLOT(slotRunEtagJob() ));
}
}
@@ -956,7 +971,7 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
// speed up next sync
_lastEtag.clear();
_forceSyncOnPollTimeout = true;
QTimer::singleShot(50, this, SLOT(slotPollTimerTimeout()));
QTimer::singleShot(50, this, SLOT(slotRunEtagJob()));
}
}
} // namespace Mirall

View File

@@ -22,6 +22,7 @@
#include "mirall/syncjournaldb.h"
#include "mirall/clientproxy.h"
#include "mirall/syncfilestatus.h"
#include "mirall/networkjobs.h"
#include <csync.h>
@@ -123,6 +124,9 @@ public:
bool estimateState(QString fn, csync_ftw_type_e t, SyncFileStatus* s);
RequestEtagJob *etagJob() { return _requestEtagJob; }
qint64 msecSinceLastSync() { return _timeSinceLastSync.elapsed(); }
signals:
void syncStateChange();
void syncStarted();
@@ -149,6 +153,8 @@ public slots:
void setProxyDirty(bool value);
bool proxyDirty();
int slotDiscardDownloadProgress();
int downloadInfoCount();
int slotWipeBlacklist();
int blackListEntryCount();
@@ -163,7 +169,7 @@ private slots:
void slotJobCompleted(const SyncFileItem&);
void slotSyncItemDiscovered(const SyncFileItem & item);
void slotPollTimerTimeout();
void slotRunEtagJob();
void etagRetreived(const QString &);
void slotNetworkUnavailable();
@@ -199,7 +205,7 @@ private:
bool _csyncUnavail;
bool _wipeDb;
bool _proxyDirty;
QTimer _pollTimer;
QPointer<RequestEtagJob> _requestEtagJob;
QString _lastEtag;
QElapsedTimer _timeSinceLastSync;
bool _forceSyncOnPollTimeout;

View File

@@ -34,6 +34,8 @@
#include <QMessageBox>
#include <QPointer>
#include <QtCore>
#include <QMutableSetIterator>
#include <QSet>
namespace Mirall {
@@ -66,6 +68,13 @@ FolderMan::FolderMan(QObject *parent) :
_socketApi = new SocketApi(this);
_socketApi->slotReadExcludes();
MirallConfigFile cfg;
int polltime = cfg.remotePollInterval();
qDebug() << "setting remote poll timer interval to" << polltime << "msec";
_etagPollTimer.setInterval( polltime );
QObject::connect(&_etagPollTimer, SIGNAL(timeout()), this, SLOT(slotEtagPollTimerTimeout()));
_etagPollTimer.start();
}
FolderMan *FolderMan::instance()
@@ -390,21 +399,17 @@ void FolderMan::slotSetFolderPaused( const QString& alias, bool paused )
}
}
// this really terminates, ie. no questions, no prisoners.
// this really terminates the current sync process
// ie. no questions, no prisoners
// csync still remains in a stable state, regardless of that.
void FolderMan::terminateSyncProcess( const QString& alias )
void FolderMan::terminateSyncProcess()
{
QString folderAlias = alias;
if( alias.isEmpty() ) {
folderAlias = _currentSyncFolder;
}
if( ! folderAlias.isEmpty() && _folderMap.contains(folderAlias) ) {
Folder *f = _folderMap[folderAlias];
if( ! _currentSyncFolder.isEmpty() && _folderMap.contains(_currentSyncFolder) ) {
Folder *f = _folderMap[_currentSyncFolder];
if( f ) {
// This will, indirectly and eventually, call slotFolderSyncFinished
// and thereby clear _currentSyncFolder.
f->slotTerminateSync();
if(_currentSyncFolder == folderAlias ) {
_currentSyncFolder.clear();
}
}
}
}
@@ -489,6 +494,41 @@ void FolderMan::slotScheduleSync( const QString& alias )
QTimer::singleShot(msBetweenRequestAndSync, this, SLOT(slotStartScheduledFolderSync()));
}
void FolderMan::slotScheduleETagJob(const QString &/*alias*/, RequestEtagJob *job)
{
QObject::connect(job, SIGNAL(destroyed(QObject*)), this, SLOT(slotEtagJobDestroyed(QObject*)));
QMetaObject::invokeMethod(this, "slotRunOneEtagJob", Qt::QueuedConnection);
// maybe: add to queue
}
void FolderMan::slotEtagJobDestroyed(QObject* /*o*/)
{
// _currentEtagJob is automatically cleared
// maybe: remove from queue
QMetaObject::invokeMethod(this, "slotRunOneEtagJob", Qt::QueuedConnection);
}
void FolderMan::slotRunOneEtagJob()
{
if (_currentEtagJob.isNull()) {
QString alias;
foreach(Folder *f, _folderMap) {
if (f->etagJob()) {
// Caveat: always grabs the first folder with a job, but we think this is Ok for now and avoids us having a seperate queue.
_currentEtagJob = f->etagJob();
alias = f->alias();
break;
}
}
if (_currentEtagJob.isNull()) {
qDebug() << "No more remote ETag check jobs to schedule.";
} else {
qDebug() << "Scheduling" << alias << "to check remote ETag";
_currentEtagJob->start(); // on destroy/end it will continue the queue via slotEtagJobDestroyed
}
}
}
// only enable or disable foldermans will to schedule and do syncs.
// this is not the same as Pause and Resume of folders.
void FolderMan::setSyncEnabled( bool enabled )
@@ -545,6 +585,51 @@ void FolderMan::slotStartScheduledFolderSync()
}
}
void FolderMan::slotEtagPollTimerTimeout()
{
//qDebug() << Q_FUNC_INFO << "Checking if we need to make any folders check the remote ETag";
MirallConfigFile cfg;
int polltime = cfg.remotePollInterval();
QSet<QString> folderAliases = _folderMap.keys().toSet();
QMutableSetIterator<QString> i(folderAliases);
while (i.hasNext()) {
QString alias = i.next();
if (_currentSyncFolder == alias) {
i.remove();
continue;
}
if (_scheduleQueue.contains(alias)) {
i.remove();
continue;
}
Folder *f = _folderMap.value(alias);
if (f && _disabledFolders.contains(f)) {
i.remove();
continue;
}
if (f && (f->etagJob() || f->isBusy() || f->syncPaused())) {
i.remove();
continue;
}
if (f && f->msecSinceLastSync() < polltime) {
i.remove();
continue;
}
}
if (folderAliases.isEmpty()) {
qDebug() << Q_FUNC_INFO << "No folders need to check for the remote ETag";
} else {
qDebug() << Q_FUNC_INFO << "The following folders need to check for the remote ETag:" << folderAliases;
i = folderAliases; // reset
while (i.hasNext()) {
QString alias = i.next();
QMetaObject::invokeMethod(_folderMap.value(alias), "slotRunEtagJob", Qt::QueuedConnection);
}
}
}
void FolderMan::slotFolderSyncStarted( )
{
qDebug() << ">===================================== sync started for " << _currentSyncFolder;
@@ -615,7 +700,7 @@ void FolderMan::slotRemoveFolder( const QString& alias )
if( _currentSyncFolder == alias ) {
// terminate if the sync is currently underway.
terminateSyncProcess( alias );
terminateSyncProcess();
}
removeFolder(alias);
}
@@ -706,6 +791,8 @@ bool FolderMan::startFromScratch( const QString& localFolder )
if( localFolder.startsWith(f->path()) ) {
_socketApi->slotUnregisterPath(f->alias());
}
f->journalDb()->close();
f->slotTerminateSync(); // Normaly it should not be running, but viel hilft viel
}
}

View File

@@ -108,11 +108,11 @@ public slots:
void slotFolderSyncFinished( const SyncResult& );
/**
* Terminates the specified folder sync (or the current one).
* Terminates the current folder sync.
*
* It does not switch the folder to paused state.
*/
void terminateSyncProcess( const QString& alias = QString::null );
void terminateSyncProcess();
/* unload and delete on folder object */
void unloadFolder( const QString& alias );
@@ -130,11 +130,16 @@ public slots:
// slot to add a folder to the syncing queue
void slotScheduleSync( const QString & );
// slot to scheule an ETag job
void slotScheduleETagJob ( const QString &alias, RequestEtagJob *job);
void slotEtagJobDestroyed (QObject*);
void slotRunOneEtagJob();
private slots:
// slot to take the next folder from queue and start syncing.
void slotStartScheduledFolderSync();
void slotEtagPollTimerTimeout();
private:
// finds all folder configuration files
@@ -153,6 +158,9 @@ private:
QSignalMapper *_folderWatcherSignalMapper;
QString _currentSyncFolder;
bool _syncEnabled;
QTimer _etagPollTimer;
QPointer<RequestEtagJob> _currentEtagJob; // alias of Folder running the current RequestEtagJob
QMap<QString, FolderWatcher*> _folderWatchers;
QPointer<SocketApi> _socketApi;

View File

@@ -71,6 +71,12 @@ bool FolderWatcher::pathIsIgnored( const QString& path )
{
if( path.isEmpty() ) return true;
QFileInfo fInfo(path);
if( fInfo.isHidden() ) {
qDebug() << "* Discarded as is hidden!" << fInfo.filePath();
return true;
}
// Remember: here only directories are checked!
// If that changes to files too at some day, remember to check
// for the database name as well as the trailing slash rule for
@@ -79,12 +85,6 @@ bool FolderWatcher::pathIsIgnored( const QString& path )
QRegExp regexp(pattern);
regexp.setPatternSyntax(QRegExp::Wildcard);
QFileInfo fInfo(path);
if( fInfo.isHidden() ) {
qDebug() << "* Discarded as is hidden!" << fInfo.filePath();
return true;
}
if(pattern.endsWith('/')) {
// directory only pattern. But since only dirs here, we cut off the trailing dir.
pattern.remove(pattern.length()-1, 1); // remove the last char.

View File

@@ -13,6 +13,7 @@
#include <QThread>
#include <QDebug>
#include <QDir>
#include "mirall/folderwatcher.h"
#include "mirall/folderwatcher_win.h"
@@ -23,52 +24,123 @@
namespace Mirall {
void WatcherThread::run()
void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
bool* increaseBufferSize)
{
_handle = FindFirstChangeNotification((wchar_t*)_path.utf16(),
true, // recursive watch
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_LAST_WRITE);
*increaseBufferSize = false;
_handle = CreateFileW(
(wchar_t*)_path.utf16(),
FILE_LIST_DIRECTORY,
FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL
);
if (_handle == INVALID_HANDLE_VALUE)
{
qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification function failed, stopping watcher!";
FindCloseChangeNotification(_handle);
DWORD errorCode = GetLastError();
qDebug() << Q_FUNC_INFO << "Failed to create handle for" << _path << ", error:" << errorCode;
_handle = 0;
return;
}
if (_handle == NULL)
{
qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned null, stopping watcher!";
FindCloseChangeNotification(_handle);
_handle = 0;
return;
}
// QVarLengthArray ensures the stack-buffer is aligned like double and qint64.
QVarLengthArray<char, 4096*10> fileNotifyBuffer;
fileNotifyBuffer.resize(fileNotifyBufferSize);
while(true) {
switch(WaitForSingleObject(_handle, /*wait*/ INFINITE)) {
case WAIT_OBJECT_0:
if (FindNextChangeNotification(_handle) == false) {
qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned FALSE, stopping watcher!";
FindCloseChangeNotification(_handle);
_handle = 0;
return;
const size_t fileNameBufferSize = 4096;
TCHAR fileNameBuffer[fileNameBufferSize];
forever {
FILE_NOTIFY_INFORMATION *pFileNotifyBuffer =
(FILE_NOTIFY_INFORMATION*)fileNotifyBuffer.data();
DWORD dwBytesReturned = 0;
SecureZeroMemory(pFileNotifyBuffer, fileNotifyBufferSize);
if(ReadDirectoryChangesW( _handle, (LPVOID)pFileNotifyBuffer,
fileNotifyBufferSize, true,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_LAST_WRITE,
&dwBytesReturned, NULL, NULL))
{
FILE_NOTIFY_INFORMATION *curEntry = pFileNotifyBuffer;
forever {
size_t len = curEntry->FileNameLength / 2;
QString file = _path + "\\" + QString::fromWCharArray(curEntry->FileName, len);
// Unless the file was removed or renamed, get its full long name
// TODO: We could still try expanding the path in the tricky cases...
QString longfile = file;
if (curEntry->Action != FILE_ACTION_REMOVED
&& curEntry->Action != FILE_ACTION_RENAMED_OLD_NAME) {
size_t longNameSize = GetLongPathNameW(reinterpret_cast<LPCWSTR>(file.utf16()), fileNameBuffer, fileNameBufferSize);
if (longNameSize > 0) {
longfile = QString::fromUtf16(reinterpret_cast<const ushort *>(fileNameBuffer), longNameSize);
} else {
qDebug() << Q_FUNC_INFO << "Error converting file name to full length, keeping original name.";
}
}
longfile = QDir::cleanPath(longfile);
qDebug() << Q_FUNC_INFO << "Found change in" << longfile << "action:" << curEntry->Action;
emit changed(longfile);
if (curEntry->NextEntryOffset == 0) {
break;
}
curEntry = (FILE_NOTIFY_INFORMATION*)(
(char*)curEntry + curEntry->NextEntryOffset);
}
// qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread ();
emit changed(_path);
break;
default:
qDebug() << Q_FUNC_INFO << "Error while watching";
} else {
DWORD errorCode = GetLastError();
switch(errorCode) {
case ERROR_NOTIFY_ENUM_DIR:
qDebug() << Q_FUNC_INFO << "The buffer for changes overflowed! Triggering a generic change and resizing";
emit changed(_path);
*increaseBufferSize = true;
break;
default:
qDebug() << Q_FUNC_INFO << "General error" << errorCode << "while watching. Exiting.";
break;
}
CloseHandle(_handle);
_handle = NULL;
return;
}
}
}
void WatcherThread::run()
{
// If this buffer fills up before we've extracted its data we will lose
// change information. Therefore start big.
size_t bufferSize = 4096*10;
size_t maxBuffer = 64*1024;
forever {
bool increaseBufferSize = false;
watchChanges(bufferSize, &increaseBufferSize);
if (increaseBufferSize) {
bufferSize = qMin(bufferSize*2, maxBuffer);
} else {
// Other errors shouldn't actually happen,
// so sleep a bit to avoid running into the same error case in a
// tight loop.
sleep(2);
}
}
}
WatcherThread::~WatcherThread()
{
if (_handle)
FindCloseChangeNotification(_handle);
if (_handle) {
CloseHandle(_handle);
_handle = NULL;
}
}
FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p, const QString& path)

View File

@@ -33,6 +33,8 @@ public:
protected:
void run();
void watchChanges(size_t fileNotifyBufferSize,
bool* increaseBufferSize);
signals:
void changed(const QString &path);

View File

@@ -254,9 +254,9 @@ void FolderWizardRemotePath::slotAddRemoteFolder()
QInputDialog *dlg = new QInputDialog(this);
dlg->setWindowTitle(tr("Add Remote Folder"));
dlg->setLabelText(tr("Enter the name of the new folder:"));
dlg->setTextValue(parent);
dlg->setWindowTitle(tr("Create Remote Folder"));
dlg->setLabelText(tr("Enter the name of the new folder to be created below '%1':")
.arg(parent));
dlg->open(this, SLOT(slotCreateRemoteFolder(QString)));
dlg->setAttribute(Qt::WA_DeleteOnClose);
}
@@ -265,7 +265,14 @@ void FolderWizardRemotePath::slotCreateRemoteFolder(const QString &folder)
{
if( folder.isEmpty() ) return;
MkColJob *job = new MkColJob(AccountManager::instance()->account(), folder, this);
QTreeWidgetItem *current = _ui.folderTreeWidget->currentItem();
QString fullPath;
if (current) {
fullPath = current->data(0, Qt::UserRole).toString();
}
fullPath += "/" + folder;
MkColJob *job = new MkColJob(AccountManager::instance()->account(), fullPath, this);
/* check the owncloud configuration file and query the ownCloud */
connect(job, SIGNAL(finished(QNetworkReply::NetworkError)),
SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError)));

View File

@@ -137,7 +137,7 @@
<item row="1" column="1">
<widget class="QPushButton" name="addFolderButton">
<property name="text">
<string>Add Folder</string>
<string>Create Folder</string>
</property>
</widget>
</item>

View File

@@ -31,6 +31,7 @@
#include "mirall/networkjobs.h"
#include "mirall/account.h"
#include "mirall/owncloudpropagator.h"
#include "creds/credentialsfactory.h"
#include "creds/abstractcredentials.h"
@@ -50,12 +51,7 @@ AbstractNetworkJob::AbstractNetworkJob(Account *account, const QString &path, QO
, _path(path)
{
_timer.setSingleShot(true);
if (!AbstractNetworkJob::preOc7WasDetected) {
_timer.setInterval(10*1000); // default to 10 seconds.
} else {
qDebug() << "Pre-oc7 server detected, adjusting timeout values";
_timer.setInterval(60*1000); // long PROPFINDs in oc6 might take too long
}
_timer.setInterval(OwncloudPropagator::httpTimeout() * 1000); // default to 5 minutes.
connect(&_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
connect(this, SIGNAL(networkActivity()), SLOT(resetTimeout()));
@@ -104,6 +100,12 @@ void AbstractNetworkJob::setPath(const QString &path)
void AbstractNetworkJob::setupConnections(QNetworkReply *reply)
{
connect(reply, SIGNAL(finished()), SLOT(slotFinished()));
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
connect(reply, SIGNAL(encrypted()), SIGNAL(networkActivity()));
#endif
connect(reply->manager(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SIGNAL(networkActivity()));
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SIGNAL(networkActivity()));
connect(reply, SIGNAL(metaDataChanged()), SIGNAL(networkActivity()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(networkActivity()));
connect(reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(networkActivity()));
}
@@ -164,8 +166,8 @@ void AbstractNetworkJob::slotFinished()
bool discard = finished();
AbstractCredentials *creds = _account->credentials();
if (!creds->stillValid(_reply) &&! _ignoreCredentialFailure
&& _account->state() != Account::InvalidCredidential) {
_account->setState(Account::InvalidCredidential);
&& _account->state() != Account::InvalidCredential) {
_account->setState(Account::InvalidCredential);
// invalidate & forget token/password
// but try to re-sign in.
@@ -382,8 +384,11 @@ void CheckServerJob::start()
void CheckServerJob::slotTimeout()
{
qDebug() << "TIMEOUT" << Q_FUNC_INFO;
if (reply()->isRunning())
if (reply() && reply()->isRunning()) {
emit timeout(reply()->url());
} else if (!reply()) {
qDebug() << Q_FUNC_INFO << "Timeout even there was no reply?";
}
deleteLater();
}

View File

@@ -259,16 +259,17 @@ void ownCloudGui::slotComputeOverallSyncStatus()
// create the tray blob message, check if we have an defined state
if( overallResult.status() != SyncResult::Undefined ) {
QStringList allStatusStrings;
foreach(Folder* folder, map.values()) {
qDebug() << "Folder in overallStatus Message: " << folder << " with name " << folder->alias();
QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncPaused());
allStatusStrings += tr("Folder %1: %2").arg(folder->alias(), folderMessage);
}
if( map.count() > 0 ) {
foreach(Folder* folder, map.values()) {
qDebug() << "Folder in overallStatus Message: " << folder << " with name " << folder->alias();
QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncPaused());
allStatusStrings += tr("Folder %1: %2").arg(folder->alias(), folderMessage);
}
if( ! allStatusStrings.isEmpty() )
trayMessage = allStatusStrings.join(QLatin1String("\n"));
else
} else {
trayMessage = tr("No sync folders configured.");
}
QIcon statusIcon = Theme::instance()->syncStateIcon( overallResult.status(), true);
_tray->setIcon( statusIcon );

View File

@@ -248,13 +248,23 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
if (!removedDirectory.isEmpty() && item._file.startsWith(removedDirectory)) {
// this is an item in a directory which is going to be removed.
PropagateDirectory *delDirJob = dynamic_cast<PropagateDirectory*>(directoriesToRemove.last());
if (item._instruction == CSYNC_INSTRUCTION_REMOVE) {
//already taken care of. (by the removal of the parent directory)
// increase the number of subjobs that would be there.
if( delDirJob ) {
delDirJob->increaseAffectedCount();
}
continue;
} else if (item._instruction == CSYNC_INSTRUCTION_NEW && item._isDirectory) {
// create a new directory within a deleted directory? That can happen if the directory
// etag were not fetched properly on the previous sync because the sync was aborted
// while uploading this directory (which is now removed). We can ignore it.
if( delDirJob ) {
delDirJob->increaseAffectedCount();
}
continue;
} else if (item._instruction == CSYNC_INSTRUCTION_IGNORE) {
continue;

View File

@@ -71,59 +71,6 @@ signals:
};
/*
* Propagate a directory, and all its sub entries.
*/
class PropagateDirectory : public PropagatorJob {
Q_OBJECT
public:
// e.g: create the directory
QScopedPointer<PropagatorJob>_firstJob;
// all the sub files or sub directories.
QVector<PropagatorJob *> _subJobs;
SyncFileItem _item;
int _current; // index of the current running job
int _runningNow; // number of subJob running now
SyncFileItem::Status _hasError; // NoStatus, or NormalError / SoftError if there was an error
explicit PropagateDirectory(OwncloudPropagator *propagator, const SyncFileItem &item = SyncFileItem())
: PropagatorJob(propagator)
, _firstJob(0), _item(item), _current(-1), _runningNow(0), _hasError(SyncFileItem::NoStatus) { }
virtual ~PropagateDirectory() {
qDeleteAll(_subJobs);
}
void append(PropagatorJob *subJob) {
_subJobs.append(subJob);
}
virtual void start() Q_DECL_OVERRIDE;
virtual void abort() Q_DECL_OVERRIDE {
if (_firstJob)
_firstJob->abort();
foreach (PropagatorJob *j, _subJobs)
j->abort();
}
private slots:
void startJob(PropagatorJob *next) {
connect(next, SIGNAL(finished(SyncFileItem::Status)), this, SLOT(slotSubJobFinished(SyncFileItem::Status)), Qt::QueuedConnection);
connect(next, SIGNAL(completed(SyncFileItem)), this, SIGNAL(completed(SyncFileItem)));
connect(next, SIGNAL(progress(SyncFileItem,quint64)), this, SIGNAL(progress(SyncFileItem,quint64)));
connect(next, SIGNAL(ready()), this, SLOT(slotSubJobReady()));
_runningNow++;
QMetaObject::invokeMethod(next, "start", Qt::QueuedConnection);
}
void slotSubJobFinished(SyncFileItem::Status status);
void slotSubJobReady();
};
/*
* Abstract class to propagate a single item
@@ -148,8 +95,6 @@ protected:
_item._errorString = msg;
}
SyncFileItem _item;
protected slots:
void slotRestoreJobCompleted(const SyncFileItem& );
@@ -160,8 +105,69 @@ public:
PropagateItemJob(OwncloudPropagator* propagator, const SyncFileItem &item)
: PropagatorJob(propagator), _item(item) {}
SyncFileItem _item;
};
/*
* Propagate a directory, and all its sub entries.
*/
class PropagateDirectory : public PropagatorJob {
Q_OBJECT
public:
// e.g: create the directory
QScopedPointer<PropagateItemJob>_firstJob;
// all the sub files or sub directories.
QVector<PropagatorJob *> _subJobs;
SyncFileItem _item;
int _current; // index of the current running job
int _runningNow; // number of subJob running now
SyncFileItem::Status _hasError; // NoStatus, or NormalError / SoftError if there was an error
explicit PropagateDirectory(OwncloudPropagator *propagator, const SyncFileItem &item = SyncFileItem())
: PropagatorJob(propagator)
, _firstJob(0), _item(item), _current(-1), _runningNow(0), _hasError(SyncFileItem::NoStatus)
{ }
virtual ~PropagateDirectory() {
qDeleteAll(_subJobs);
}
void append(PropagatorJob *subJob) {
_subJobs.append(subJob);
}
virtual void start() Q_DECL_OVERRIDE;
virtual void abort() Q_DECL_OVERRIDE {
if (_firstJob)
_firstJob->abort();
foreach (PropagatorJob *j, _subJobs)
j->abort();
}
void increaseAffectedCount() {
_firstJob->_item._affectedItems++;
}
private slots:
void startJob(PropagatorJob *next) {
connect(next, SIGNAL(finished(SyncFileItem::Status)), this, SLOT(slotSubJobFinished(SyncFileItem::Status)), Qt::QueuedConnection);
connect(next, SIGNAL(completed(SyncFileItem)), this, SIGNAL(completed(SyncFileItem)));
connect(next, SIGNAL(progress(SyncFileItem,quint64)), this, SIGNAL(progress(SyncFileItem,quint64)));
connect(next, SIGNAL(ready()), this, SLOT(slotSubJobReady()));
_runningNow++;
QMetaObject::invokeMethod(next, "start", Qt::QueuedConnection);
}
void slotSubJobFinished(SyncFileItem::Status status);
void slotSubJobReady();
};
// Dummy job that just mark it as completed and ignored.
class PropagateIgnoreJob : public PropagateItemJob {
Q_OBJECT

View File

@@ -111,6 +111,7 @@ void OwncloudSetupWizard::startWizard()
}
}
_ocWizard->setProperty("oldLocalFolder", localFolder);
_ocWizard->setProperty("localFolder", localFolder);
// remember the local folder to compare later if it changed, but clean first
@@ -145,7 +146,7 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
}
Account *account = _ocWizard->account();
account->setUrl(url);
// Set fake credentials beforfe we check what credidential it actually is.
// Set fake credentials beforfe we check what credential it actually is.
account->setCredentials(CredentialsFactory::create("dummy"));
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), false, this);
job->setIgnoreCredentialFailure(true);
@@ -183,17 +184,17 @@ void OwncloudSetupWizard::slotOwnCloudFoundAuth(const QUrl& url, const QVariantM
void OwncloudSetupWizard::slotNoOwnCloudFoundAuth(QNetworkReply *reply)
{
_ocWizard->displayError(tr("Failed to connect to %1 at %2:<br/>%3")
.arg(Theme::instance()->appNameGUI())
.arg(reply->url().toString())
.arg(reply->errorString()));
.arg(Theme::instance()->appNameGUI(),
reply->url().toString(),
reply->errorString()));
}
void OwncloudSetupWizard::slotNoOwnCloudFoundAuthTimeout(const QUrl&url)
{
_ocWizard->displayError(tr("Failed to connect to %1 at %2:<br/>%3")
.arg(Theme::instance()->appNameGUI())
.arg(url.toString())
.arg("Timeout"));
.arg(Theme::instance()->appNameGUI(),
url.toString(),
"Timeout"));
}
void OwncloudSetupWizard::slotConnectToOCUrl( const QString& url )
@@ -412,7 +413,7 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
Folder *f = folderMan->folderForPath(localFolder);
if( f ) {
folderMan->setSyncEnabled(false);
folderMan->terminateSyncProcess(f->alias());
f->slotTerminateSync();
f->journalDb()->close();
}
@@ -432,6 +433,7 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
}
// 2. Server URL or user changed, requires reinit of folders
else if (reinitRequired) {
folderMan->removeAllFolderDefinitions();
// 2.1: startFromScratch: (Re)move local data, clean slate sync
if (startFromScratch) {
if (ensureStartFromScratch(localFolder)) {
@@ -443,7 +445,6 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
}
// 2.2: Reinit: Remove journal and start a sync
else {
folderMan->removeAllFolderDefinitions();
folderMan->addFolderDefinition(Theme::instance()->appName(),
localFolder, _remoteFolder, _ocWizard->blacklist() );
_ocWizard->appendToConfigurationLog(tr("<font color=\"green\"><b>Local sync folder %1 successfully created!</b></font>").arg(localFolder));

View File

@@ -15,6 +15,7 @@
#include <QDateTime>
#include <QString>
#include <QDebug>
#include <QFile>
#include "ownsql.h"
#include "utility.h"
@@ -40,23 +41,88 @@ bool SqlDatabase::isOpen()
return _db != 0;
}
bool SqlDatabase::open( const QString& filename )
bool SqlDatabase::openHelper( const QString& filename, int sqliteFlags )
{
if(isOpen()) {
if( isOpen() ) {
return true;
}
int flag = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_NOMUTEX;
SQLITE_DO( sqlite3_open_v2(filename.toUtf8().constData(), &_db, flag, 0) );
sqliteFlags |= SQLITE_OPEN_NOMUTEX;
SQLITE_DO( sqlite3_open_v2(filename.toUtf8().constData(), &_db, sqliteFlags, 0) );
if( _errId != SQLITE_OK ) {
close(); // FIXME: Correct?
_db = 0;
qDebug() << "Error:" << _error << "for" << filename;
close();
return false;
}
if( !_db ) {
qDebug() << "Error: no database for" << filename;
return false;
}
sqlite3_busy_timeout(_db, 5000);
return isOpen();
return true;
}
bool SqlDatabase::checkDb()
{
SqlQuery quick_check("PRAGMA quick_check;", *this);
if( !quick_check.exec() ) {
qDebug() << "Error running quick_check on database";
return false;
}
quick_check.next();
QString result = quick_check.stringValue(0);
if( result != "ok" ) {
qDebug() << "quick_check returned failure:" << result;
return false;
}
return true;
}
bool SqlDatabase::openOrCreateReadWrite( const QString& filename )
{
if( isOpen() ) {
return true;
}
if( !openHelper(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) ) {
return false;
}
if( !checkDb() ) {
qDebug() << "Consistency check failed, removing broken db" << filename;
close();
QFile::remove(filename);
return openHelper(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
}
return true;
}
bool SqlDatabase::openReadOnly( const QString& filename )
{
if( isOpen() ) {
return true;
}
if( !openHelper(filename, SQLITE_OPEN_READONLY) ) {
return false;
}
if( !checkDb() ) {
qDebug() << "Consistency check failed in readonly mode, giving up" << filename;
close();
return false;
}
return true;
}
QString SqlDatabase::error() const

View File

@@ -30,7 +30,8 @@ public:
explicit SqlDatabase();
bool isOpen();
bool open( const QString& filename );
bool openOrCreateReadWrite( const QString& filename );
bool openReadOnly( const QString& filename );
bool transaction();
bool commit();
void close();
@@ -38,6 +39,9 @@ public:
sqlite3* sqliteDb();
private:
bool openHelper( const QString& filename, int sqliteFlags );
bool checkDb();
sqlite3 *_db;
QString _error; // last error string
int _errId;

View File

@@ -20,6 +20,8 @@
#include <QTime>
#include <QQueue>
#include <QElapsedTimer>
#include <QDebug>
#include "syncfileitem.h"
namespace Mirall {
@@ -112,12 +114,12 @@ namespace Progress
void setProgressComplete(const SyncFileItem &item) {
_currentItems.remove(item._file);
_completedFileCount += item._affectedItems;
if (!item._isDirectory) {
_completedFileCount++;
if (Progress::isSizeDependent(item._instruction)) {
_completedSize += item._size;
}
}
if (Progress::isSizeDependent(item._instruction)) {
_completedSize += item._size;
}
}
_lastCompletedItem = item;
this->updateEstimation();
}

View File

@@ -95,6 +95,12 @@ void PropagateUploadFileLegacy::start()
state = hbf_splitlist(trans.data(), file.handle());
// This is the modtime hbf will announce to the server.
// We don't trust the modtime hbf computes itself via _fstat64
// on windows - hbf may only use it to detect file changes during
// upload.
trans->oc_header_modtime = FileSystem::getModTime(file.fileName());
// If the source file has changed during upload, it is detected and the
// variable _previousFileSize is set accordingly. The propagator waits a
// couple of seconds and retries.
@@ -105,7 +111,7 @@ void PropagateUploadFileLegacy::start()
Q_ARG(qint64, trans->stat_size - _previousFileSize));
// update the item's values to the current from trans. hbf_splitlist does a stat
_item._size = trans->stat_size;
_item._modtime = trans->modtime;
_item._modtime = trans->oc_header_modtime;
}
emit progress(_item, 0);
@@ -185,7 +191,7 @@ void PropagateUploadFileLegacy::start()
if( trans->modtime_accepted ) {
_item._etag = parseEtag(hbf_transfer_etag( trans.data() ));
} else {
if (!updateMTimeAndETag(uri.data(), _item._modtime))
if (!updateMTimeAndETag(uri.data(), trans->oc_header_modtime))
return;
}
@@ -242,7 +248,7 @@ void PropagateUploadFileLegacy::chunk_finished_cb(hbf_transfer_s *trans, int chu
pi._valid = true;
pi._chunk = chunk + 1; // next chunk to start with
pi._transferid = trans->transfer_id;
pi._modtime = Utility::qDateTimeFromTime_t(trans->modtime);
pi._modtime = Utility::qDateTimeFromTime_t(trans->oc_header_modtime);
that->_propagator->_journal->setUploadInfo(that->_item._file, pi);
that->_propagator->_journal->commit("Upload info");
}

View File

@@ -228,6 +228,7 @@ void PropagateUploadFileQNAM::startNextChunk()
quint64 fileSize = _item._size;
QMap<QByteArray, QByteArray> headers;
headers["OC-Total-Length"] = QByteArray::number(fileSize);
headers["OC-Chunk-Size"]= QByteArray::number(quint64(chunkSize()));
headers["Content-Type"] = "application/octet-stream";
headers["X-OC-Mtime"] = QByteArray::number(qint64(_item._modtime));
if (!_item._etag.isEmpty() && _item._etag != "empty_etag" &&
@@ -265,7 +266,6 @@ void PropagateUploadFileQNAM::startNextChunk()
if( isOpen ) {
_job = new PUTFileJob(AccountManager::instance()->account(), _propagator->_remoteFolder + path, device, headers);
_job->setTimeout(_propagator->httpTimeout() * 1000);
connect(_job, SIGNAL(finishedSignal()), this, SLOT(slotPutFinished()));
connect(_job, SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(slotUploadProgress(qint64,qint64)));
_job->start();
@@ -679,7 +679,6 @@ void PropagateDownloadFileQNAM::start()
url,
&_tmpFile, headers);
}
_job->setTimeout(_propagator->httpTimeout() * 1000);
connect(_job, SIGNAL(finishedSignal()), this, SLOT(slotGetFinished()));
connect(_job, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(slotDownloadProgress(qint64,qint64)));
_propagator->_activeJobs ++;
@@ -742,6 +741,21 @@ void PropagateDownloadFileQNAM::slotGetFinished()
_tmpFile.close();
_tmpFile.flush();
/* Check that the size of the GET reply matches the file size. There have been cases
* reported that if a server breaks behind a proxy, the GET is still a 200 but is
* truncated, as described here: https://github.com/owncloud/mirall/issues/2528
*/
const QByteArray sizeHeader("Content-Length");
quint64 bodySize = job->reply()->rawHeader(sizeHeader).toULongLong();
if(bodySize > 0 && bodySize != _tmpFile.size() - job->resumeStart() ) {
qDebug() << bodySize << _tmpFile.size() << job->resumeStart();
_propagator->_anotherSyncNeeded = true;
done(SyncFileItem::SoftError, tr("The file could not be downloaded completely."));
return;
}
downloadFinished();
}
@@ -771,10 +785,18 @@ void PropagateDownloadFileQNAM::downloadFinished()
QString fn = _propagator->getFilePath(_item._file);
// In case of file name clash, report an error
// This can happen if another parallel download saved a clashing file.
if (_propagator->localFileNameClash(_item._file)) {
done( SyncFileItem::NormalError, tr("File %1 cannot be saved because of a local file name clash!")
.arg(QDir::toNativeSeparators(_item._file)) );
return;
}
// In case of conflict, make a backup of the old file
// Ignore conflicts where both files are binary equal
bool isConflict = _item._instruction == CSYNC_INSTRUCTION_CONFLICT
&& !FileSystem::fileEquals(fn, _tmpFile.fileName()); // compare the files to see if there was an actual conflict.
//In case of conflict, make a backup of the old file
&& !FileSystem::fileEquals(fn, _tmpFile.fileName());
if (isConflict) {
QFile f(fn);
QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item._modtime));
@@ -794,6 +816,19 @@ void PropagateDownloadFileQNAM::downloadFinished()
QString error;
if (!FileSystem::renameReplace(_tmpFile.fileName(), fn, &error)) {
// If we moved away the original file due to a conflict but can't
// put the downloaded file in its place, we are in a bad spot:
// If we do nothing the next sync run will assume the user deleted
// the file!
// To avoid that, the file is removed from the metadata table entirely
// which makes it look like we're just about to initially download
// it.
if (isConflict) {
_propagator->_journal->deleteFileRecord(fn);
_propagator->_journal->commit("download finished");
_propagator->_anotherSyncNeeded = true;
}
done(SyncFileItem::NormalError, error);
return;
}

View File

@@ -50,7 +50,8 @@
namespace Mirall {
// Code copied from Qt5's QDir::removeRecursively
static bool removeRecursively(const QString &path)
// (and modified to report the error)
static bool removeRecursively(const QString &path, QString &error)
{
bool success = true;
QDirIterator di(path, QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot);
@@ -58,15 +59,28 @@ static bool removeRecursively(const QString &path)
di.next();
const QFileInfo& fi = di.fileInfo();
bool ok;
if (fi.isDir() && !fi.isSymLink())
ok = removeRecursively(di.filePath()); // recursive
else
ok = QFile::remove(di.filePath());
if (fi.isDir() && !fi.isSymLink()) {
ok = removeRecursively(di.filePath(), error); // recursive
} else {
QFile f(di.filePath());
ok = f.remove();
if (!ok) {
error += PropagateLocalRemove::tr("Error removing '%1': %2; ").
arg(QDir::toNativeSeparators(f.fileName()), f.errorString());
qDebug() << "Error removing " << f.fileName() << ':' << f.errorString();
}
}
if (!ok)
success = false;
}
if (success)
if (success) {
success = QDir().rmdir(path);
if (!success) {
error += PropagateLocalRemove::tr("Could not remove directory '%1'; ")
.arg(QDir::toNativeSeparators(path));
qDebug() << "Error removing directory" << path;
}
}
return success;
}
@@ -83,9 +97,9 @@ void PropagateLocalRemove::start()
}
if (_item._isDirectory) {
if (QDir(filename).exists() && !removeRecursively(filename)) {
done(SyncFileItem::NormalError, tr("Could not remove directory %1")
.arg(QDir::toNativeSeparators(filename)));
QString error;
if (QDir(filename).exists() && !removeRecursively(filename, error)) {
done(SyncFileItem::NormalError, error);
return;
}
} else {

View File

@@ -65,9 +65,9 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
connect(this, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
_clearBlacklistBtn = _ui->_dialogButtonBox->addButton(tr("Retry Sync"), QDialogButtonBox::ActionRole);
_clearBlacklistBtn->setEnabled(false);
connect(_clearBlacklistBtn, SIGNAL(clicked()), SLOT(slotClearBlacklist()));
_retrySyncBtn = _ui->_dialogButtonBox->addButton(tr("Retry Sync"), QDialogButtonBox::ActionRole);
_retrySyncBtn->setEnabled(false);
connect(_retrySyncBtn, SIGNAL(clicked()), SLOT(slotRetrySync()));
_copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
_copyBtn->setToolTip( tr("Copy the activity list to the clipboard."));
@@ -118,7 +118,7 @@ void ProtocolWidget::copyToClipboard()
emit guiLog(tr("Copied to clipboard"), tr("The sync status has been copied to the clipboard."));
}
void ProtocolWidget::slotClearBlacklist()
void ProtocolWidget::slotRetrySync()
{
FolderMan *folderMan = FolderMan::instance();
@@ -126,7 +126,12 @@ void ProtocolWidget::slotClearBlacklist()
foreach( Folder *f, folders ) {
int num = f->slotWipeBlacklist();
qDebug() << num << "entries were removed from"<< f->alias() << "blacklist";
qDebug() << num << "entries were removed from"
<< f->alias() << "blacklist";
num = f->slotDiscardDownloadProgress();
qDebug() << num << "temporary files with partial downloads"
<< "were removed from" << f->alias();
}
folderMan->slotScheduleAllFolders();
@@ -247,18 +252,23 @@ void ProtocolWidget::computeResyncButtonEnabled()
FolderMan *folderMan = FolderMan::instance();
Folder::Map folders = folderMan->map();
int cnt = 0;
int blacklist_cnt = 0;
int downloads_cnt = 0;
foreach( Folder *f, folders ) {
cnt += f->blackListEntryCount();
blacklist_cnt += f->blackListEntryCount();
downloads_cnt += f->downloadInfoCount();
}
QString t = tr("Currently no files are ignored because of previous errors.");
if(cnt > 0) {
t = tr("%n files are ignored because of previous errors.\n Try to sync these again.", 0, cnt);
QString t = tr("Currently no files are ignored because of previous errors and no downloads are in progress.");
bool enabled = blacklist_cnt > 0 || downloads_cnt > 0;
if (enabled) {
t = tr("%n files are ignored because of previous errors.\n", 0, blacklist_cnt)
+ tr("%n files are partially downloaded.\n", 0, downloads_cnt)
+ tr("Try to sync these again.");
}
_clearBlacklistBtn->setEnabled(cnt > 0);
_clearBlacklistBtn->setToolTip(t);
_retrySyncBtn->setEnabled(enabled);
_retrySyncBtn->setToolTip(t);
}

View File

@@ -47,7 +47,7 @@ public slots:
protected slots:
void copyToClipboard();
void slotClearBlacklist();
void slotRetrySync();
signals:
void guiLog(const QString&, const QString&);
@@ -65,7 +65,7 @@ private:
const int IgnoredIndicatorRole;
Ui::ProtocolWidget *_ui;
QPushButton *_clearBlacklistBtn;
QPushButton *_retrySyncBtn;
QPushButton *_copyBtn;
};

View File

@@ -51,7 +51,7 @@ void QuotaInfo::slotAccountStateChanged(int state)
{
switch (state) {
case Account::SignedOut: // fall through
case Account::InvalidCredidential:
case Account::InvalidCredential:
case Account::Disconnected:
_jobRestartTimer->stop();
break;

View File

@@ -271,7 +271,9 @@ void SelectiveSyncDialog::init(Account *account)
setWindowTitle(tr("Choose What to Sync"));
QVBoxLayout *layout = new QVBoxLayout(this);
_treeView = new SelectiveSyncTreeView(account, this);
layout->addWidget(new QLabel(tr("Unchecked folders will not be sync to this computer")));
QLabel *label = new QLabel(tr("Unchecked folders will be <b>removed</b> from your local file system and will not be synchronized to this computer anymore"));
label->setWordWrap(true);
layout->addWidget(label);
layout->addWidget(_treeView);
QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal);
QPushButton *button;

View File

@@ -1,3 +1,16 @@
/*
* Copyright (C) by Denis Dzyubenko
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "settingsdialogmac.h"
#include "macstandardicon.h"

View File

@@ -1,3 +1,17 @@
/*
* Copyright (C) by Denis Dzyubenko
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef SETTINGSDIALOGMAC_H
#define SETTINGSDIALOGMAC_H

View File

@@ -94,6 +94,11 @@ SocketApi::SocketApi(QObject* parent)
runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
#else
runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
if (runtimeDir.isEmpty()) {
runtimeDir = QDir::tempPath() + QLatin1String("/runtime-")
+ QString::fromLocal8Bit(qgetenv("USER"));
QDir().mkdir(runtimeDir);
}
#endif
socketPath = runtimeDir + "/" + Theme::instance()->appName() + "/socket";
} else {
@@ -417,7 +422,7 @@ SqlQuery* SocketApi::getSqlQuery( Folder *folder )
if( fi.exists() ) {
SqlDatabase *db = new SqlDatabase;
if( db && db->open(dbFileName) ) {
if( db && db->openReadOnly(dbFileName) ) {
_openDbs.insert(folder, db);
SqlQuery *query = new SqlQuery(*db);
@@ -430,6 +435,8 @@ SqlQuery* SocketApi::getSqlQuery( Folder *folder )
}
_dbQueries.insert( folder, query);
return query;
} else {
qDebug() << "Unable to open db" << dbFileName;
}
} else {
qDebug() << Q_FUNC_INFO << "Journal to query does not yet exist.";

View File

@@ -179,7 +179,9 @@ QString SyncEngine::csyncErrorToString(CSYNC_STATUS err)
case CSYNC_STATUS_ABORTED:
errStr = tr("Aborted by the user");
break;
case CSYNC_STATUS_SERVICE_UNAVAILABLE:
errStr = tr("The mounted directory is temporary not available on the server");
break;
default:
errStr = tr("An internal error number %1 happened.").arg( (int) err );
}
@@ -325,7 +327,9 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
item._modtime = file->modtime;
} else {
if (file->instruction != CSYNC_INSTRUCTION_NONE) {
qDebug() << "ERROR: Instruction" << item._instruction << "vs" << file->instruction << "for" << fileUtf8;
Q_ASSERT(!"Instructions are both unequal NONE");
return -1;
}
}
@@ -368,12 +372,19 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
case CYSNC_STATUS_FILE_LOCKED_OR_OPEN:
item._errorString = QLatin1String("File locked"); // don't translate, internal use!
break;
case CSYNC_STATUS_SERVICE_UNAVAILABLE:
item._errorString = QLatin1String("Directory temporarily not available on server.");
item._status = SyncFileItem::SoftError;
break;
default:
Q_ASSERT("Non handled error-status");
/* No error string */
}
item._isDirectory = file->type == CSYNC_FTW_TYPE_DIR;
if(item._isDirectory) {
item._affectedItems = 0; // defaults to 1 for normal items.
}
// The etag is already set in the previous sync phases somewhere. Maybe we should remove it there
// and do it here so we have a consistent state about which tree stores information from which source.
@@ -404,12 +415,17 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE:
if (remote && item._should_update_etag && !item._isDirectory && item._instruction == CSYNC_INSTRUCTION_NONE) {
// Update the database now already (new fileid or etag or remotePerm)
// Those are files that were detected as "resolved conflict".
// Update the database now already: New fileid or Etag or RemotePerm
// Or for files that were detected as "resolved conflict".
// They should have been a conflict because they both were new, or both
// had their local mtime or remote etag modified, but the size and mtime
// is the same on the server. This typically happen when the database is removed.
// Nothing will be done for those file, but we still need to update the database.
// 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;
_journal->setFileRecord(SyncJournalFileRecord(item, _localPath + item._file));
item._should_update_etag = false;
}
@@ -532,6 +548,14 @@ void SyncEngine::startSync()
qDebug() << "=====sync with existing DB";
}
qDebug() << "=====Using Qt" << qVersion();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
qDebug() << "=====Using SSL library version"
<< QSslSocket::sslLibraryVersionString().toUtf8().data();
#endif
// Note that this seems to output the OpenSSL build version not runtime version:
qDebug() << "=====Using" << ne_version_string();
fileRecordCount = _journal->getFileRecordCount(); // this creates the DB if it does not exist yet
bool isUpdateFrom_1_5 = _journal->isUpdateFrom_1_5();

View File

@@ -53,7 +53,10 @@ public:
SyncFileItem() : _type(UnknownType), _direction(None), _isDirectory(false),
_instruction(CSYNC_INSTRUCTION_NONE), _modtime(0),
_size(0), _inode(0), _should_update_etag(false), _hasBlacklistEntry(false),
_status(NoStatus), _httpErrorCode(0), _requestDuration(0), _isRestoration(false) {}
_status(NoStatus), _httpErrorCode(0), _requestDuration(0), _isRestoration(false),
_affectedItems(1)
{
}
friend bool operator==(const SyncFileItem& item1, const SyncFileItem& item2) {
return item1._file == item2._file;
@@ -111,7 +114,8 @@ public:
QString _responseTimeStamp;
quint64 _requestDuration;
bool _isRestoration; // The original operation was forbidden, and this is a restoration
int _affectedItems; // the number of affected items by the operation on this item.
// usually this value is 1, but for removes on dirs, it might be much higher.
struct {
quint64 _size;
time_t _modtime;

View File

@@ -120,7 +120,7 @@ bool SyncJournalDb::checkConnect()
bool isNewDb = !QFile::exists(_dbFile);
// The database file is created by this call (SQLITE_OPEN_CREATE)
if( !_db.open(_dbFile) ) {
if( !_db.openOrCreateReadWrite(_dbFile) ) {
QString error = _db.error();
qDebug() << "Error opening the db: " << error;
return false;
@@ -158,11 +158,6 @@ bool SyncJournalDb::checkConnect()
return sqlFail("Set PRAGMA case_sensitivity", pragma1);
}
// Hide 'em all!
FileSystem::setFileHidden(databaseFilePath(), true);
FileSystem::setFileHidden(databaseFilePath() + "-wal", true);
FileSystem::setFileHidden(databaseFilePath() + "-shm", true);
/* Because insert are so slow, e do everything in a transaction, and one need to call commit */
startTransaction();
@@ -335,6 +330,11 @@ bool SyncJournalDb::checkConnect()
// don't start a new transaction now
commitInternal(QString("checkConnect End"), false);
// Hide 'em all!
FileSystem::setFileHidden(databaseFilePath(), true);
FileSystem::setFileHidden(databaseFilePath() + "-wal", true);
FileSystem::setFileHidden(databaseFilePath() + "-shm", true);
return rc;
}
@@ -807,6 +807,24 @@ QVector<SyncJournalDb::DownloadInfo> SyncJournalDb::getAndDeleteStaleDownloadInf
return deleted_entries;
}
int SyncJournalDb::downloadInfoCount()
{
int re = 0;
QMutexLocker locker(&_mutex);
if( checkConnect() ) {
SqlQuery query("SELECT count(*) FROM downloadinfo", _db);
if( ! query.exec() ) {
sqlFail("Count number of downloadinfo entries failed", query);
}
if( query.next() ) {
re = query.intValue(0);
}
}
return re;
}
SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString& file)
{
QMutexLocker locker(&_mutex);

View File

@@ -72,6 +72,7 @@ public:
DownloadInfo getDownloadInfo(const QString &file);
void setDownloadInfo(const QString &file, const DownloadInfo &i);
QVector<DownloadInfo> getAndDeleteStaleDownloadInfos(const QSet<QString>& keep);
int downloadInfoCount();
UploadInfo getUploadInfo(const QString &file);
void setUploadInfo(const QString &file, const UploadInfo &i);
@@ -142,10 +143,12 @@ private:
QList<QString> _avoidReadFromDbOnNextSyncFilter;
};
bool operator==(const SyncJournalDb::DownloadInfo & lhs,
const SyncJournalDb::DownloadInfo & rhs);
bool operator==(const SyncJournalDb::UploadInfo & lhs,
const SyncJournalDb::UploadInfo & rhs);
bool OWNCLOUDSYNC_EXPORT
operator==(const SyncJournalDb::DownloadInfo & lhs,
const SyncJournalDb::DownloadInfo & rhs);
bool OWNCLOUDSYNC_EXPORT
operator==(const SyncJournalDb::UploadInfo & lhs,
const SyncJournalDb::UploadInfo & rhs);
} // namespace Mirall
#endif // SYNCJOURNALDB_H

View File

@@ -43,8 +43,9 @@ public:
int _mode;
};
bool operator==(const SyncJournalFileRecord & lhs,
const SyncJournalFileRecord & rhs);
bool OWNCLOUDSYNC_EXPORT
operator==(const SyncJournalFileRecord & lhs,
const SyncJournalFileRecord & rhs);
class SyncJournalBlacklistRecord
{

View File

@@ -138,7 +138,7 @@ void help()
std::cout << binaryName << " - command line " APPLICATION_NAME " client tool" << std::endl;
std::cout << "" << std::endl;
std::cout << "Usage: " << binaryName << " <sourcedir> <owncloudurl>" << std::endl;
std::cout << "Usage: " << binaryName << " [OPTION] <source_dir> <server_url>" << std::endl;
std::cout << "" << std::endl;
std::cout << "A proxy can either be set manually using --httpproxy or it" << std::endl;
std::cout << "uses the setting from a configured sync client." << std::endl;

View File

@@ -98,7 +98,7 @@ void OwncloudAdvancedSetupPage::initializePage()
_checking = false;
_multipleFoldersExist = false;
_oldLocalFolder = localFolder();
_oldLocalFolder = wizard()->property("oldLocalFolder").toString();
// call to init label
updateStatus();
@@ -152,7 +152,8 @@ bool OwncloudAdvancedSetupPage::dataChanged()
Account *oldAccount = AccountManager::instance()->account();
if (!ocWizard || !oldAccount) {
return false;
// If there was no account configured before, the data is new (hence changed)
return true;
}
const QString url(field("OCUrl").toString());

View File

@@ -224,7 +224,7 @@ void OwncloudSetupPage::setErrorString( const QString& err )
_ui.errorLabel->setVisible(false);
} else {
if (_ui.leUrl->text().startsWith("https://")) {
QString msg = tr("Could not connect securely. Do you want to connect unencrypted instead (not recommended)?").arg(err);
QString msg = tr("<p>Could not connect securely:</p><p>%1</p><p>Do you want to connect unencrypted instead (not recommended)?</p>").arg(err);
QString title = tr("Connection failed");
if (QMessageBox::question(this, title, msg, QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
QUrl url(_ui.leUrl->text());

View File

@@ -71,18 +71,7 @@ bool OwncloudWizardResultPage::isComplete() const
void OwncloudWizardResultPage::initializePage()
{
const QString localFolder = wizard()->property("localFolder").toString();
QString text;
if( _remoteFolder == QLatin1String("/") || _remoteFolder.isEmpty() ) {
text = tr("Your entire account is synced to the local folder <i>%1</i>")
.arg(QDir::toNativeSeparators(localFolder));
} else {
text = tr("%1 folder <i>%1</i> is synced to local folder <i>%2</i>")
.arg(Theme::instance()->appNameGUI())
.arg(_remoteFolder).arg(QDir::toNativeSeparators(localFolder));
}
_ui.localFolderLabel->setText( text );
_ui.localFolderLabel->setText( QString::null );
}
void OwncloudWizardResultPage::setRemoteFolder(const QString &remoteFolder)

View File

@@ -27,8 +27,8 @@ endif(UNIX AND NOT APPLE)
owncloud_add_test(CSyncSqlite "")
owncloud_add_test(NetrcParser ../src/owncloudcmd/netrcparser.cpp)
owncloud_add_test(OwnSql ../src/mirall/ownsql.cpp)
owncloud_add_test(SyncJournalDB ../src/mirall/syncjournaldb.cpp)
owncloud_add_test(OwnSql "")
owncloud_add_test(SyncJournalDB "")

View File

@@ -8,6 +8,7 @@
#define MIRALL_TESTCSYNCSQLITE_H
#include "csync_statedb.h"
#include "csync_private.h"
#include <QtTest>
@@ -16,39 +17,12 @@ class TestCSyncSqlite : public QObject
Q_OBJECT
private:
/* Attention !!!!!!!!!!!!!!!!!!!
* This struct MY_CSYNC has to be a copy of the CSYNC struct defined
* in csync_private.h until the end of struct statedb.
* Subsequent functions cast the struct to CSYNC. In order to get the
* same values as in the original struct, the start must be the same.
*/
typedef struct {
struct {
csync_auth_callback auth_function;
void *userdata;
csync_update_callback update_callback;
void *update_callback_userdata;
} callbacks;
c_strlist_t *excludes;
struct {
char *file;
sqlite3 *db;
int exists;
int disabled;
sqlite3_stmt* by_hash_stmt;
sqlite3_stmt* by_fileid_stmt;
sqlite3_stmt* by_inode_stmt;
} statedb;
} MY_CSYNC;
MY_CSYNC _ctx;
CSYNC _ctx;
private slots:
void initTestCase() {
int rc;
memset(&_ctx, 0, sizeof(MY_CSYNC));
memset(&_ctx, 0, sizeof(CSYNC));
_ctx.statedb.file = c_strdup("./test_journal.db");

View File

@@ -10,7 +10,7 @@
#include <QtTest>
#include "mirall/folderwatcher_linux.h"
#include "mirall/folderwatcher.h"
#include "mirall/utility.h"
using namespace Mirall;
@@ -21,9 +21,12 @@ class TestFolderWatcher : public QObject
public slots:
void slotFolderChanged( const QString& path ) {
qDebug() << "COMPARE: " << path << _checkMark;
QVERIFY(_checkMark == path);
_checkMark.clear();
if (_skipNotifications.contains(path)) {
return;
}
if (_requiredNotifications.contains(path)) {
_receivedNotifications.insert(path);
}
}
void slotEnd() { // in case something goes wrong...
@@ -36,7 +39,16 @@ private:
FolderWatcher *_watcher;
QEventLoop _loop;
QTimer _timer;
QString _checkMark;
QSet<QString> _requiredNotifications;
QSet<QString> _receivedNotifications;
QSet<QString> _skipNotifications;
void processAndWait()
{
_loop.processEvents();
Utility::usleep(200000);
_loop.processEvents();
}
private slots:
void initTestCase() {
@@ -52,68 +64,95 @@ private slots:
rootDir.mkpath(_root + "/a2/b3/c3");
Utility::writeRandomFile( _root+"/a1/random.bin");
Utility::writeRandomFile( _root+"/a1/b2/todelete.bin");
Utility::writeRandomFile( _root+"/a2/movefile");
Utility::writeRandomFile( _root+"/a2/renamefile");
Utility::writeRandomFile( _root+"/a1/movefile");
_watcher = new FolderWatcher(_root);
QObject::connect(_watcher, SIGNAL(folderChanged(QString)), this, SLOT(slotFolderChanged(QString)));
_timer.singleShot(3000, this, SLOT(slotEnd()));
_timer.singleShot(5000, this, SLOT(slotEnd()));
}
void init()
{
_receivedNotifications.clear();
_requiredNotifications.clear();
_skipNotifications.clear();
}
void checkNotifications()
{
processAndWait();
QCOMPARE(_receivedNotifications, _requiredNotifications);
}
void testACreate() { // create a new file
QString cmd;
_checkMark = _root;
_requiredNotifications.insert(_root);
cmd = QString("echo \"xyz\" > %1/foo.txt").arg(_root);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
_loop.processEvents();
QVERIFY(_checkMark.isEmpty()); // the slot clears the checkmark.
checkNotifications();
}
void testATouch() { // touch an existing file.
_requiredNotifications.insert(_root+"/a1");
#ifdef Q_OS_WIN
Utility::writeRandomFile(QString("%1/a1/random.bin").arg(_root));
#else
QString cmd;
cmd = QString("/usr/bin/touch %1/a1/random.bin").arg(_root);
_checkMark = _root+"/a1";
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
#endif
_loop.processEvents();
QVERIFY(_checkMark.isEmpty()); // the slot clears the checkmark.
checkNotifications();
}
void testCreateADir() {
_checkMark = _root+"/a1/b1";
_requiredNotifications.insert(_root+"/a1/b1");
_skipNotifications.insert(_root + "/a1/b1/new_dir");
QDir dir;
dir.mkdir( _root + "/a1/b1/new_dir");
QVERIFY(QFile::exists(_root + "/a1/b1/new_dir"));
_loop.processEvents();
QVERIFY(_checkMark.isEmpty()); // the slot clears the checkmark.
checkNotifications();
}
void testRemoveADir() {
_checkMark = _root+"/a1/b3";
_requiredNotifications.insert(_root+"/a1/b3");
QDir dir;
QVERIFY(dir.rmdir(_root+"/a1/b3/c3"));
_loop.processEvents();
QVERIFY(_checkMark.isEmpty()); // the slot clears the checkmark.
checkNotifications();
}
void testRemoveAFile() {
_checkMark = _root+"/a1/b2";
_requiredNotifications.insert(_root+"/a1/b2");
QVERIFY(QFile::exists(_root+"/a1/b2/todelete.bin"));
QFile::remove(_root+"/a1/b2/todelete.bin");
QVERIFY(!QFile::exists(_root+"/a1/b2/todelete.bin"));
_loop.processEvents();
QVERIFY(_checkMark.isEmpty()); // the slot clears the checkmark.
checkNotifications();
}
void testRenameAFile() {
_requiredNotifications.insert(_root+"/a2");
QVERIFY(QFile::exists(_root+"/a2/renamefile"));
QFile::rename(_root+"/a2/renamefile", _root+"/a2/renamefile.renamed" );
QVERIFY(QFile::exists(_root+"/a2/renamefile.renamed"));
checkNotifications();
}
void testMoveAFile() {
_checkMark = _root+"/a2";
QVERIFY(QFile::exists(_root+"/a2/movefile"));
QFile::rename(_root+"/a2/movefile", _root+"/a2/movefile.renamed" );
_requiredNotifications.insert(_root+"/a1");
_requiredNotifications.insert(_root+"/a2");
QVERIFY(QFile::exists(_root+"/a1/movefile"));
QFile::rename(_root+"/a1/movefile", _root+"/a2/movefile.renamed" );
QVERIFY(QFile::exists(_root+"/a2/movefile.renamed"));
_loop.processEvents();
QVERIFY(_checkMark.isEmpty()); // the slot clears the checkmark.
checkNotifications();
}
void cleanupTestCase() {

View File

@@ -42,7 +42,7 @@ private slots:
void testOpenDb() {
QFileInfo fi( testdbC );
QVERIFY( !fi.exists() ); // must not exist
_db.open(testdbC);
_db.openOrCreateReadWrite(testdbC);
fi.refresh();
QVERIFY(fi.exists());

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -36,8 +36,8 @@
</message>
<message>
<location filename="../src/mirall/folderwizardtargetpage.ui" line="140"/>
<source>Add Folder</source>
<translation>Mappa hozzáadása</translation>
<source>Create Folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderwizardtargetpage.ui" line="160"/>
@@ -288,126 +288,126 @@ Total time left %5</source>
<context>
<name>Mirall::Folder</name>
<message>
<location filename="../src/mirall/folder.cpp" line="112"/>
<location filename="../src/mirall/folder.cpp" line="106"/>
<source>Unable to create csync-context</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="166"/>
<location filename="../src/mirall/folder.cpp" line="160"/>
<source>Local folder %1 does not exist.</source>
<translation>%1 helyi mappa nem létezik.</translation>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="169"/>
<location filename="../src/mirall/folder.cpp" line="163"/>
<source>%1 should be a directory but is not.</source>
<translation>%1 könyvtár kell legyen, de nem az.</translation>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="172"/>
<location filename="../src/mirall/folder.cpp" line="166"/>
<source>%1 is not readable.</source>
<translation>%1 nem olvasható.</translation>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="354"/>
<location filename="../src/mirall/folder.cpp" line="364"/>
<source>%1: %2</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="445"/>
<location filename="../src/mirall/folder.cpp" line="455"/>
<source>%1 and %2 other files have been removed.</source>
<comment>%1 names a file.</comment>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="447"/>
<location filename="../src/mirall/folder.cpp" line="457"/>
<source>%1 has been removed.</source>
<comment>%1 names a file.</comment>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="452"/>
<location filename="../src/mirall/folder.cpp" line="462"/>
<source>%1 and %2 other files have been downloaded.</source>
<comment>%1 names a file.</comment>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="454"/>
<location filename="../src/mirall/folder.cpp" line="464"/>
<source>%1 has been downloaded.</source>
<comment>%1 names a file.</comment>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="459"/>
<location filename="../src/mirall/folder.cpp" line="469"/>
<source>%1 and %2 other files have been updated.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="461"/>
<location filename="../src/mirall/folder.cpp" line="471"/>
<source>%1 has been updated.</source>
<comment>%1 names a file.</comment>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="466"/>
<location filename="../src/mirall/folder.cpp" line="476"/>
<source>%1 has been renamed to %2 and %3 other files have been renamed.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="468"/>
<location filename="../src/mirall/folder.cpp" line="478"/>
<source>%1 has been renamed to %2.</source>
<comment>%1 and %2 name files.</comment>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="473"/>
<location filename="../src/mirall/folder.cpp" line="483"/>
<source>%1 has been moved to %2 and %3 other files have been moved.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="475"/>
<location filename="../src/mirall/folder.cpp" line="485"/>
<source>%1 has been moved to %2.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="480"/>
<location filename="../src/mirall/folder.cpp" line="490"/>
<source>%1 and %2 other files could not be synced due to errors. See the log for details.</source>
<comment>%1 names a file.</comment>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="482"/>
<location filename="../src/mirall/folder.cpp" line="492"/>
<source>%1 could not be synced due to an error. See the log for details.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="490"/>
<location filename="../src/mirall/folder.cpp" line="500"/>
<source>Sync Activity</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="707"/>
<location filename="../src/mirall/folder.cpp" line="739"/>
<source>Could not read system exclude file</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="903"/>
<location filename="../src/mirall/folder.cpp" line="956"/>
<source>This sync would remove all the files in the sync folder '%1'.
This might be because the folder was silently reconfigured, or that all the file were manually removed.
Are you sure you want to perform this operation?</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="907"/>
<location filename="../src/mirall/folder.cpp" line="960"/>
<source>Remove All Files?</source>
<translation>El legyen távolítva az összes fájl?</translation>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="909"/>
<location filename="../src/mirall/folder.cpp" line="962"/>
<source>Remove all files</source>
<translation>Összes fájl eltávolítása</translation>
</message>
<message>
<location filename="../src/mirall/folder.cpp" line="910"/>
<location filename="../src/mirall/folder.cpp" line="963"/>
<source>Keep files</source>
<translation>Fájlok megtartása</translation>
</message>
@@ -415,62 +415,62 @@ Are you sure you want to perform this operation?</source>
<context>
<name>Mirall::FolderMan</name>
<message>
<location filename="../src/mirall/folderman.cpp" line="228"/>
<location filename="../src/mirall/folderman.cpp" line="237"/>
<source>Could not reset folder state</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="229"/>
<location filename="../src/mirall/folderman.cpp" line="238"/>
<source>An old sync journal &apos;%1&apos; was found, but could not be removed. Please make sure that no application is currently using it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="859"/>
<location filename="../src/mirall/folderman.cpp" line="957"/>
<source>Undefined State.</source>
<translation>Ismeretlen állapot.</translation>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="862"/>
<location filename="../src/mirall/folderman.cpp" line="960"/>
<source>Waits to start syncing.</source>
<translation>Várakozás a szinkronizálás elindítására.</translation>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="865"/>
<location filename="../src/mirall/folderman.cpp" line="963"/>
<source>Preparing for sync.</source>
<translation>Előkészítés szinkronizációhoz.</translation>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="868"/>
<location filename="../src/mirall/folderman.cpp" line="966"/>
<source>Sync is running.</source>
<translation>Szinkronizálás fut.</translation>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="871"/>
<location filename="../src/mirall/folderman.cpp" line="969"/>
<source>Last Sync was successful.</source>
<translation>Legutolsó szinkronizálás sikeres volt.</translation>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="876"/>
<location filename="../src/mirall/folderman.cpp" line="974"/>
<source>Last Sync was successful, but with warnings on individual files.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="879"/>
<location filename="../src/mirall/folderman.cpp" line="977"/>
<source>Setup Error.</source>
<translation>Beállítás hiba.</translation>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="882"/>
<location filename="../src/mirall/folderman.cpp" line="980"/>
<source>User Abort.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="885"/>
<location filename="../src/mirall/folderman.cpp" line="983"/>
<source>Sync is paused.</source>
<translation>Szinkronizálás megállítva.</translation>
</message>
<message>
<location filename="../src/mirall/folderman.cpp" line="891"/>
<location filename="../src/mirall/folderman.cpp" line="989"/>
<source>%1 (Sync is paused)</source>
<translation type="unfinished"/>
</message>
@@ -497,8 +497,8 @@ Are you sure you want to perform this operation?</source>
<context>
<name>Mirall::FolderWizard</name>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="494"/>
<location filename="../src/mirall/folderwizard.cpp" line="496"/>
<location filename="../src/mirall/folderwizard.cpp" line="501"/>
<location filename="../src/mirall/folderwizard.cpp" line="503"/>
<source>Add Folder</source>
<translation>Mappa hozzáadása</translation>
</message>
@@ -575,41 +575,41 @@ Are you sure you want to perform this operation?</source>
<name>Mirall::FolderWizardRemotePath</name>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="257"/>
<source>Add Remote Folder</source>
<translation>Távoli mappa hozzáadása</translation>
<source>Create Remote Folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="258"/>
<source>Enter the name of the new folder:</source>
<translation>Adja meg az új mappa nevét:</translation>
<source>Enter the name of the new folder to be created below &apos;%1&apos;:</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="280"/>
<location filename="../src/mirall/folderwizard.cpp" line="287"/>
<source>Folder was successfully created on %1.</source>
<translation>A mappa sikeresen létrehozva: %1.</translation>
</message>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="288"/>
<location filename="../src/mirall/folderwizard.cpp" line="295"/>
<source>Failed to create the folder on %1. Please check manually.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="337"/>
<location filename="../src/mirall/folderwizard.cpp" line="344"/>
<source>Choose this to sync the entire account</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="392"/>
<location filename="../src/mirall/folderwizard.cpp" line="399"/>
<source>This folder is already being synced.</source>
<translation>Ez a mappa már szinkronizálva van.</translation>
</message>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="394"/>
<location filename="../src/mirall/folderwizard.cpp" line="401"/>
<source>You are already syncing &lt;i&gt;%1&lt;/i&gt;, which is a parent folder of &lt;i&gt;%2&lt;/i&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="398"/>
<location filename="../src/mirall/folderwizard.cpp" line="405"/>
<source>You are already syncing all your files. Syncing another folder is &lt;b&gt;not&lt;/b&gt; supported. If you want to sync multiple folders, please remove the currently configured root folder sync.</source>
<translation type="unfinished"/>
</message>
@@ -617,7 +617,7 @@ Are you sure you want to perform this operation?</source>
<context>
<name>Mirall::FolderWizardSelectiveSync</name>
<message>
<location filename="../src/mirall/folderwizard.cpp" line="436"/>
<location filename="../src/mirall/folderwizard.cpp" line="443"/>
<source>Choose What to Sync: You can optionally deselect subfolders you do not wish to synchronize.</source>
<translation type="unfinished"/>
</message>
@@ -1053,12 +1053,12 @@ for additional privileges during the process.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/wizard/owncloudadvancedsetuppage.cpp" line="252"/>
<location filename="../src/wizard/owncloudadvancedsetuppage.cpp" line="253"/>
<source>Local Sync Folder</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/wizard/owncloudadvancedsetuppage.cpp" line="265"/>
<location filename="../src/wizard/owncloudadvancedsetuppage.cpp" line="266"/>
<source>Update advanced setup</source>
<translation type="unfinished"/>
</message>
@@ -1106,7 +1106,7 @@ It is not advisable to use it.</source>
</message>
<message>
<location filename="../src/wizard/owncloudsetuppage.cpp" line="227"/>
<source>Could not connect securely. Do you want to connect unencrypted instead (not recommended)?</source>
<source>&lt;p&gt;Could not connect securely:&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;Do you want to connect unencrypted instead (not recommended)?&lt;/p&gt;</source>
<translation type="unfinished"/>
</message>
<message>
@@ -1123,126 +1123,126 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::OwncloudSetupWizard</name>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="372"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="373"/>
<source>Folder rename failed</source>
<translation>A mappa átnevezése nem sikerült</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="434"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="443"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="442"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="450"/>
<source>&lt;font color=&quot;green&quot;&gt;&lt;b&gt;Local sync folder %1 successfully created!&lt;/b&gt;&lt;/font&gt;</source>
<translation>&lt;font color=&quot;green&quot;&gt;&lt;b&gt;Helyi %1 szinkronizációs mappa sikeresen létrehozva!&lt;/b&gt;&lt;/font&gt;</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="205"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="206"/>
<source>Trying to connect to %1 at %2...</source>
<translation>Próbál kapcsolódni az %1-hoz: %2...</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="161"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="162"/>
<source>&lt;font color=&quot;green&quot;&gt;Successfully connected to %1: %2 version %3 (%4)&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;</source>
<translation>&lt;font color=&quot;green&quot;&gt;Sikeresen csatlakozott az %1-hoz: %2 verziószám %3 (%4)&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="230"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="231"/>
<source>Error: Wrong credentials.</source>
<translation>Hiba: rossz azonosítási adatok</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="244"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="245"/>
<source>Local sync folder %1 already exists, setting it up for sync.&lt;br/&gt;&lt;br/&gt;</source>
<translation>A helyi %1 mappa már létezik, állítsa be a szinkronizálódását.&lt;br/&gt;&lt;br/&gt;</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="246"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="247"/>
<source>Creating local sync folder %1... </source>
<translation>Helyi %1 szinkronizációs mappa létrehozása...</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="250"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="251"/>
<source>ok</source>
<translation>ok</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="252"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="253"/>
<source>failed.</source>
<translation> sikertelen.</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="254"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="255"/>
<source>Could not create local folder %1</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="185"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="193"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="186"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="194"/>
<source>Failed to connect to %1 at %2:&lt;br/&gt;%3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="279"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="280"/>
<source>No remote folder specified!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="285"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="286"/>
<source>Error: %1</source>
<translation>Hiba: %1</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="298"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="299"/>
<source>creating folder on ownCloud: %1</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="314"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="315"/>
<source>Remote folder %1 created successfully.</source>
<translation>%1 távoli nappa sikeresen létrehozva.</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="316"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="317"/>
<source>The remote folder %1 already exists. Connecting it for syncing.</source>
<translation>A %1 távoli mappa már létezik. Csatlakoztassa a szinkronizációhoz.</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="318"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="320"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="319"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="321"/>
<source>The folder creation resulted in HTTP error code %1</source>
<translation>A könyvtár létrehozásakor keletkezett HTTP hibakód %1</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="322"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="323"/>
<source>The remote folder creation failed because the provided credentials are wrong!&lt;br/&gt;Please go back and check your credentials.&lt;/p&gt;</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="325"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="326"/>
<source>&lt;p&gt;&lt;font color=&quot;red&quot;&gt;Remote folder creation failed probably because the provided credentials are wrong.&lt;/font&gt;&lt;br/&gt;Please go back and check your credentials.&lt;/p&gt;</source>
<translation>&lt;p&gt;&lt;font color=&quot;red&quot;&gt;A távoli mappa létrehozása sikertelen, valószínűleg mivel hibásak a megdott hitelesítési adatok.&lt;/font&gt;&lt;br/&gt;Lépjen vissza és ellenőrizze a belépési adatokat.&lt;/p&gt;</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="330"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="331"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="332"/>
<source>Remote folder %1 creation failed with error &lt;tt&gt;%2&lt;/tt&gt;.</source>
<translation>A távoli %1 mappa létrehozása nem sikerült. Hibaüzenet: &lt;tt&gt;%2&lt;/tt&gt;.</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="347"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="348"/>
<source>A sync connection from %1 to remote directory %2 was set up.</source>
<translation>A szinkronizációs kapcsolat a %1 és a %2 távoli mappa között létrejött.</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="352"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="353"/>
<source>Successfully connected to %1!</source>
<translation>Sikeresen csatlakozva: %1!</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="359"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="360"/>
<source>Connection to %1 could not be established. Please check again.</source>
<translation>A kapcsolat a %1 kiszolgálóhoz sikertelen. Ellenőrizze újra.</translation>
</message>
<message>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="373"/>
<location filename="../src/mirall/owncloudsetupwizard.cpp" line="374"/>
<source>Can&apos;t remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup.</source>
<translation type="unfinished"/>
</message>
@@ -1277,16 +1277,6 @@ It is not advisable to use it.</source>
<source>Open %1 in Browser</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/wizard/owncloudwizardresultpage.cpp" line="77"/>
<source>Your entire account is synced to the local folder &lt;i&gt;%1&lt;/i&gt;</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/wizard/owncloudwizardresultpage.cpp" line="80"/>
<source>%1 folder &lt;i&gt;%1&lt;/i&gt; is synced to local folder &lt;i&gt;%2&lt;/i&gt;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Mirall::PUTFileJob</name>
@@ -1299,27 +1289,27 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::PropagateDownloadFileLegacy</name>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="357"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="363"/>
<source>Sync was aborted by user.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="410"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="416"/>
<source>No E-Tag received from server, check Proxy/Gateway</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="416"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="422"/>
<source>We received a different E-Tag for resuming. Retrying next time.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="438"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="444"/>
<source>Server returned wrong content-range</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="489"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="495"/>
<source>File %1 can not be downloaded because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
@@ -1331,6 +1321,16 @@ It is not advisable to use it.</source>
<source>File %1 can not be downloaded because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_qnam.cpp" line="755"/>
<source>The file could not be downloaded completely.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_qnam.cpp" line="791"/>
<source>File %1 cannot be saved because of a local file name clash!</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Mirall::PropagateItemJob</name>
@@ -1348,12 +1348,12 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::PropagateLocalMkdir</name>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="113"/>
<location filename="../src/mirall/propagatorjobs.cpp" line="127"/>
<source>Attention, possible case sensitivity clash with %1</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="118"/>
<location filename="../src/mirall/propagatorjobs.cpp" line="132"/>
<source>could not create directory %1</source>
<translation type="unfinished"/>
</message>
@@ -1361,20 +1361,25 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::PropagateLocalRemove</name>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="80"/>
<source>Could not remove %1 because of a local file name clash</source>
<location filename="../src/mirall/propagatorjobs.cpp" line="68"/>
<source>Error removing &apos;%1&apos;: %2; </source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="87"/>
<source>Could not remove directory %1</source>
<location filename="../src/mirall/propagatorjobs.cpp" line="79"/>
<source>Could not remove directory &apos;%1&apos;; </source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="94"/>
<source>Could not remove %1 because of a local file name clash</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Mirall::PropagateLocalRename</name>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="257"/>
<location filename="../src/mirall/propagatorjobs.cpp" line="271"/>
<source>File %1 can not be renamed to %2 because of a local file name clash</source>
<translation type="unfinished"/>
</message>
@@ -1382,7 +1387,7 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::PropagateRemoteRemove</name>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="138"/>
<location filename="../src/mirall/propagatorjobs.cpp" line="152"/>
<source>The file has been removed from a read only share. It was restored.</source>
<translation type="unfinished"/>
</message>
@@ -1390,17 +1395,17 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::PropagateRemoteRename</name>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="294"/>
<location filename="../src/mirall/propagatorjobs.cpp" line="308"/>
<source>This folder must not be renamed. It is renamed back to its original name.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="296"/>
<location filename="../src/mirall/propagatorjobs.cpp" line="310"/>
<source>This folder must not be renamed. Please name it back to Shared.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagatorjobs.cpp" line="311"/>
<location filename="../src/mirall/propagatorjobs.cpp" line="325"/>
<source>The file was renamed but is part of a read only share. The original file was restored.</source>
<translation type="unfinished"/>
</message>
@@ -1408,18 +1413,18 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::PropagateUploadFileLegacy</name>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="165"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="224"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="171"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="230"/>
<source>Local file changed during sync, syncing once it arrived completely</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="168"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="174"/>
<source>Sync was aborted by user.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/propagator_legacy.cpp" line="174"/>
<location filename="../src/mirall/propagator_legacy.cpp" line="180"/>
<source>The file was edited locally but is part of a read only share. It is restored and your edit is in the conflict file.</source>
<translation type="unfinished"/>
</message>
@@ -1521,27 +1526,38 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/protocolwidget.cpp" line="255"/>
<source>Currently no files are ignored because of previous errors.</source>
<location filename="../src/mirall/protocolwidget.cpp" line="262"/>
<source>Currently no files are ignored because of previous errors and no downloads are in progress.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
<location filename="../src/mirall/protocolwidget.cpp" line="257"/>
<location filename="../src/mirall/protocolwidget.cpp" line="265"/>
<source>%n files are ignored because of previous errors.
Try to sync these again.</source>
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
<location filename="../src/mirall/protocolwidget.cpp" line="266"/>
<source>%n files are partially downloaded.
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
<location filename="../src/mirall/protocolwidget.cpp" line="267"/>
<source>Try to sync these again.</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Mirall::SelectiveSyncDialog</name>
<message>
<location filename="../src/mirall/selectivesyncdialog.cpp" line="268"/>
<location filename="../src/mirall/selectivesyncdialog.cpp" line="271"/>
<source>Choose What to Sync</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/selectivesyncdialog.cpp" line="271"/>
<source>Unchecked folders will not be sync to this computer</source>
<location filename="../src/mirall/selectivesyncdialog.cpp" line="274"/>
<source>Unchecked folders will be &lt;b&gt;removed&lt;/b&gt; from your local file system and will not be synchronized to this computer anymore</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1589,27 +1605,27 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::SettingsDialogMac</name>
<message>
<location filename="../src/mirall/settingsdialogmac.cpp" line="50"/>
<location filename="../src/mirall/settingsdialogmac.cpp" line="63"/>
<source>%1</source>
<translation>%1</translation>
</message>
<message>
<location filename="../src/mirall/settingsdialogmac.cpp" line="54"/>
<location filename="../src/mirall/settingsdialogmac.cpp" line="67"/>
<source>Account</source>
<translation>Fiók</translation>
</message>
<message>
<location filename="../src/mirall/settingsdialogmac.cpp" line="58"/>
<location filename="../src/mirall/settingsdialogmac.cpp" line="71"/>
<source>Activity</source>
<translation>Aktivitás</translation>
</message>
<message>
<location filename="../src/mirall/settingsdialogmac.cpp" line="62"/>
<location filename="../src/mirall/settingsdialogmac.cpp" line="75"/>
<source>General</source>
<translation>Általános</translation>
</message>
<message>
<location filename="../src/mirall/settingsdialogmac.cpp" line="66"/>
<location filename="../src/mirall/settingsdialogmac.cpp" line="79"/>
<source>Network</source>
<translation>Hálózat</translation>
</message>
@@ -1617,12 +1633,12 @@ It is not advisable to use it.</source>
<context>
<name>Mirall::ShibbolethCredentials</name>
<message>
<location filename="../src/creds/shibbolethcredentials.cpp" line="285"/>
<location filename="../src/creds/shibbolethcredentials.cpp" line="297"/>
<source>Login Error</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/creds/shibbolethcredentials.cpp" line="285"/>
<location filename="../src/creds/shibbolethcredentials.cpp" line="297"/>
<source>You must sign in as user %1</source>
<translation type="unfinished"/>
</message>
@@ -1993,99 +2009,104 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="184"/>
<location filename="../src/mirall/syncengine.cpp" line="183"/>
<source>The mounted directory is temporary not available on the server</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="186"/>
<source>An internal error number %1 happened.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="243"/>
<location filename="../src/mirall/syncengine.cpp" line="245"/>
<source>The item is not synced because of previous errors: %1</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="357"/>
<location filename="../src/mirall/syncengine.cpp" line="361"/>
<source>Symbolic links are not supported in syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="360"/>
<location filename="../src/mirall/syncengine.cpp" line="364"/>
<source>Hard links are not supported in syncing.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="363"/>
<location filename="../src/mirall/syncengine.cpp" line="367"/>
<source>File is listed on the ignore list.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="366"/>
<location filename="../src/mirall/syncengine.cpp" line="370"/>
<source>File contains invalid characters that can not be synced cross platform.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="540"/>
<location filename="../src/mirall/syncengine.cpp" line="564"/>
<source>Unable to initialize a sync journal.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="621"/>
<location filename="../src/mirall/syncengine.cpp" line="645"/>
<source>Cannot open the sync journal</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="853"/>
<location filename="../src/mirall/syncengine.cpp" line="860"/>
<location filename="../src/mirall/syncengine.cpp" line="877"/>
<location filename="../src/mirall/syncengine.cpp" line="884"/>
<source>Ignored because of the &quot;choose what to sync&quot; blacklist</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="878"/>
<location filename="../src/mirall/syncengine.cpp" line="902"/>
<source>Not allowed because you don&apos;t have permission to add sub-directories in that directory</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="884"/>
<location filename="../src/mirall/syncengine.cpp" line="908"/>
<source>Not allowed because you don&apos;t have permission to add parent directory</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="891"/>
<location filename="../src/mirall/syncengine.cpp" line="915"/>
<source>Not allowed because you don&apos;t have permission to add files in that directory</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="911"/>
<location filename="../src/mirall/syncengine.cpp" line="935"/>
<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/mirall/syncengine.cpp" line="928"/>
<location filename="../src/mirall/syncengine.cpp" line="948"/>
<location filename="../src/mirall/syncengine.cpp" line="952"/>
<location filename="../src/mirall/syncengine.cpp" line="972"/>
<source>Not allowed to remove, restoring</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="963"/>
<location filename="../src/mirall/syncengine.cpp" line="987"/>
<source>Local files and share folder removed.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="1018"/>
<location filename="../src/mirall/syncengine.cpp" line="1042"/>
<source>Move not allowed, item restored</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="1027"/>
<location filename="../src/mirall/syncengine.cpp" line="1051"/>
<source>Move not allowed because %1 is read-only</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="1028"/>
<location filename="../src/mirall/syncengine.cpp" line="1052"/>
<source>the destination</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/syncengine.cpp" line="1028"/>
<location filename="../src/mirall/syncengine.cpp" line="1052"/>
<source>the source</source>
<translation type="unfinished"/>
</message>
@@ -2119,7 +2140,7 @@ It is not advisable to use it.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="265"/>
<location filename="../src/mirall/owncloudgui.cpp" line="266"/>
<source>Folder %1: %2</source>
<translation>Mappa %1: %2</translation>
</message>
@@ -2129,117 +2150,117 @@ It is not advisable to use it.</source>
<translation>Nincsenek megadva szinkronizálandó mappák.</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="280"/>
<location filename="../src/mirall/owncloudgui.cpp" line="281"/>
<source>There are no sync folders configured.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="306"/>
<location filename="../src/mirall/owncloudgui.cpp" line="307"/>
<source>None.</source>
<translation>Nincs</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="310"/>
<location filename="../src/mirall/owncloudgui.cpp" line="311"/>
<source>Recent Changes</source>
<translation>Legutóbbi változások</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="327"/>
<location filename="../src/mirall/owncloudgui.cpp" line="328"/>
<source>Open %1 folder</source>
<translation>%1 mappa megnyitása</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="337"/>
<location filename="../src/mirall/owncloudgui.cpp" line="338"/>
<source>Managed Folders:</source>
<translation>Kezelt mappák:</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="340"/>
<location filename="../src/mirall/owncloudgui.cpp" line="341"/>
<source>Open folder &apos;%1&apos;</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="412"/>
<location filename="../src/mirall/owncloudgui.cpp" line="413"/>
<source>Open %1 in browser</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="414"/>
<location filename="../src/mirall/owncloudgui.cpp" line="415"/>
<source>Calculating quota...</source>
<translation>Kvóta kiszámítása...</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="416"/>
<location filename="../src/mirall/owncloudgui.cpp" line="417"/>
<source>Unknown status</source>
<translation>Ismeretlen állapot</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="418"/>
<location filename="../src/mirall/owncloudgui.cpp" line="419"/>
<source>Settings...</source>
<translation>Beállítások...</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="419"/>
<location filename="../src/mirall/owncloudgui.cpp" line="420"/>
<source>Details...</source>
<translation>Részletek...</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="424"/>
<location filename="../src/mirall/owncloudgui.cpp" line="425"/>
<source>Help</source>
<translation>Súgó</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="426"/>
<location filename="../src/mirall/owncloudgui.cpp" line="427"/>
<source>Quit %1</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="429"/>
<location filename="../src/mirall/owncloudgui.cpp" line="430"/>
<source>Sign in...</source>
<translation>Belépés...</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="431"/>
<location filename="../src/mirall/owncloudgui.cpp" line="432"/>
<source>Sign out</source>
<translation>Kilépés</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="439"/>
<location filename="../src/mirall/owncloudgui.cpp" line="440"/>
<source>Quota n/a</source>
<translation>Kvóta n/a</translation>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="446"/>
<location filename="../src/mirall/owncloudgui.cpp" line="447"/>
<source>%1% of %2 in use</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="458"/>
<location filename="../src/mirall/owncloudgui.cpp" line="459"/>
<source>No items synced recently</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="470"/>
<location filename="../src/mirall/owncloudgui.cpp" line="471"/>
<source>Discovering &apos;%1&apos;</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="474"/>
<location filename="../src/mirall/owncloudgui.cpp" line="475"/>
<source>Syncing %1 of %2 (%3 left)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="479"/>
<location filename="../src/mirall/owncloudgui.cpp" line="480"/>
<source>Syncing %1 (%2 left)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="499"/>
<location filename="../src/mirall/owncloudgui.cpp" line="500"/>
<source>%1 (%2, %3)</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/mirall/owncloudgui.cpp" line="527"/>
<location filename="../src/mirall/owncloudgui.cpp" line="528"/>
<source>Up to date</source>
<translation>Frissítve</translation>
</message>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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