Comparar commits
396 Commits
v1.8.0-rc1
..
1.8
| Autor | SHA1 | Data | |
|---|---|---|---|
| a228b8cbb1 | |||
| eb83832d70 | |||
| e4deca4231 | |||
| a57c017f44 | |||
| e0e793fb14 | |||
| 9222db6df9 | |||
| 3fc9bf59d1 | |||
| dd8c2ba94a | |||
| 180084da94 | |||
| fb79fe1e11 | |||
| 2ace075579 | |||
| a3fd341dac | |||
| 65933d5a2e | |||
| fbcfef175e | |||
| 2b085f693d | |||
| dc89dc0703 | |||
| 4bbf766909 | |||
| 31b0553b8f | |||
| 2efb4d9d17 | |||
| 5eb098b3ca | |||
| 518006cba0 | |||
| 6a83a65048 | |||
| 9e7da1f154 | |||
| c5f99f9179 | |||
| e4ef04a793 | |||
| 02cc76870a | |||
| affe2f13ff | |||
| 30926c0aa5 | |||
| 972aa6d329 | |||
| d1e0fbeca9 | |||
| 64369c7303 | |||
| b888242db8 | |||
| 8f359f339d | |||
| e88582166c | |||
| f0b8066e71 | |||
| b362a0a84a | |||
| 516509b4ed | |||
| 13a15a6256 | |||
| 678b6affa2 | |||
| 1fa5fa91a8 | |||
| fc99070b54 | |||
| eca3d48510 | |||
| bf9bb26d19 | |||
| 01efba99af | |||
| 6e469662d3 | |||
| 4bc94c17ea | |||
| 1820d4018e | |||
| f130a2716e | |||
| deb5e68e15 | |||
| 9a9897ea1e | |||
| deea902c4f | |||
| 42513af536 | |||
| 676a2ff8ca | |||
| 1e56349838 | |||
| 33b8064042 | |||
| 1f5170253c | |||
| ad6f2e03c9 | |||
| 4c3daf7927 | |||
| 4936f70d20 | |||
| ecd2da185d | |||
| 7a7bf4c561 | |||
| 827e07700d | |||
| d142c554d1 | |||
| 69f2b2da7c | |||
| 4000993200 | |||
| 2c6c21d753 | |||
| 34384e3613 | |||
| a42856ef84 | |||
| e7f01b9a95 | |||
| fc2ceb88fb | |||
| 36f62f7fd4 | |||
| ee08b3759d | |||
| c73110e3c7 | |||
| 9ced5fb9a3 | |||
| f9659d80c9 | |||
| 553e831121 | |||
| e9ff471e1c | |||
| eb6d29a223 | |||
| 3df26ef189 | |||
| 25767bee0b | |||
| 0f7773ff99 | |||
| 2ed329e025 | |||
| e04882cc7c | |||
| 40818920d1 | |||
| 1bec652822 | |||
| 4c10f1e40c | |||
| 53154bcd1e | |||
| 1d600ceecc | |||
| e1a36b53dc | |||
| 5f91abd7c6 | |||
| 75b38d1a2f | |||
| 7f597e5dd2 | |||
| e3be1a176d | |||
| b1658cb1cf | |||
| 6ba3324035 | |||
| e2a26f0eaf | |||
| 8cfb17bca6 | |||
| 211e5ec82e | |||
| 2435ba7e7d | |||
| be77e4f57e | |||
| f344b42aa9 | |||
| 90f4a20a50 | |||
| 793130a533 | |||
| 1ddb162338 | |||
| 070d9d3147 | |||
| 9b73308edd | |||
| b46a8239e2 | |||
| e9d0f5a022 | |||
| 5721d8eb64 | |||
| e708c145fa | |||
| 713beeb2a5 | |||
| 6c46713701 | |||
| 3754e6c781 | |||
| 6401b1cfc3 | |||
| 6b9e123816 | |||
| fb2295fcec | |||
| 0af2f7e5ed | |||
| 1c84d01584 | |||
| 3fcce08a22 | |||
| 289800c1ba | |||
| 49fb37fefc | |||
| 9a02a0f3a8 | |||
| 4e79093f84 | |||
| d2fff2c3e3 | |||
| 8f277e46d6 | |||
| c33d962712 | |||
| 3870915118 | |||
| b05ca526a4 | |||
| 4e28a24af3 | |||
| aebadfcda2 | |||
| c975954a9a | |||
| dec3bd4a02 | |||
| 64ce0cd7a2 | |||
| 34593cccb6 | |||
| 5b5a636cc1 | |||
| 5c6a6529a6 | |||
| 68fa190cf7 | |||
| d148464efe | |||
| 6a7f2089e8 | |||
| 17fe4c3b29 | |||
| dd6c97abb6 | |||
| ddfe3fa7ab | |||
| 1f7274c2f2 | |||
| 4d87f30434 | |||
| 8b371c42b7 | |||
| c7f759fedf | |||
| 830daa40d1 | |||
| f016d25b4c | |||
| e18fd62f34 | |||
| 3701fbcbfe | |||
| 823f9fa0d1 | |||
| 67d38bc87b | |||
| b36ff1ed1d | |||
| ec83295b99 | |||
| e36252a845 | |||
| d0d8de9f2f | |||
| 9693048f78 | |||
| 101d2268ff | |||
| 2fcad760b9 | |||
| 52eb6c95cf | |||
| 35169e3de4 | |||
| 650b201b33 | |||
| f595fc2f9c | |||
| 06c889630c | |||
| d6dbabfbc4 | |||
| bcae146444 | |||
| 8a39748654 | |||
| 3556ed416c | |||
| e5e2ce2b22 | |||
| 39d103adf7 | |||
| afd1406e61 | |||
| a4c411af99 | |||
| bcc896fb6e | |||
| 76166c6252 | |||
| dd5a49bc78 | |||
| cdfafa2180 | |||
| 6b16e18eb8 | |||
| c2dacd03a5 | |||
| 505dba5b23 | |||
| af5a7063c9 | |||
| 9e7779a476 | |||
| 625e61516f | |||
| 41614ec851 | |||
| 4d3a0ed250 | |||
| cac15988f0 | |||
| 1e131f4732 | |||
| 22c35c4d15 | |||
| 9507bb4be6 | |||
| e1c370a9a2 | |||
| b9eafaaf24 | |||
| 909368025f | |||
| 15bfa46023 | |||
| 0359c775e0 | |||
| 1053153ec4 | |||
| 79ac61684c | |||
| 441eca86c4 | |||
| f07d3d069e | |||
| e300e3c744 | |||
| b9df8290c9 | |||
| 73e2254a80 | |||
| 352c2957b2 | |||
| 23b6426dfa | |||
| 9ef8658122 | |||
| 0a67719f2f | |||
| 04d820f9cf | |||
| 931dd59844 | |||
| a6500d8068 | |||
| 0d5d2c578d | |||
| 77679790db | |||
| ee71024496 | |||
| b1f326054f | |||
| bceb40ed80 | |||
| fd684eda52 | |||
| 9e3c3353bd | |||
| 07ffff3d77 | |||
| 9b34427a1c | |||
| 5fba476076 | |||
| d63abef718 | |||
| cdba8a7f2f | |||
| 21967a130b | |||
| 08e78d5d6f | |||
| fe68e1e82c | |||
| 25ac3bfdb7 | |||
| 4700c604b1 | |||
| 356fa737c5 | |||
| 520e2eb392 | |||
| e0d2bd4830 | |||
| 1dc05f99bf | |||
| b2b176bcd0 | |||
| fde5ccd0df | |||
| d1fe25cc31 | |||
| 60c18f75b5 | |||
| c7f3791f3d | |||
| ee9d5e6bf0 | |||
| 96fa3a3a1a | |||
| 7c4deec800 | |||
| 78e82eb920 | |||
| 3c91a1ace4 | |||
| 3a52db46ad | |||
| 137bce6dd0 | |||
| f000e6ce6a | |||
| 7c1281dd06 | |||
| 60729f2bbd | |||
| 0b0ecfcbe4 | |||
| 1fe86bced2 | |||
| c6a62a497d | |||
| 8be6881093 | |||
| 99c8118229 | |||
| 6c5ca055c4 | |||
| a6ec8f3090 | |||
| b039c2ce86 | |||
| 5a6d286c41 | |||
| ba65187ad3 | |||
| a91f54f0a8 | |||
| d77c1f3e4a | |||
| 7390ddbd98 | |||
| 32a4b40f0a | |||
| bc1bc2a4f8 | |||
| 155c965866 | |||
| 6c73f25747 | |||
| 2518fd7059 | |||
| 56edae6958 | |||
| d8275cd4e1 | |||
| c3dca7a288 | |||
| 96ff0076c7 | |||
| 8bb4af067a | |||
| df0df76b51 | |||
| 458f336405 | |||
| 3f3f27d4d3 | |||
| 7c9cffa5ae | |||
| 996223197c | |||
| b8e7555977 | |||
| ed80a712ab | |||
| 2866e56c51 | |||
| 2074bdbb19 | |||
| d212ac7d16 | |||
| d2bae21b14 | |||
| 4283ab3b44 | |||
| c579069071 | |||
| 88488c695c | |||
| 21594e9aa9 | |||
| 9ffacd4ecd | |||
| 9d5f5ea3bc | |||
| 2dbd27af76 | |||
| 0634a4d0c6 | |||
| fa80a006b8 | |||
| 9d88ef5432 | |||
| 7b99877c68 | |||
| ec81cdefb0 | |||
| 454d5b575c | |||
| 785b59e6d1 | |||
| 9d8fc4aa4d | |||
| 57ac1d9ea2 | |||
| d9ea6936ab | |||
| c917251e9e | |||
| c805c5d6e9 | |||
| adcf40afc3 | |||
| d986011067 | |||
| 5a83636f81 | |||
| d475628c70 | |||
| 4a890eae38 | |||
| 760e11bc5d | |||
| 96ebf2b519 | |||
| 4a6f4919d7 | |||
| b98040c7d5 | |||
| 1240a8163d | |||
| e15b9b5358 | |||
| 1617c9d482 | |||
| 16600fe86a | |||
| 50ba73860c | |||
| 750cdc1910 | |||
| f4e2c84111 | |||
| 4f27750711 | |||
| 71d9f23068 | |||
| 9f7aed7602 | |||
| 7f2213416a | |||
| 9b9f0bdd4d | |||
| ee0aec514f | |||
| c2fd7d6ebd | |||
| 4a893c5267 | |||
| 2473183f19 | |||
| 7d7142d7d8 | |||
| cb57cda87a | |||
| f2fa812b0b | |||
| ef89582d7e | |||
| ae74a21305 | |||
| 32af63764c | |||
| 61ff90409d | |||
| ba0c3256fa | |||
| b6fe5d2cff | |||
| 9123fac545 | |||
| c6bc388001 | |||
| ea985a85af | |||
| 2578832002 | |||
| cfada67aa6 | |||
| 5483682281 | |||
| 2a8c23aac3 | |||
| 88bc96fc4c | |||
| 588129d852 | |||
| 0889991c38 | |||
| 5c87a35fe4 | |||
| 418185af9a | |||
| 4b56cc6e08 | |||
| 3cef771868 | |||
| 59b20de7cd | |||
| e0ae34f01b | |||
| a9a24c96fc | |||
| a202203325 | |||
| 83c3d76966 | |||
| 99734f8d72 | |||
| 570a0bb586 | |||
| 450a815d61 | |||
| dafc2d2b73 | |||
| 0bd2edd33a | |||
| 807267cfdb | |||
| 48c9222578 | |||
| b5ea56df73 | |||
| 2fdf6dd8f2 | |||
| 5b8c9eb16f | |||
| 9c05150c12 | |||
| c7eb85ef78 | |||
| 4df455f2e0 | |||
| 653a00d63d | |||
| 3c9acdf724 | |||
| e81d1ab9b8 | |||
| ad5620efb5 | |||
| f455c71338 | |||
| 033f2cd231 | |||
| c9eccd729d | |||
| b1100cd9e5 | |||
| 8f728ddfb2 | |||
| 4ef0ce112c | |||
| 57c14a0eba | |||
| 89f831e7d4 | |||
| 917b8409ae | |||
| 86fd39e3a9 | |||
| 04db332051 | |||
| 06a2f58c51 | |||
| b87d55758b | |||
| 38ef525d5e | |||
| 367b1fcc33 | |||
| f5c930968e | |||
| 5264a8c7f6 | |||
| 6c4b7f1479 | |||
| c42c9f0002 | |||
| 95f299f865 | |||
| 09749e2c7f | |||
| dc33784a76 | |||
| 961df1fc44 | |||
| e93c1ccb73 | |||
| 286ad0c478 | |||
| e30970ff90 | |||
| 14e0e4a072 | |||
| 60da0a15e6 | |||
| 0f84510e6f | |||
| 1dd3488973 |
+1
-1
@@ -165,13 +165,13 @@ endif()
|
||||
find_package(Sphinx)
|
||||
find_package(PdfLatex)
|
||||
|
||||
|
||||
find_package(SQLite3 3.8.0 REQUIRED)
|
||||
# On some OS, we want to use our own, not the system sqlite
|
||||
if (USE_OUR_OWN_SQLITE3)
|
||||
include_directories(BEFORE ${SQLITE3_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
find_package(ZLIB)
|
||||
|
||||
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
|
||||
+97
-4
@@ -1,6 +1,100 @@
|
||||
ChangeLog
|
||||
=========
|
||||
version 1.8.0 (release 2015-02-xx)
|
||||
version 1.8.3 (release 2015-06-23)
|
||||
* Fix a bug in the Windows Installer that could crash explorer (#3320)
|
||||
* Reduce 'Connection closed' errors (#3318, #3313, #3298)
|
||||
* Ignores: Force a remote discovery after ignore list change (#3172)
|
||||
* Shibboleth: Avoid crash by letting the webview use its own QNAM (#3359)
|
||||
* System Ignores: Removed *.tmp from system ignore again. If a user
|
||||
wants to ignore *.tmp, it needs to be added to the user ignore list.
|
||||
|
||||
ChangeLog
|
||||
=========
|
||||
version 1.8.2 (release 2015-06-08)
|
||||
* Improve reporting of server error messages (#3220)
|
||||
* Discovery: Ignore folders with any 503 (#3113)
|
||||
* Wizard: Show server error message if possible (#3220)
|
||||
* QNAM: Fix handling of mitm cert changes (#3283)
|
||||
* Win32: Installer translations added (#3277)
|
||||
* Win32: Allow concurrent OEM (un-)installers (#3272)
|
||||
* Win32: Make Setup/Update Mutex theme-unique (#3272)
|
||||
* HTTP: Add the branding name to the UserAgent string
|
||||
* ConnectonValidator: Always run with new credentials (#3266)
|
||||
* Recall Feature: Admins can trigger an upload of a file from
|
||||
client to server again (#3246)
|
||||
* Propagator: Add 'Content-Length: 0' header to MKCOL request (#3256)
|
||||
* Switch on checksum verification through branding or config
|
||||
* Add ability for checksum verification of up and download
|
||||
* Fix opening external links for some labels (#3135)
|
||||
* AccountState: Run only a single validator, allow error message
|
||||
overriding (#3236, #3153)
|
||||
* SyncJournalDB: Minor fixes and simplificatons
|
||||
* SyncEngine: Force re-read of folder Etags for upgrades from
|
||||
1.8.0 and 1.8.1
|
||||
* Propagator: Limit length of temporary file name (#2789)
|
||||
* ShareDialog: Password ui fixes (#3189)
|
||||
* Fix startup hang by removing QSettings lock file (#3175)
|
||||
* Wizard: Allow SSL cert dialog to show twice (#3168)
|
||||
* ProtocolWidget: Fix rename message (#3210)
|
||||
* Discovery: Test better, treat invalid hrefs as error (#3176)
|
||||
* Propagator: Overwrite local data only if unchanged (#3156)
|
||||
* ShareDialog: Improve error reporting for share API fails
|
||||
* OSX Updater: Only allow updates only if in /Applications (#2931)
|
||||
* Wizard: Fix lock icon (#1447)
|
||||
* Fix compilation with GCC 5
|
||||
* Treat any 503 error as temporary (#3113)
|
||||
* Work around for the Qt PUT corruption bug (#2425)
|
||||
* OSX Shell integration: Optimizations
|
||||
* Windows Shell integration: Optimizations
|
||||
.. more than 250 commits since 1.8.1
|
||||
|
||||
version 1.8.1 (release 2015-05-07)
|
||||
* Make "operation canceled" error a soft error
|
||||
* Do not throw an error for files that are scheduled to be removed,
|
||||
but can not be found on the server. #2919
|
||||
* Windows: Reset QNAM to proper function after hibernation. #2899 #2895 #2973
|
||||
* Fix argument verification of --confdir #2453
|
||||
* Fix a crash when accessing a dangling UploadDevice pointer #2984
|
||||
* Add-folder wizard: Make sure there is a scrollbar if folder names
|
||||
are too long #2962
|
||||
* Add-folder Wizard: Select the newly created folder
|
||||
* Activity: Correctly restore column sizes #3005
|
||||
* SSL Button: do not crash on empty certificate chain
|
||||
* SSL Button: Make menu creation lazy #3007 #2990
|
||||
* Lookup system proxy async to avoid hangs #2993 #2802
|
||||
* ShareDialog: Some GUI refinements
|
||||
* ShareDialog: On creation of a share always retrieve the share
|
||||
This makes sure that if a default expiration date is set this is reflected
|
||||
in the dialog. #2889
|
||||
* ShareDialog: Only show share dialog if we are connected.
|
||||
* HttpCreds: Fill pw dialog with previous password. #2848 #2879
|
||||
* HttpCreds: Delete password from old location. #2186
|
||||
* Do not store Session Cookies in the client cookie storage
|
||||
* CookieJar: Don't accidentally overwrite cookies. #2808
|
||||
* ProtocolWidget: Always add seconds to the DateTime locale. #2535
|
||||
* Updater: Give context as to which app is about to be updated #3040
|
||||
* Windows: Add version information for owncloud.exe. This should help us know
|
||||
what version or build number a crash report was generated with.
|
||||
* Fix a crash on shutdown in ~SocketApi #3057
|
||||
* SyncEngine: Show more timing measurements #3064
|
||||
* Discovery: Add warning if returned etag is 0
|
||||
* Fix a crash caused by an invalid DiscoveryDirectoryResult::iterator #3051
|
||||
* Sync: Fix sync of deletions during 503. #2894
|
||||
* Handle redirect of auth request. #3082
|
||||
* Discovery: Fix parsing of broken XML replies, which fixes local file disappearing #3102
|
||||
* Migration: Silently restore files that were deleted locally by bug #3102
|
||||
* Sort folder sizes SelectiveSyncTreeView numerically #3112
|
||||
* Sync: PropagateDownload: Read the mtime from the file system after writing it #3103
|
||||
* Sync: Propagate download: Fix restoring files for which the conflict file exists #3106
|
||||
* Use identical User Agents and version for csync and the Qt parts
|
||||
* Prevent another crash in ~SocketApi #3118
|
||||
* Windows: Fix rename of finished file. #3073
|
||||
* AccountWizard: Fix auth error handling. #3155
|
||||
* Documentation fixes
|
||||
* Infrastructure/build fixes
|
||||
* Win32/OS X: Apply patch from OpenSSL to handle oudated intermediates gracefully #3087
|
||||
|
||||
version 1.8.0 (release 2015-03-17)
|
||||
* Mac OS: HIDPI support
|
||||
* Support Sharing from desktop: Added a share dialog that can be
|
||||
opened by context menu in the file managers (Win, Mac, Nautilus)
|
||||
@@ -12,7 +106,7 @@ version 1.8.0 (release 2015-02-xx)
|
||||
* Added ability to build on Windows utilizing MingGW
|
||||
* SQLite database fixes if running on FAT filesystems
|
||||
* Improved detection of changing files to upload from local
|
||||
* Preparations for the muli-account feature
|
||||
* Preparations for the multi-account feature
|
||||
* Fixed experience for Window manager without system tray
|
||||
* Build with Qt 5.4
|
||||
* Dropped libneon dependency if Qt 5.4 is available
|
||||
@@ -24,8 +118,7 @@ version 1.8.0 (release 2015-02-xx)
|
||||
* Prepared direct download
|
||||
* Added Crashreporter feature to be switched on on demand
|
||||
* A huge amount of bug fixes in all areas of the client.
|
||||
|
||||
* more than 7000 commits since 1.7.0
|
||||
* almost 700 commits since 1.7.1
|
||||
|
||||
version 1.7.1 (release 2014-12-18)
|
||||
* Documentation fixes and updates
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
set( MIRALL_VERSION_MAJOR 1 )
|
||||
set( MIRALL_VERSION_MINOR 8 )
|
||||
set( MIRALL_VERSION_PATCH 0 )
|
||||
set( MIRALL_VERSION_PATCH 4 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
set( MIRALL_VERSION_SUFFIX "rc1") #e.g. beta1, beta2, rc1
|
||||
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
|
||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||
|
||||
@@ -50,7 +50,7 @@ if [ ! -z "$identity" ]; then
|
||||
echo "Will try to sign the installer"
|
||||
pushd $install_path
|
||||
productsign --sign "$identity" "$installer_file" "$installer_file.new"
|
||||
mv "$installer_file".new $installer_file
|
||||
mv "$installer_file".new "$installer_file"
|
||||
popd
|
||||
else
|
||||
echo "No certificate given, will not sign the pkg"
|
||||
|
||||
@@ -260,12 +260,18 @@ def CopyFramework(path):
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', os.path.join(full_path, parts[-1])]
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', os.path.join(frameworks_dir, framework, "Resources")]
|
||||
resources_dir = os.path.join(frameworks_dir, framework, "Resources")
|
||||
|
||||
args = ['mkdir', resources_dir]
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', resources_dir]
|
||||
commands.append(args)
|
||||
|
||||
info_plist = os.path.join(os.path.split(path)[0], '..', '..', 'Contents', 'Info.plist')
|
||||
if not os.path.exists(info_plist):
|
||||
info_plist = os.path.join(os.path.split(path)[0], 'Resources', 'Info.plist')
|
||||
if os.path.exists(info_plist):
|
||||
args = ['cp', '-r', info_plist, os.path.join(frameworks_dir, framework, "Resources")]
|
||||
args = ['cp', '-r', info_plist, resources_dir]
|
||||
commands.append(args)
|
||||
return os.path.join(full_path, parts[-1])
|
||||
|
||||
|
||||
@@ -6,3 +6,4 @@ killall @APPLICATION_EXECUTABLE@
|
||||
# Unload the Finder plugin. see issue #2105
|
||||
killall Finder
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh -x
|
||||
#!/bin/sh -xe
|
||||
|
||||
[ "$#" -lt 2 ] && echo "Usage: sign_app.sh <app> <identity>" && exit
|
||||
|
||||
@@ -7,6 +7,6 @@ identity="$2"
|
||||
|
||||
codesign -s "$identity" --force --verbose=4 --deep "$src_app"
|
||||
|
||||
# Just for our debug purposes:
|
||||
# Verify the signature
|
||||
spctl -a -t exec -vv $src_app
|
||||
codesign -dv $src_app
|
||||
|
||||
Arquivo executável
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: $(basename $0) directory_relative_to_home [uid]"
|
||||
exit
|
||||
fi
|
||||
|
||||
useradd user -u ${2:-1000}
|
||||
su - user << EOF
|
||||
cd /home/user/$1
|
||||
rm -rf build-win32
|
||||
mkdir build-win32
|
||||
cd build-win32
|
||||
../admin/win/download_runtimes.sh
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON
|
||||
make -j4
|
||||
make package
|
||||
ctest .
|
||||
EOF
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#VS2013
|
||||
base_url=http://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3
|
||||
tmp_path=/tmp/.vcredist
|
||||
tmp_path=${1:-/tmp/.vcredist}
|
||||
|
||||
mkdir -p $tmp_path
|
||||
|
||||
|
||||
@@ -10,24 +10,25 @@ minimum_perc = 5
|
||||
|
||||
# simple one-to-one language mappings
|
||||
trans.ca = pofiles/ca.po
|
||||
trans.el = pofiles/el.po
|
||||
trans.es = pofiles/es.po
|
||||
trans.es_AR = pofiles/es_AR.po
|
||||
trans.eu = pofiles/eu.po
|
||||
trans.fa = pofiles/fa.po
|
||||
trans.fr = pofiles/fr.po
|
||||
trans.gl = pofiles/gl.po
|
||||
trans.it = pofiles/it.po
|
||||
trans.nl = pofiles/nl.po
|
||||
trans.pl = pofiles/pl.po
|
||||
trans.pt_BR = pofiles/pt_BR.po
|
||||
trans.ru = pofiles/ru.po
|
||||
trans.el = pofiles/el.po
|
||||
trans.es_AR = pofiles/es_AR.po
|
||||
trans.es = pofiles/es.po
|
||||
trans.eu = pofiles/eu.po
|
||||
trans.fa = pofiles/fa.po
|
||||
trans.fr = pofiles/fr.po
|
||||
trans.gl = pofiles/gl.po
|
||||
trans.it = pofiles/it.po
|
||||
trans.nb_NO = pofiles/nb_NO.po
|
||||
trans.nl = pofiles/nl.po
|
||||
trans.pl = pofiles/pl.po
|
||||
trans.pt_BR = pofiles/pt_BR.po
|
||||
trans.ru = pofiles/ru.po
|
||||
trans.sl = pofiles/sl.po
|
||||
trans.sv = pofiles/sv.po
|
||||
trans.tr = pofiles/tr.po
|
||||
trans.uk = pofiles/uk.po
|
||||
trans.zh_TW = pofiles/zh_TW.po
|
||||
trans.zh_CN = pofiles/zh_CN.po
|
||||
trans.uk = pofiles/uk.po
|
||||
trans.zh_CN = pofiles/zh_CN.po
|
||||
trans.zh_TW = pofiles/zh_TW.po
|
||||
|
||||
# special handling below
|
||||
|
||||
@@ -35,14 +36,13 @@ trans.zh_CN = pofiles/zh_CN.po
|
||||
trans.de_DE = pofiles/de.po
|
||||
|
||||
# choose one of the given translations on transifex as default
|
||||
trans.pt_PT = pofiles/pt.po
|
||||
trans.pt_PT = pofiles/pt.po
|
||||
|
||||
# choose a special language as more generic default
|
||||
trans.cs_CZ = pofiles/cs.po
|
||||
trans.et_EE = pofiles/et.po
|
||||
trans.fi_FI = pofiles/fi.po
|
||||
trans.ja_JP = pofiles/ja.po
|
||||
trans.hu_HU = pofiles/hu.po
|
||||
trans.sk_SK = pofiles/sk.po
|
||||
trans.th_TH = pofiles/th.po
|
||||
|
||||
trans.cs_CZ = pofiles/cs.po
|
||||
trans.et_EE = pofiles/et.po
|
||||
trans.fi_FI = pofiles/fi.po
|
||||
trans.hu_HU = pofiles/hu.po
|
||||
trans.ja_JP = pofiles/ja.po
|
||||
trans.sk_SK = pofiles/sk.po
|
||||
trans.th_TH = pofiles/th.po
|
||||
|
||||
@@ -15,6 +15,8 @@ StrCpy $PageReinstall_SAME_Field_3 "Desinstal.lar ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Desinstal.lar ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Escolliu l'opció de manteniment per executar-ho."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Instal·lant ${APPLICATION_NAME} essencial."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integració per Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Instal·lant integració per Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Accés directe del programa al menú d'inici"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Afegint la drecera per ${APPLICATION_NAME} al menú d'inici."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Drecera a l'escriptori"
|
||||
@@ -42,5 +44,3 @@ StrCpy $INIT_INSTALLER_RUNNING "L'instal·lador ja s'està executant."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Aquest desinstal·lador requereix accés d'administrador, intenteu-ho de nou."
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "El desinstal·lador ja s'està executant."
|
||||
StrCpy $SectionGroup_Shortcuts "Dreceres"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
|
||||
@@ -15,16 +15,18 @@ StrCpy $PageReinstall_SAME_Field_3 "Desinstalli ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Desinstalli ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Vali hooldustegevus, mida sa soovid sooritada."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Paigaldan ${APPLICATION_NAME} põhiosa."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menüü Programmide viit"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Lisan ${APPLICATION_NAME} viida Start menüüsse."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integreerimine Windows Exploreriga"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Paigalda Windows Exploreriga integreerimine"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menüü programmide otsetee"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Lisan ${APPLICATION_NAME} otsetee Start menüüsse."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Töölaua otsetee"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Töölaua otseteede loomine"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Kiirvaliku nupp"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Kiirvaliku nupu loomine"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Kiirvaliku otsetee"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Kiirvaliku otsetee loomine"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} põhiosa."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME} otsetee."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Töölaua viit rakendusele ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Kiirvaliku viit rakendusele ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Töölaua otsetee rakendusele ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Kiirvaliku otsetee rakendusele ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Eemalda arvutist rakenduse ${APPLICATION_NAME} andmete kataloog."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Kas soovid kustutada ${APPLICATION_NAME} andmete kataloogi?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Jäta märkimata säilitamaks andmete kataloog hilisemaks kasutuseks või märgi andmete kataloogi kustutamiseks."
|
||||
@@ -34,13 +36,11 @@ StrCpy $UNINSTALLER_REGISTRY_Detail "Kirjutan paigaldaja registri v
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Lõpetatud"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Ei leia, et ${APPLICATION_NAME} oleks paigaldatud kataloogi '$INSTDIR'.$\n$\nJätkata sellele vaatamata (pole soovitav)?"
|
||||
StrCpy $UNINSTALL_ABORT "Desinstallimine on kasutaja poolt katkestatud"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Kiirvaliku viit (N/A)"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Kiirvaliku otsetee (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Ikoon töölaual (kirjutab olemasoleva üle)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Ei suuda ülendada õigusi, viga: "
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "See paigaldaja vajab admini ligipääsu, proovi uuesti"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Paigaldaja on juba käimas."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "See desinstallija vajab admini ligipääsu, proovi uuesti"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "See desinstallija on juba käimas"
|
||||
StrCpy $SectionGroup_Shortcuts "Viidad"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "See desinstallija on juba käimas."
|
||||
StrCpy $SectionGroup_Shortcuts "Otseteed"
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "نمایش پادداشت های انتشار نسخه"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "پردازش برای از بین بردن یافت نشد!"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "عمل حذف را قبل از نصب انجام دهید"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "حذف نکن"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "از قبل نصب شده است"
|
||||
StrCpy $PageReinstall_SAME_Field_2 "افزودن/نصب مجدد اجزا"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "بازکردن میانبر منو برنامه"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "افزودن میانبر ${APPLICATION_NAME} به استارت منو ."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "میانبر دسکتاپ"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "ایجاد میانبر دسکتاپ"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "میانبر بازکردن سریع"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "ایجاد میانبر اجرای سریع"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "ملزومات ${APPLICATION_NAME}"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "میانبر ${APPLICATION_NAME} "
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "میانبر دسکتاپ برای ${APPLICATION_NAME} ."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "میانبر اجرای سریع برای ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "حذف پوشه ی data نرم افزار ${APPLICATION_NAME} از روی سیستم شما ."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "آیا می خواهید پوشه ی data نرم افزار ${APPLICATION_NAME} را حذف نمایید ؟"
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "بله، این پوشه داده را حذف کن."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "نوشتن حذف کننده"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "در حال نوشتن کلید های رجیستری نصاب"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "اتمام"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "به نظر نمی رسد نرم افزار ${APPLICATION_NAME} در '$INSTDIR'.$\n$\nنصب شده باشد.\nآیا می خواهید ادامه دهید ( توصیه نشده است ) ؟"
|
||||
StrCpy $UNINSTALL_ABORT "عمل حذف توسط کاربر متوقف شد"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "میانبر بازکردن سریع ( N/A )"
|
||||
StrCpy $INIT_NO_DESKTOP "میانبر دسکتاپ (رونویسی وجود دارد)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "مشکل در بالااوردن ، خطا : "
|
||||
StrCpy $INIT_INSTALLER_RUNNING "نصاب از قبل در حال اجراست."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "حذف برنامه نیاز به دسترسی مدیر دارد ، لطفا دوباره سعی کنید"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "حذف کننده از قبل در حال اجراست."
|
||||
StrCpy $SectionGroup_Shortcuts "میانبرها"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $PageReinstall_NEW_Field_1 "An older version of ${APPLICATION_NAME} is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Uninstall before installing"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Choose how you want to install ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
|
||||
@@ -26,21 +42,5 @@ StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Choose the maintenance opti
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installing ${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menu Program Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Adding shortcut for ${APPLICATION_NAME} to the Start Menu."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creating Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME} shortcut."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Desktop shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Remove ${APPLICATION_NAME}'s data folder from your computer."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Do you want to delete ${APPLICATION_NAME}'s data folder?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Leave unchecked to keep the data folder for later use or check to delete the data folder."
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Writing Installer Registry Keys"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
|
||||
StrCpy $UNINSTALL_ABORT "Uninstall aborted by user"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Quick Launch Shortcut (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "This installer requires admin access, try again"
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "This uninstaller requires admin access, try again"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Afficher les notes de version"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Le(s) processus en cours d’exécution ${APPLICATION_EXECUTABLE} doit (doivent) être stoppé(s) afin de poursuivre.$\nVoulez-vous que le programme d’installation s’en charge pour vous ?"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Les processus ${APPLICATION_EXECUTABLE} en cours d’exécution doivent être stoppés avant de poursuivre.$\nVoulez-vous que le programme d’installation s’en charge pour vous ?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Fermeture des processus ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Le processus à stopper n'a pas été trouvé !"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Une ancienne version de ${APPLICATION_NAME} est installée sur votre système. Il est recommandé de désinstaller cette version avant de continuer. Sélectionnez l'opération que vous voulez exécuter et cliquez sur Suivant pour continuer."
|
||||
|
||||
@@ -39,8 +39,8 @@ StrCpy $UNINSTALL_ABORT "A desinstalaci
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Acceso de inicio rápido (n/d)"
|
||||
StrCpy $INIT_NO_DESKTOP "Atallo no escritorio (sobrescribe o existente)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Non foi posíbel elevalo, erro:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador require acceso de administrador, tenteo de novo"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador require acceso de administrador, ténteo de novo"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "O instalador xa está en execución."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este desinstalador require acceso de administrador, tenteo de novo"
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este desinstalador require acceso de administrador, ténteo de novo"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "O desinstalador xa está en execución."
|
||||
StrCpy $SectionGroup_Shortcuts "Atallos"
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Kiadási jegyzetek megtekintése"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "A következő folyamatot(okat) meg kell állítani ${APPLICATION_EXECUTABLE}.$\nSzeretné ha a telepítő program megállítani ezeket a folyamatokat?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Folyamat ${APPLICATION_EXECUTABLE} kilövése."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Kilövésre szánt folyamat nem található."
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Az ${APPLICATION_NAME} alkalmazás egy régebbi verziója telepítva van a rendszeren. Ajánlott a régi alkalmazás eltávolítása mielőtt a legfrissebb verziót telepítané. Válassza ki milyen műveletet szeretne végrehajtani, és nyomja meg a $\"Következő$\" gombot a folytatáshoz."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Eltávolítás telepítés előtt"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Ne távolítsa el"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Már telepítve"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Válaszd ki, hogy szeretnéd telepíteni a következő alkalmazást ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Az ${APPLICATION_NAME} alklamazás egy újabb verziója már megtalálható a rendszeren. Nem ajánlott egy régebbi verzió telepítése. Ha valóban szeretné a régebbi verziót telepíteni, akkor ajánlott a jelenleg telepített verzió eltávolítása. Válassza ki milyen műveletet szeretne végrehajtani, és nyomja meg a $\"Következő$\" gombot a folytatáshoz."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "Az ${APPLICATION_NAME} alkalmazás ${VERSION} verziója már telepítve van.\nKérem válassza ki milyen műveletet szeretne végrehajtan, és nyomja meg a $\"Következő$\" gombot."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Komponens hozzáadása/újratelepítése"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} eltávolítása"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} eltávolítása"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Kérem válassza ki milyen karbantartási műveletet szeretne elvégezni?"
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Az ${APPLICATION_NAME} alkalmazás lényeges komponenseinek telepítése."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Windows Explorer Integráció"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Windows Explorer Integráció Telepítése"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menü Parancsikonok"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "A ${APPLICATION_NAME} parancsikon hozzáadása a Start Menühöz"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Asztali Parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Asztali Parancsikon Létrehozása"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Gyorsindítás Eszköztár Parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Gyorsindítás Eszköztár Parancsikon Létrehozása"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} lényeges komponensek."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME} parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Asztali parancsikon a ${APPLICATION_NAME} alkalmazásnak."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Gyorsindítás eszköztár parancsikon a ${APPLICATION_NAME} alkalmazásnak."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Az ${APPLICATION_NAME} alkalmazás adatkönyvtárának eltávolítása a számítógépről."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "El szeretné távolítani az ${APPLICATION_NAME} alkalmazás adatkönyvtárát?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Hagyja bejelelöletlenül, hogy megtartsa az adatkönyvtárat későbbi használatra, vagy jelölje be az adatkönyvtár törléséhez."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Igen, törölje ezt az adatkönyvtárat."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Program Eltávolító Írása"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Telepítési registry kulcsok írása"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Befejezve"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Nem sikerült az ${APPLICATION_NAME} alkalmazás telepítése a '$INSTDIR' könyvtárba.$\n$\nSzeretné mindenképpen folytatni (nem ajánlott)?"
|
||||
StrCpy $UNINSTALL_ABORT "Az eltávolítást egy felhasználó megszakította"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Gyorsindító Hivatkozás (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Asztali Hivatkozás (felülírja a meglévőt)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Nem sikerült felemelni, hiba:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "A telepítő futtatásához adminisztrátori hozzáférés szükséges, próbáld újra."
|
||||
StrCpy $INIT_INSTALLER_RUNNING "A telepítő már fut."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Az eltávolító futtatásához adminisztrátori hozzáférés szükséges, próbáld újra."
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Az eltávolító már fut."
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Process to kill not found!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "An older version of ${APPLICATION_NAME} is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Choose the maintenance option to perform."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installing ${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menu Program Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Adding shortcut for ${APPLICATION_NAME} to the Start Menu."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Desktop Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creating Desktop Shortcuts"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creating Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME} shortcut."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Desktop shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Remove ${APPLICATION_NAME}'s data folder from your computer."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Do you want to delete ${APPLICATION_NAME}'s data folder?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Leave unchecked to keep the data folder for later use or check to delete the data folder."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Writing Uninstaller"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Writing Installer Registry Keys"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
|
||||
StrCpy $SectionGroup_Shortcuts "Shortcuts"
|
||||
StrCpy $SectionGroup_Shortcuts "Parancsikonok"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "リリースノートを表示"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "${APPLICATION_EXECUTABLE} のプロセスを終了する必要があります。\nインストーラーがそのプロセスを停止してもよろしいですか?"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "${APPLICATION_EXECUTABLE} のプロセスを終了する必要があります。$\nインストーラーがそのプロセスを停止してもよろしいですか?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "${APPLICATION_EXECUTABLE} プロセスを停止しています。"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "終了するプロセスがありません"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "システムに ${APPLICATION_NAME} の旧バージョンがインストールされています。\n旧バージョンをアンインストールし、最新バージョンをインストールするのをお勧めします。\nオペレーションを選択し、次へをクリックする。"
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Vis versjonsmerknader"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Fant ${APPLICATION_EXECUTABLE}-prosess(er) som må stoppes.$\nVil du at installasjonsprogrammet skal stoppe dem for deg?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Terminerer ${APPLICATION_EXECUTABLE}-prosesser."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Fant ikke prosess som skulle termineres!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "En eldre versjon av ${APPLICATION_NAME} er installert på systemet ditt. Det anbefales at du avnistallerer den versjonen før installering av ny versjon. Velg hva du vil gjøre og klikk Neste for å fortsette."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Avinstaller før installering"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Ikke avinstaller"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Allerede installert"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Velg hvordan du vil installere ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "En nyere versjon av ${APPLICATION_NAME} er allerede installert! Det anbefales ikke at du installerer en eldre versjon. Hvis du virkelig ønsker å installere denne eldre versjonen, er det bedre å avinstallere gjeldende versjon først. Velg hva du vil gjøre og klikk Neste for å fortsette."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} er allerede installert.\nVelg hva du vil gjøre og klikk Neste for å fortsette."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Legg til/installer komponenter på nytt"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Avinstaller ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Avinstaller ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Velg hva slags vedlikehold som skal utføres."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installerer ${APPLICATION_NAME} grunnleggende."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integrering med Windows Utforsker"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installerer integrering med Windows Utforsker"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Snarvei i Start-menyen"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Legger til snarvei for ${APPLICATION_NAME} i Start-menyen."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Snarvei på skrivebordet"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Oppretter snarveier på skrivebordet"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Snarvei i Hurtigstart"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Oppretter snarvei i Hurtigstart"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} grunnleggende."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME}-snarvei."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Skrivebordssnarvei for ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Hurtigstart-snarvei for ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Fjern ${APPLICATION_NAME} sin datamappe fra datamaskinen."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Ønsker du å slette ${APPLICATION_NAME} sin datamappe?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Ikke kryss av dersom du vil beholde datamappen for senere bruk. Kryss av for å slette mappen."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Ja, slett denne datamappen."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Skriver Avinstallasjonsprogram."
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Skriver registernøkler for installasjonsprogrammet"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Ferdig"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Det ser ikke ut som ${APPLICATION_NAME} er installert i mappe '$INSTDIR'.$\n$\nFortsett likevel (ikke anbefalt)?"
|
||||
StrCpy $UNINSTALL_ABORT "Avinstallering avbrutt av bruker"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Hurtigstart-snarvei (I/T)"
|
||||
StrCpy $INIT_NO_DESKTOP "Snarvei på skrivebordet (skriver over eksisterende)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Klarte ikke å heve tilgangsnivå. Feil: "
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Dette installasjonsprogrammet krever administrasjonstilgang. Prøv igjen"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Installasjonsprogrammet kjører allerede."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Avinstallasjonsprogrammet krever administrasjonstilgang. Prøv igjen"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Avinstallasjonsprogrammet kjører allerede."
|
||||
StrCpy $SectionGroup_Shortcuts "Snarveier"
|
||||
@@ -0,0 +1,46 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "แสดงบันทึกประจำรุ่น"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "พบว่ากระบวนการ ${APPLICATION_EXECUTABLE} จะต้องหยุดทำงาน\nคุณต้องการติดตั้งเพื่อหยุดการทำงานเหล่านี้ของคุณ?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "ฆ่ากระบวนการทำงาน ${APPLICATION_EXECUTABLE}"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "ไม่พบการฆ่ากระบวนการ!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "รุ่นเก่าของ ${APPLICATION_NAME} มีการติดตั้งในระบบของคุณ ขอแนะนำให้คุณถอนการติดตั้งรุ่นปัจจุบันออกก่อน เลือกการดำเนินการที่คุณต้องการที่จะดำเนินการและคลิกถัดไปเพื่อดำเนินการต่อ"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "ถอนการติดตั้งก่อนการติดตั้ง"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "อย่าถอนการติดตั้ง"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "ติดตั้งแล้ว"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "เลือกวิธีที่คุณต้องการติดตั้ง ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "รุ่นใหม่ของ ${APPLICATION_NAME} ถูกติดตั้งแล้ว! เราไม่แนะนำให้คุณติดตั้งรุ่นเก่า ถ้าคุณอยากจะติดตั้งรุ่นเก่าก็สามารถสอนการติดตั้งได้"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} ได้ถูกติดตั้งแล้ว เลือกการดำเนินการที่คุณต้องการที่จะดำเนินการและคลิกถัดไปเพื่อดำเนินการต่อ"
|
||||
StrCpy $PageReinstall_SAME_Field_2 "ส่วนประกอบ เพิ่ม/ติดตั้งใหม่ "
|
||||
StrCpy $PageReinstall_SAME_Field_3 "ถอนการติดตั้ง ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "ถอนการติดตั้ง ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "เลือกตัวเลือกการบำรุงรักษาเพื่อดำเนินการ"
|
||||
StrCpy $SEC_APPLICATION_DETAILS "กำลังติดตั้งข้อมูลที่เป็นเป็นของ ${APPLICATION_NAME}"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "บูรณาการสำหรับ Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "บูรณาการกำลังติดตั้งสำหรับ Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "โปรแกรมทางลัดเมนูเริ่มต้น"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "เพิ่มทางลัดสำหรับ ${APPLICATION_NAME} ที่เมนูเริ่มต้น"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "ทางลัดพื้นโต๊ะ"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "สร้างทางลัดบนเดสก์ทอป"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "ทางลัดเร่งด่วน"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "สร้างทางลัดเร่งด่วน"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} ที่จำเป็น"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "ทางลัด ${APPLICATION_NAME}"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "ทางลัดบนเดสก์ทอปสำหรับ ${APPLICATION_NAME}"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "ทางลัดเร่งด่วนสำหรับ ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "ลบ ${APPLICATION_NAME} ของโฟลเดอร์ข้อมูลจากคอมพิวเตอร์ของคุณ"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "คุณต้องการลบ ${APPLICATION_NAME} ของโฟลเดอร์ข้อมูล?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "ปล่อยให้ตรวจสอบสำหรับใช้โฟลเดอร์ข้อมูลในภายหลังหรือตรวจสอบเพื่อลบโฟลเดอร์ข้อมูล"
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "ใช่ลบโฟลเดอร์ข้อมูลนี้"
|
||||
StrCpy $UNINSTALLER_FILE_Detail "กำลังถอนการติดตั้ง"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "กำลังติดตั้งรหัสรีจิสทรี"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "เสร็จสิ้น"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "มันจะไม่ปรากฏ ${APPLICATION_NAME} ที่มีการติดตั้งในไดเรกทอรี '$INSTDIR' ดำเนินการต่อไป (ไม่แนะนำ)?"
|
||||
StrCpy $UNINSTALL_ABORT "ถอนการติดตั้งถูกยกเลิกโดยผู้ใช้"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "ทางลัดเร่งด่วน (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "ทางลัดเดสก์ทอป (จะเขียนทับหากมีอยู่แล้ว)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "ไม่สามารถที่จะยกระดับข้อผิดพลาด:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "การติดตั้งนี้จะต้องมีการเข้าถึงผู้ดูแลระบบ กรุณาลองอีกครั้ง"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "กำลังทำการติดตั้ง"
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "การถอนการติดตั้งนี้จะต้องมีการเข้าถึงส่วนผู้ดูแลระบบ กรุณาลองอีกครั้ง"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "กำลังทำการถอนการติดตั้ง"
|
||||
StrCpy $SectionGroup_Shortcuts "ทางลัด"
|
||||
@@ -67,7 +67,7 @@ localeToName = {
|
||||
"mg" : "Malagasy",
|
||||
"ms" : "Malay",
|
||||
"mn" : "Mongolian",
|
||||
"nb" : "Norwegian",
|
||||
"nb_NO" : "Norwegian",
|
||||
"nn" : "NorwegianNynorsk",
|
||||
"ps" : "Pashto",
|
||||
"pl" : "Polish",
|
||||
|
||||
@@ -44,5 +44,6 @@ iconv -t CP1252 -o Finnish.nsh Finnish.nsh
|
||||
iconv -t CP932 -o Japanese.nsh Japanese.nsh
|
||||
iconv -t CP1250 -o Slovak.nsh Slovak.nsh
|
||||
iconv -t CP1254 -o Turkish.nsh Turkish.nsh
|
||||
iconv -t CP1252 -o Norwegian.nsh Norwegian.nsh
|
||||
|
||||
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
!insertmacro MUI_LANGUAGE "Hungarian"
|
||||
!insertmacro MUI_LANGUAGE "Ukrainian"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Norwegian"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "Thai"
|
||||
!insertmacro MUI_LANGUAGE "Finnish"
|
||||
!insertmacro MUI_LANGUAGE "Basque"
|
||||
!insertmacro MUI_LANGUAGE "Greek"
|
||||
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "Portuguese"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
|
||||
+1
-1
Submodule binary updated: 01d73965dc...8b72648a93
@@ -175,10 +175,11 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${VERSION}"
|
||||
StrCmp $LANGUAGE ${LANG_ITALIAN} Italian 0
|
||||
StrCmp $LANGUAGE ${LANG_ESTONIAN} Estonian 0
|
||||
StrCmp $LANGUAGE ${LANG_GREEK} Greek 0
|
||||
StrCmp $LANGUAGE ${LANG_GREEK} Basque 0
|
||||
StrCmp $LANGUAGE ${LANG_GREEK} Galician 0
|
||||
StrCmp $LANGUAGE ${LANG_GREEK} Slovak 0
|
||||
StrCmp $LANGUAGE ${LANG_GREEK} Turkish 0
|
||||
StrCmp $LANGUAGE ${LANG_BASQUE} Basque 0
|
||||
StrCmp $LANGUAGE ${LANG_GALICIAN} Galician 0
|
||||
StrCmp $LANGUAGE ${LANG_SLOVAC} Slovak 0
|
||||
StrCmp $LANGUAGE ${LANG_TURKISH} Turkish 0
|
||||
StrCmp $LANGUAGE ${LANG_NORWEGIAN} Norwegian 0
|
||||
StrCmp $LANGUAGE ${LANG_PORTUGUESEBR} Brazilian EndLanguageCmp
|
||||
German:
|
||||
!include "${source_path}/admin/win/nsi/l10n\German.nsh"
|
||||
@@ -221,6 +222,9 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${VERSION}"
|
||||
Goto EndLanguageCmp
|
||||
Brazilian:
|
||||
!include "${source_path}/admin/win/nsi/l10n\PortugueseBR.nsh"
|
||||
Goto EndLanguageCmp
|
||||
Norwegian:
|
||||
!include "${source_path}/admin/win/nsi/l10n\Norwegian.nsh"
|
||||
EndLanguageCmp:
|
||||
|
||||
FunctionEnd
|
||||
@@ -445,7 +449,7 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
File "${MING_BIN}\libcrypto-10.dll"
|
||||
File "${MING_BIN}\libssl-10.dll"
|
||||
File "${MING_BIN}\libstdc++-6.dll"
|
||||
File "${MING_BIN}\libwebp-4.dll"
|
||||
File "${MING_BIN}\libwebp-5.dll"
|
||||
File "${MING_BIN}\libxslt-1.dll"
|
||||
File "${MING_BIN}\libxml2-2.dll"
|
||||
File "${MING_BIN}\zlib1.dll"
|
||||
@@ -475,6 +479,7 @@ SectionEnd
|
||||
CreateDirectory "$INSTDIR\shellext"
|
||||
!define LIBRARY_COM
|
||||
!define LIBRARY_SHELL_EXTENSION
|
||||
!define LIBRARY_IGNORE_VERSION
|
||||
${If} ${RunningX64}
|
||||
!define LIBRARY_X64
|
||||
!insertmacro InstallLib DLL NOTSHARED REBOOT_PROTECTED "${SOURCE_PATH}\binary\shell_integration\windows\Release\x64\OCUtil_x64.dll" "$INSTDIR\shellext\OCUtil_x64.dll" "$INSTDIR\shellext"
|
||||
@@ -488,6 +493,7 @@ SectionEnd
|
||||
${Endif}
|
||||
!undef LIBRARY_COM
|
||||
!undef LIBRARY_SHELL_EXTENSION
|
||||
!undef LIBRARY_IGNORE_VERSION
|
||||
${MementoSectionEnd}
|
||||
!endif
|
||||
|
||||
@@ -646,6 +652,7 @@ Section Uninstall
|
||||
!ifdef OPTION_SECTION_SC_SHELL_EXT
|
||||
!define LIBRARY_COM
|
||||
!define LIBRARY_SHELL_EXTENSION
|
||||
!define LIBRARY_IGNORE_VERSION
|
||||
${If} ${HasSection} SEC_SHELL_EXT
|
||||
DetailPrint "Uninstalling x64 overlay DLLs"
|
||||
!define LIBRARY_X64
|
||||
@@ -661,6 +668,7 @@ Section Uninstall
|
||||
${EndIf}
|
||||
!undef LIBRARY_COM
|
||||
!undef LIBRARY_SHELL_EXTENSION
|
||||
!undef LIBRARY_IGNORE_VERSION
|
||||
!endif
|
||||
|
||||
;Start menu shortcut
|
||||
@@ -777,7 +785,7 @@ Function .onInit
|
||||
goto UAC_Elevate
|
||||
|
||||
;Prevent multiple instances.
|
||||
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "owncloudInstaller") i .r1 ?e'
|
||||
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${APPLICATION_SHORTNAME}Installer") i .r1 ?e'
|
||||
Pop $R0
|
||||
StrCmp $R0 0 +3
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION $INIT_INSTALLER_RUNNING
|
||||
@@ -842,7 +850,7 @@ Function un.onInit
|
||||
goto UAC_Elevate
|
||||
|
||||
;Prevent multiple instances.
|
||||
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "owncloudUninstaller") i .r1 ?e'
|
||||
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${APPLICATION_SHORTNAME}Uninstaller") i .r1 ?e'
|
||||
Pop $R0
|
||||
StrCmp $R0 0 +3
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION $INIT_UNINSTALLER_RUNNING
|
||||
|
||||
@@ -17,6 +17,7 @@ if( Qt5Core_FOUND )
|
||||
message(STATUS "Found Qt5 core, checking for further dependencies...")
|
||||
find_package(Qt5Network REQUIRED)
|
||||
find_package(Qt5Xml REQUIRED)
|
||||
find_package(Qt5Concurrent REQUIRED)
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
find_package(Qt5WebKitWidgets REQUIRED)
|
||||
find_package(Qt5WebKit REQUIRED)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#cmakedefine APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@"
|
||||
#cmakedefine APPLICATION_UPDATE_URL "@APPLICATION_UPDATE_URL@"
|
||||
|
||||
#cmakedefine ZLIB_FOUND @ZLIB_FOUND@
|
||||
|
||||
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
|
||||
#cmakedefine DATADIR "@DATADIR@"
|
||||
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
# global needed variables
|
||||
set(APPLICATION_NAME "ocsync")
|
||||
|
||||
set(APPLICATION_VERSION_MAJOR "0")
|
||||
set(APPLICATION_VERSION_MINOR "91")
|
||||
set(APPLICATION_VERSION_PATCH "5")
|
||||
|
||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||
|
||||
set(LIBRARY_VERSION "0.2.1")
|
||||
set(LIBRARY_VERSION ${MIRALL_VERSION})
|
||||
set(LIBRARY_SOVERSION "0")
|
||||
|
||||
# add definitions
|
||||
|
||||
+16
-8
@@ -386,6 +386,20 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
|
||||
SAFE_FREE(renamed_path);
|
||||
}
|
||||
|
||||
if (!other_node) {
|
||||
/* Check the source path as well. */
|
||||
int len;
|
||||
uint64_t h = 0;
|
||||
char *renamed_path = csync_rename_adjust_path_source(ctx, cur->path);
|
||||
|
||||
if (!c_streq(renamed_path, cur->path)) {
|
||||
len = strlen( renamed_path );
|
||||
h = c_jhash64((uint8_t *) renamed_path, len, 0);
|
||||
other_node = c_rbtree_find(other_tree, &h);
|
||||
}
|
||||
SAFE_FREE(renamed_path);
|
||||
}
|
||||
|
||||
if (obj == NULL || data == NULL) {
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
return -1;
|
||||
@@ -576,7 +590,8 @@ int csync_commit(CSYNC *ctx) {
|
||||
_csync_clean_ctx(ctx);
|
||||
|
||||
ctx->remote.read_from_db = 0;
|
||||
ctx->read_from_db_disabled = 0;
|
||||
ctx->read_remote_from_db = true;
|
||||
ctx->db_is_empty = false;
|
||||
|
||||
|
||||
/* Create new trees */
|
||||
@@ -773,10 +788,3 @@ int csync_set_module_property(CSYNC* ctx, const char* key, void* value)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int csync_set_read_from_db(CSYNC* ctx, int enabled)
|
||||
{
|
||||
ctx->read_from_db_disabled = !enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+2
-8
@@ -40,8 +40,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <config_csync.h>
|
||||
|
||||
#include "csync_version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -106,7 +104,8 @@ enum csync_status_codes_e {
|
||||
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
|
||||
CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME,
|
||||
CYSNC_STATUS_FILE_LOCKED_OR_OPEN
|
||||
CYSNC_STATUS_FILE_LOCKED_OR_OPEN,
|
||||
CSYNC_STATUS_INDIVIDUAL_STAT_FAILED
|
||||
};
|
||||
|
||||
typedef enum csync_status_codes_e CSYNC_STATUS;
|
||||
@@ -550,11 +549,6 @@ void csync_resume(CSYNC *ctx);
|
||||
*/
|
||||
int csync_abort_requested(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* Specify if it is allowed to read the remote tree from the DB (default to enabled)
|
||||
*/
|
||||
int csync_set_read_from_db(CSYNC* ctx, int enabled);
|
||||
|
||||
char *csync_normalize_etag(const char *);
|
||||
time_t oc_httpdate_parse( const char *date );
|
||||
|
||||
|
||||
@@ -151,11 +151,12 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
|
||||
return match;
|
||||
}
|
||||
|
||||
// See http://support.microsoft.com/kb/74496
|
||||
static const char *win_reserved_words[] = {"CON","PRN","AUX", "NUL",
|
||||
"COM1", "COM2", "COM3", "COM4",
|
||||
"LPT1", "LPT2", "LPT3", "CLOCK$" };
|
||||
|
||||
// See http://support.microsoft.com/kb/74496 and
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
|
||||
// Additionally, we ignore '$Recycle.Bin', see https://github.com/owncloud/client/issues/2955
|
||||
static const char* win_reserved_words[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5",
|
||||
"COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4",
|
||||
"LPT5", "LPT6", "LPT7", "LPT8", "LPT9", "CLOCK$", "$Recycle.Bin" };
|
||||
|
||||
bool csync_is_windows_reserved_word(const char* filename) {
|
||||
|
||||
@@ -232,6 +233,7 @@ CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path
|
||||
}
|
||||
|
||||
// check the strlen and ignore the file if its name is longer than 254 chars.
|
||||
// whenever changing this also check createDownloadTmpFileName
|
||||
if (strlen(bname) > 254) {
|
||||
match = CSYNC_FILE_EXCLUDE_LONG_FILENAME;
|
||||
SAFE_FREE(bname);
|
||||
|
||||
@@ -27,7 +27,8 @@ enum csync_exclude_type_e {
|
||||
CSYNC_FILE_EXCLUDE_AND_REMOVE,
|
||||
CSYNC_FILE_EXCLUDE_LIST,
|
||||
CSYNC_FILE_EXCLUDE_INVALID_CHAR,
|
||||
CSYNC_FILE_EXCLUDE_LONG_FILENAME
|
||||
CSYNC_FILE_EXCLUDE_LONG_FILENAME,
|
||||
CSYNC_FILE_EXCLUDE_STAT_FAILED
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ enum csync_log_priority_e {
|
||||
};
|
||||
|
||||
#define CSYNC_LOG(priority, ...) \
|
||||
csync_log(priority, __FUNCTION__, __VA_ARGS__)
|
||||
csync_log(priority, __func__, __VA_ARGS__)
|
||||
|
||||
void csync_log(int verbosity,
|
||||
const char *function,
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "csync_private.h"
|
||||
|
||||
#include "csync_version.h"
|
||||
|
||||
|
||||
/*
|
||||
* helper method to build up a user text for SSL problems, called from the
|
||||
@@ -437,8 +439,8 @@ int dav_connect(CSYNC *csyncCtx, const char *base_url) {
|
||||
// Should never take more than some seconds, 30 is really a max.
|
||||
ne_set_connect_timeout(ctx->dav_session.ctx, 30);
|
||||
|
||||
snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) csyncoC/%s",
|
||||
csync_owncloud_get_platform(), CSYNC_STRINGIFY( LIBCSYNC_VERSION ));
|
||||
snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) mirall/%s (csyncoC)",
|
||||
CSYNC_STRINGIFY( MIRALL_VERSION ), csync_owncloud_get_platform() );
|
||||
ne_set_useragent( ctx->dav_session.ctx, uaBuf);
|
||||
ne_set_server_auth(ctx->dav_session.ctx, authentication_callback_by_neon, ctx);
|
||||
|
||||
|
||||
@@ -151,7 +151,17 @@ struct csync_s {
|
||||
int status;
|
||||
volatile int abort;
|
||||
void *rename_info;
|
||||
int read_from_db_disabled;
|
||||
|
||||
/**
|
||||
* Specify if it is allowed to read the remote tree from the DB (default to enabled)
|
||||
*/
|
||||
bool read_remote_from_db;
|
||||
|
||||
/**
|
||||
* If true, the DB is considered empty and all reads are skipped. (default is false)
|
||||
* This is useful during the initial local discovery as it speeds it up significantly.
|
||||
*/
|
||||
bool db_is_empty;
|
||||
|
||||
struct csync_owncloud_ctx_s *owncloud_context;
|
||||
|
||||
|
||||
@@ -156,8 +156,8 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
}
|
||||
|
||||
if( tmp ) {
|
||||
if( tmp->path ) {
|
||||
len = strlen( tmp->path );
|
||||
len = strlen( tmp->path );
|
||||
if( len > 0 ) {
|
||||
h = c_jhash64((uint8_t *) tmp->path, len, 0);
|
||||
/* First, check that the file is NOT in our tree (another file with the same name was added) */
|
||||
node = c_rbtree_find(ctx->current == REMOTE_REPLICA ? ctx->remote.tree : ctx->local.tree, &h);
|
||||
|
||||
@@ -43,6 +43,7 @@ struct csync_rename_s {
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> folder_renamed_to; // map from->to
|
||||
std::map<std::string, std::string> folder_renamed_from; // map to->from
|
||||
|
||||
struct renameop {
|
||||
csync_file_stat_t *st;
|
||||
@@ -63,6 +64,7 @@ void csync_rename_destroy(CSYNC* ctx)
|
||||
void csync_rename_record(CSYNC* ctx, const char* from, const char* to)
|
||||
{
|
||||
csync_rename_s::get(ctx)->folder_renamed_to[from] = to;
|
||||
csync_rename_s::get(ctx)->folder_renamed_from[to] = from;
|
||||
}
|
||||
|
||||
char* csync_rename_adjust_path(CSYNC* ctx, const char* path)
|
||||
@@ -78,4 +80,18 @@ char* csync_rename_adjust_path(CSYNC* ctx, const char* path)
|
||||
return c_strdup(path);
|
||||
}
|
||||
|
||||
char* csync_rename_adjust_path_source(CSYNC* ctx, const char* path)
|
||||
{
|
||||
csync_rename_s* d = csync_rename_s::get(ctx);
|
||||
for (std::string p = _parentDir(path); !p.empty(); p = _parentDir(p)) {
|
||||
std::map< std::string, std::string >::iterator it = d->folder_renamed_from.find(p);
|
||||
if (it != d->folder_renamed_from.end()) {
|
||||
std::string rep = it->second + (path + p.length());
|
||||
return c_strdup(rep.c_str());
|
||||
}
|
||||
}
|
||||
return c_strdup(path);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Return the final destination path of a given patch in case of renames */
|
||||
char *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
||||
/* Return the source of a given path in case of renames */
|
||||
char *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
|
||||
void csync_rename_destroy(CSYNC *ctx);
|
||||
void csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "csync_statedb.h"
|
||||
#include "csync_util.h"
|
||||
#include "csync_misc.h"
|
||||
#include "csync_exclude.h"
|
||||
|
||||
#include "c_string.h"
|
||||
#include "c_jhash.h"
|
||||
@@ -298,7 +299,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
|
||||
csync_file_stat_t *st = NULL;
|
||||
int rc;
|
||||
|
||||
if( !ctx ) {
|
||||
if( !ctx || ctx->db_is_empty ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -341,7 +342,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !ctx ) {
|
||||
if( !ctx || ctx->db_is_empty ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -381,7 +382,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( !ctx ) {
|
||||
if( !ctx || ctx->db_is_empty ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -448,7 +449,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !ctx ) {
|
||||
if( !ctx || ctx->db_is_empty ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -481,6 +482,22 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
|
||||
rc = _csync_file_stat_from_metadata_table( &st, stmt);
|
||||
if( st ) {
|
||||
/* Check for exclusion from the tree.
|
||||
* Note that this is only a safety net in case the ignore list changes
|
||||
* without a full remote discovery being triggered. */
|
||||
CSYNC_EXCLUDE_TYPE excluded = csync_excluded(ctx, st->path, st->type);
|
||||
if (excluded != CSYNC_NOT_EXCLUDED) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path, excluded);
|
||||
|
||||
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
|
||||
|| excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
|
||||
SAFE_FREE(st);
|
||||
continue;
|
||||
}
|
||||
|
||||
st->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
}
|
||||
|
||||
/* store into result list. */
|
||||
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
|
||||
SAFE_FREE(st);
|
||||
|
||||
@@ -171,8 +171,12 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if file is excluded */
|
||||
excluded = csync_excluded(ctx, path,type);
|
||||
if (type == CSYNC_FTW_TYPE_SKIP) {
|
||||
excluded =CSYNC_FILE_EXCLUDE_STAT_FAILED;
|
||||
} else {
|
||||
/* Check if file is excluded */
|
||||
excluded = csync_excluded(ctx, path,type);
|
||||
}
|
||||
|
||||
if (excluded != CSYNC_NOT_EXCLUDED) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", path, excluded);
|
||||
@@ -241,11 +245,6 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore non statable files and other strange cases. */
|
||||
if (type == CSYNC_FTW_TYPE_SKIP) {
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
goto out;
|
||||
}
|
||||
if (excluded > CSYNC_NOT_EXCLUDED || type == CSYNC_FTW_TYPE_SLINK) {
|
||||
if( type == CSYNC_FTW_TYPE_SLINK ) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK; /* Symbolic links are ignored. */
|
||||
@@ -306,7 +305,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
|| !c_streq(fs->remotePerm, tmp->remotePerm)))
|
||||
|| (ctx->current == LOCAL_REPLICA && fs->inode != tmp->inode);
|
||||
if (type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
|
||||
&& !metadata_differ && !ctx->read_from_db_disabled) {
|
||||
&& !metadata_differ && ctx->read_remote_from_db) {
|
||||
/* If both etag and file id are equal for a directory, read all contents from
|
||||
* the database.
|
||||
* The metadata comparison ensure that we fetch all the file id or permission when
|
||||
@@ -418,6 +417,8 @@ out:
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS; /* File contains invalid characters. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_LONG_FILENAME) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME; /* File name is too long. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_STAT_FAILED) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_STAT_FAILED;
|
||||
}
|
||||
}
|
||||
if (st->instruction != CSYNC_INSTRUCTION_NONE && st->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
@@ -621,7 +622,12 @@ 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_STORAGE_UNAVAILABLE) {
|
||||
}
|
||||
// The server usually replies with the custom "503 Storage not available"
|
||||
// if some path is temporarily unavailable. But in some cases a standard 503
|
||||
// is returned too. Thus we can't distinguish the two and will treat any
|
||||
// 503 as request to ignore the folder. See #3113 #2884.
|
||||
else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
|
||||
if (ctx->current_fs) {
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
|
||||
@@ -28,22 +28,7 @@ extern "C" {
|
||||
#define CSYNC_STRINGIFY(s) CSYNC_TOSTRING(s)
|
||||
#define CSYNC_TOSTRING(s) #s
|
||||
|
||||
/* csync version macros */
|
||||
#define CSYNC_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
|
||||
#define CSYNC_VERSION_DOT(a, b, c) a ##.## b ##.## c
|
||||
#define CSYNC_VERSION(a, b, c) CSYNC_VERSION_DOT(a, b, c)
|
||||
|
||||
/* csync version */
|
||||
#define LIBCSYNC_VERSION_MAJOR @APPLICATION_VERSION_MAJOR@
|
||||
#define LIBCSYNC_VERSION_MINOR @APPLICATION_VERSION_MINOR@
|
||||
#define LIBCSYNC_VERSION_MICRO @APPLICATION_VERSION_PATCH@
|
||||
|
||||
#define LIBCSYNC_VERSION_INT CSYNC_VERSION_INT(LIBCSYNC_VERSION_MAJOR, \
|
||||
LIBCSYNC_VERSION_MINOR, \
|
||||
LIBCSYNC_VERSION_MICRO)
|
||||
#define LIBCSYNC_VERSION CSYNC_VERSION(LIBCSYNC_VERSION_MAJOR, \
|
||||
LIBCSYNC_VERSION_MINOR, \
|
||||
LIBCSYNC_VERSION_MICRO)
|
||||
#define MIRALL_VERSION @MIRALL_VERSION@
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#define DEBUG_HBF(...) { if(transfer->log_cb) { \
|
||||
char buf[1024]; \
|
||||
snprintf(buf, 1024, __VA_ARGS__); \
|
||||
transfer->log_cb(__FUNCTION__, buf, transfer->user_data); \
|
||||
transfer->log_cb(__func__, buf, transfer->user_data); \
|
||||
} }
|
||||
|
||||
// #endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync.h"
|
||||
#include "csync_log.h"
|
||||
|
||||
csync_vio_file_stat_t *csync_vio_file_stat_new(void) {
|
||||
csync_vio_file_stat_t *file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t));
|
||||
@@ -30,7 +31,9 @@ csync_vio_file_stat_t *csync_vio_file_stat_new(void) {
|
||||
csync_vio_file_stat_t* csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat) {
|
||||
csync_vio_file_stat_t *file_stat_cpy = csync_vio_file_stat_new();
|
||||
memcpy(file_stat_cpy, file_stat, sizeof(csync_vio_file_stat_t));
|
||||
file_stat_cpy->etag = c_strdup(file_stat_cpy->etag);
|
||||
if (file_stat_cpy->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
|
||||
file_stat_cpy->etag = c_strdup(file_stat_cpy->etag);
|
||||
}
|
||||
if (file_stat_cpy->directDownloadCookies) {
|
||||
file_stat_cpy->directDownloadCookies = c_strdup(file_stat_cpy->directDownloadCookies);
|
||||
}
|
||||
@@ -68,6 +71,7 @@ void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t *dst, const char* sr
|
||||
void csync_vio_set_file_id( char* dst, const char *src ) {
|
||||
if( src && dst ) {
|
||||
if( strlen(src) > FILE_ID_BUF_SIZE ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Ignoring file_id because it is too long: %s", src);
|
||||
strcpy(dst, "");
|
||||
} else {
|
||||
strcpy(dst, src);
|
||||
|
||||
@@ -131,7 +131,7 @@ static void check_logging(void **state)
|
||||
rc = csync_set_log_callback(check_log_callback);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
csync_log(1, __FUNCTION__, "rc = %d", rc);
|
||||
csync_log(1, __func__, "rc = %d", rc);
|
||||
|
||||
rc = _tstat(path, &sb);
|
||||
|
||||
|
||||
@@ -124,7 +124,8 @@ sub initTesting(;$)
|
||||
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0
|
||||
}
|
||||
|
||||
$d = HTTP::DAV->new();
|
||||
my $ua = HTTP::DAV::UserAgent->new(keep_alive => 1 );
|
||||
$d = HTTP::DAV->new(-useragent => $ua);
|
||||
|
||||
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
|
||||
-user=> $user,
|
||||
@@ -191,7 +192,6 @@ sub removeRemoteDir($;$)
|
||||
my ($dir, $optionsRef) = @_;
|
||||
|
||||
my $url = testDirUrl() . $dir;
|
||||
|
||||
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
|
||||
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
|
||||
-user=> $optionsRef->{user},
|
||||
@@ -326,11 +326,11 @@ sub assertLocalDirs( $$ )
|
||||
|
||||
opendir(my $dh, $dir1 ) || die;
|
||||
while(readdir $dh) {
|
||||
assert( -e "$dir2/$_" );
|
||||
assert( -e "$dir2/$_", " $dir2/$_ do not exist" );
|
||||
next if( -d "$dir1/$_"); # don't compare directory sizes.
|
||||
my $s1 = -s "$dir1/$_";
|
||||
my $s2 = -s "$dir2/$_";
|
||||
assert( $s1 == $s2, "$dir1/$_ <-> $dir2/$_" );
|
||||
assert( $s1 == $s2, "$dir1/$_ <-> $dir2/$_ size not equal ($s1 != $s2)" );
|
||||
}
|
||||
closedir $dh;
|
||||
}
|
||||
@@ -524,7 +524,9 @@ sub put_to_dir( $$;$ )
|
||||
|
||||
my $filename = $file;
|
||||
$filename =~ s/^.*\///;
|
||||
$filename =~ s/#/%23/g; # poor man's URI encoder
|
||||
my $puturl = $targetUrl . $dir. $filename;
|
||||
|
||||
print "put_to_dir puts to $puturl\n";
|
||||
unless ($d->put( -local => $file, -url => $puturl )) {
|
||||
print " ### FAILED to put a single file!\n";
|
||||
|
||||
Arquivo executável
+85
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Test script for the ownCloud module of csync.
|
||||
# This script requires a running ownCloud instance accessible via HTTP.
|
||||
# It does quite some fancy tests and asserts the results.
|
||||
#
|
||||
# Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library 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
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
use strict;
|
||||
|
||||
print "Hello, this is t_recall, a tester for the recall feature\n";
|
||||
|
||||
initTesting();
|
||||
|
||||
printInfo( "Syncing two files with the same name that differ with case" );
|
||||
|
||||
#create some files
|
||||
my $tmpdir = "/tmp/t_recall/";
|
||||
mkdir($tmpdir);
|
||||
createLocalFile( $tmpdir . "file1.dat", 100 );
|
||||
createLocalFile( $tmpdir . "file2.dat", 150 );
|
||||
createLocalFile( $tmpdir . "file3.dat", 110 );
|
||||
createLocalFile( $tmpdir . "file4.dat", 170 );
|
||||
|
||||
#put them in some directories
|
||||
createRemoteDir( "dir" );
|
||||
glob_put( "$tmpdir/*", "dir" );
|
||||
|
||||
csync();
|
||||
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
|
||||
|
||||
printInfo( "Testing with a .sys.admin#recall#" );
|
||||
system("echo 'dir/file2.dat' > ". $tmpdir . ".sys.admin\#recall\#");
|
||||
system("echo 'dir/file3.dat' >> ". $tmpdir . ".sys.admin\#recall\#");
|
||||
glob_put( "$tmpdir/.sys.admin\#recall\#", "" );
|
||||
|
||||
csync();
|
||||
|
||||
#test that the recall files have been created
|
||||
assert( -e glob(localDir().'dir/file2_.sys.admin#recall#-*.dat' ) );
|
||||
assert( -e glob(localDir().'dir/file3_.sys.admin#recall#-*.dat' ) );
|
||||
|
||||
#Remove the recall file
|
||||
unlink(localDir() . ".sys.admin#recall#");
|
||||
|
||||
# 2 sync necessary for the recall to be uploaded
|
||||
csync();
|
||||
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
printInfo( "Testing with a dir/.sys.admin#recall#" );
|
||||
system("echo 'file4.dat' > ". $tmpdir . ".sys.admin\#recall\#");
|
||||
glob_put( "$tmpdir/.sys.admin\#recall\#", "dir" );
|
||||
|
||||
csync();
|
||||
assert( -e glob(localDir().'dir/file4_.sys.admin#recall#-*.dat' ) );
|
||||
|
||||
|
||||
cleanup();
|
||||
system("rm -r " . $tmpdir);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
==============
|
||||
Advanced Usage
|
||||
==============
|
||||
|
||||
|
||||
+44
-45
@@ -25,9 +25,9 @@ The process of synchronization keeps files in two separate repositories the
|
||||
same. When synchronized:
|
||||
|
||||
- If a file is added to one repository it is copied to the other synchronized repository.
|
||||
- When a file is changed in one repository, the change is propagated to any
|
||||
synchronized other repositories- If a file is deleted in one repository, it
|
||||
is deleted in any other.
|
||||
- When a file is changed in one repository, the change is propagated to any other
|
||||
synchronized repository.
|
||||
- If a file is deleted in one repository, it is deleted in any other.
|
||||
|
||||
It is important to note that the ownCloud synchronization process does not use
|
||||
a typical client/server system where the server is always master. This is a
|
||||
@@ -151,9 +151,9 @@ ownCloud Client provides the ability to add custom patterns.
|
||||
|
||||
By default, the ownCloud Client ignores the following files:
|
||||
|
||||
- Files matched by one of the patterns defined in :ref:`ignoredFilesEditor-label`.
|
||||
- Files containing characters that do not work on certain file systems (`\, /, :, ?, *, ", >, <, |`).
|
||||
* Files starting in ``.csync_journal.db*``, as these files are reserved for journalling.
|
||||
* Files matched by one of the patterns defined in the Ignored Files Editor
|
||||
* Files containing characters that do not work on certain file systems ``(`\, /, :, ?, *, ", >, <, |`)``.
|
||||
* Files starting in ``.csync_journal.db``, as these files are reserved for journalling.
|
||||
|
||||
If a pattern selected using a checkbox in the `ignoredFilesEditor-label` (or if
|
||||
a line in the exclude file starts with the character `]` directly followed by
|
||||
@@ -212,62 +212,61 @@ In the communication between client and server a couple of custom WebDAV propert
|
||||
were introduced. They are either needed for sync functionality or help have a positive
|
||||
effect on synchronization performance.
|
||||
|
||||
This chapter describes additional xml elemeents which the server returns in response
|
||||
to a successful PROPFIND request on a file or directory. The elemnts are returned in
|
||||
This chapter describes additional xml elements which the server returns in response
|
||||
to a successful PROPFIND request on a file or directory. The elements are returned in
|
||||
the namespace oc.
|
||||
|
||||
###Server Side Permissions
|
||||
Server Side Permissions
|
||||
------------------------
|
||||
|
||||
The XML element <oc:permissions> represents the permission- and sharing state of the
|
||||
The XML element ``<oc:permissions>`` represents the permission- and sharing state of the
|
||||
item. It is a list of characters, and each of the chars has a meaning as outlined
|
||||
in the table below:
|
||||
|
||||
+------+-------------+-------------------------------------------+
|
||||
| Code | Resource | Description |
|
||||
|======+=============+===========================================|
|
||||
| S | File or Folder | is shared |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| R | File or Folder | can share (includes reshare) |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| M | File or Folder | is mounted (like on DropBox, Samba, etc.) |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| W | File | can write file |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| C | Folder |can create file in folder |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| K | Folder | can create folder (mkdir) |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| D | File or Folder |can delete file or folder |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| N | File or Folder | can rename file or folder |
|
||||
+---+----------------+-------------------------------------------|
|
||||
| V | File or Folder | can move file or folder |
|
||||
+---+----------------+-------------------------------------------|
|
||||
+----+----------------+-------------------------------------------+
|
||||
|Code| Resource | Description |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| S | File or Folder | is shared |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| R | File or Folder | can share (includes reshare) |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| M | File or Folder | is mounted (like on DropBox, Samba, etc.) |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| W | File | can write file |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| C | Folder |can create file in folder |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| K | Folder | can create folder (mkdir) |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| D | File or Folder |can delete file or folder |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| N | File or Folder | can rename file or folder |
|
||||
+----+----------------+-------------------------------------------+
|
||||
| V | File or Folder | can move file or folder |
|
||||
+----+----------------+-------------------------------------------+
|
||||
|
||||
|
||||
Example:
|
||||
```
|
||||
<oc:permissions>RDNVCK</oc:permissions>
|
||||
```
|
||||
|
||||
###File- or Directory Size
|
||||
<oc:permissions>RDNVCK</oc:permissions>
|
||||
|
||||
The XML element <oc:size> represents the file- or directory size in bytes. For
|
||||
File- or Directory Size
|
||||
-----------------------
|
||||
|
||||
The XML element ``<oc:size>`` represents the file- or directory size in bytes. For
|
||||
directories, the size of the whole file tree underneath the directory is accumulated.
|
||||
|
||||
Example:
|
||||
```
|
||||
<oc:size>2429176697</oc:size>
|
||||
```
|
||||
|
||||
###FileID
|
||||
<oc:size>2429176697</oc:size>
|
||||
|
||||
FileID
|
||||
------
|
||||
|
||||
The XML element <oc:id> represents the so called file ID. It is a non volatile string id
|
||||
The XML element ``<oc:id>`` represents the so called file ID. It is a non volatile string id
|
||||
that stays constant as long as the file exists. It is not changed if the file changes or
|
||||
is renamed or moved.
|
||||
|
||||
|
||||
Example:
|
||||
```
|
||||
<oc:id>00000020oc5cfy6qqizm</oc:id>
|
||||
```
|
||||
|
||||
<oc:id>00000020oc5cfy6qqizm</oc:id>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
=====================
|
||||
The Automatic Updater
|
||||
=====================
|
||||
|
||||
@@ -9,11 +10,15 @@ 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.
|
||||
|
||||
.. note:: Because of various technical issues, desktop sync clients older than
|
||||
1.7 will not be allowed to connect and sync with the ownCloud 8.1 server. It is
|
||||
highly recommended to keep your client updated.
|
||||
|
||||
Basic Workflow
|
||||
--------------
|
||||
|
||||
The following sections describe how to use the Automatic Updater on different
|
||||
operating systems:
|
||||
operating systems.
|
||||
|
||||
Windows
|
||||
^^^^^^^
|
||||
@@ -26,6 +31,9 @@ If an update is available, and has been successfully downloaded, the ownCloud
|
||||
client starts a silent update prior to its next launch and then restarts
|
||||
itself. Should the silent update fail, the client offers a manual download.
|
||||
|
||||
When you upgrade from 1.7 you should restart Windows to ensure that all the new
|
||||
features in 1.8 are enabled.
|
||||
|
||||
.. note:: Administrative privileges are required to perform the update.
|
||||
|
||||
Mac OS X
|
||||
|
||||
@@ -214,6 +214,8 @@ To build the most up to date version of the client:
|
||||
1. Clone the latest versions of the client from Git_ as follows:
|
||||
|
||||
``git clone git://github.com/owncloud/client.git``
|
||||
``git submodule init``
|
||||
``git submodule update``
|
||||
|
||||
2. Create the build directory:
|
||||
|
||||
|
||||
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 14 KiB |
+12
-1
@@ -3,7 +3,7 @@ Installing the Desktop Synchronization Client
|
||||
=============================================
|
||||
|
||||
You can download the latest version of the ownCloud Desktop Synchronization
|
||||
Client from the `ownCloud Website <https://owncloud.org/install/#desktop>`_.
|
||||
Client from the `ownCloud Website <https://owncloud.org/install/#>`_.
|
||||
There are clients for Linux, Mac OS X, and Microsoft Windows.
|
||||
|
||||
Installation on Mac OS X and Windows is the same as for any software
|
||||
@@ -18,6 +18,9 @@ and then use their package managers to install the desktop sync client. Linux
|
||||
users will also update their sync clients via package manager, and the client
|
||||
will display a notification when an update is available.
|
||||
|
||||
Linux users must also have a password manager enabled, such as GNOME Keyring or
|
||||
KWallet, so that the sync client can login automatically.
|
||||
|
||||
Improvements and New Features
|
||||
-----------------------------
|
||||
|
||||
@@ -32,6 +35,9 @@ including:
|
||||
and Nautilus on Linux.
|
||||
* Faster uploads and downloads.
|
||||
|
||||
.. note:: When you upgrade from 1.7, restart Windows to ensure that all new
|
||||
features are visible.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
@@ -99,3 +105,8 @@ you saw in the installation wizard. If you un-check any folders or files that
|
||||
you have already synchronized they will be deleted.
|
||||
|
||||
.. image:: images/client11.png
|
||||
|
||||
Right-click on the systray icon to see more options, such as Open ownCloud in
|
||||
browser, Open folder 'ownCloud', Recent changes, Help, and Quit ownCloud.
|
||||
|
||||
.. image:: images/client12.png
|
||||
|
||||
@@ -11,3 +11,6 @@ Desktop Sync client enables you to:
|
||||
Your files are always automatically synchronized between your ownCloud server
|
||||
and local PC.
|
||||
|
||||
.. note:: Because of various technical issues, desktop sync clients older than
|
||||
1.7 will not allowed to connect and sync with the ownCloud 8.1 server. It is
|
||||
highly recommended to keep your client updated.
|
||||
|
||||
+13
-8
@@ -1,23 +1,28 @@
|
||||
When invoking the client from the command line, the following options are supported:
|
||||
You have the option of starting your ownCloud desktop client with the
|
||||
``owncloud`` command. The following options are supported:
|
||||
|
||||
``-h``, ``--help``
|
||||
``owncloud -h`` or ``owncloud --help``
|
||||
Displays all command options.
|
||||
|
||||
The other options are:
|
||||
|
||||
``--logwindow``
|
||||
Opens a window displaying log output.
|
||||
|
||||
``--logfile`` `<filename>`
|
||||
Write log output to the file specified. To write to stdout, specify `-` as the filename.
|
||||
Write log output to the file specified. To write to stdout, specify `-`
|
||||
as the filename.
|
||||
|
||||
``--logdir`` `<name>`
|
||||
Writes each synchronization log output in a new file in the specified directory.
|
||||
|
||||
Writes each synchronization log output in a new file in the specified
|
||||
directory.
|
||||
|
||||
``--logexpire`` `<hours>`
|
||||
Removes logs older than the value specified (in hours). This command is used with ``--logdir``.
|
||||
Removes logs older than the value specified (in hours). This command is
|
||||
used with ``--logdir``.
|
||||
|
||||
``--logflush``
|
||||
Clears (flushes) the log file after each write action.
|
||||
|
||||
``--confdir`` `<dirname>`
|
||||
Uses the specified configuration directory.
|
||||
|
||||
Uses the specified configuration directory.
|
||||
+24
-38
@@ -1,16 +1,14 @@
|
||||
The ownCloud Client packages contain a command line client that can be used to
|
||||
synchronize ownCloud files to client machines. The command line client is
|
||||
called ``owncloudcmd``.
|
||||
The ownCloud Client packages contain a command line client, ``owncloudcmd``, that can
|
||||
be used to synchronize ownCloud files to client machines.
|
||||
|
||||
owncloudcmd performs a single *sync run* and then exits the synchronization
|
||||
process. In this manner, owncloudcmd processes the differences between client
|
||||
and server directories and propagates the files to bring both repositories to
|
||||
the same state. Contrary to the GUI-based client, ``owncloudcmd`` does not
|
||||
repeat
|
||||
synchronizations on its own. It also does not monitor for file system changes.
|
||||
``owncloudcmd`` performs a single *sync run* and then exits the synchronization
|
||||
process. In this manner, ``owncloudcmd`` processes the differences between
|
||||
client and server directories and propagates the files to bring both
|
||||
repositories to the same state. Contrary to the GUI-based client,
|
||||
``owncloudcmd`` does not repeat synchronizations on its own. It also does not
|
||||
monitor for file system changes.
|
||||
|
||||
To invoke ``owncloudcmd``, you must provide the local and the remote
|
||||
repository
|
||||
To invoke ``owncloudcmd``, you must provide the local and the remote repository
|
||||
URL using the following command::
|
||||
|
||||
owncloudcmd [OPTIONS...] sourcedir owncloudurl
|
||||
@@ -18,45 +16,41 @@ URL using the following command::
|
||||
where ``sourcedir`` is the local directory and ``owncloudurl`` is
|
||||
the server URL.
|
||||
|
||||
.. note:: Prior to the 1.6 version of owncloudcmd, the tool only accepted
|
||||
``owncloud://`` or ``ownclouds://`` in place of ``http://`` and ``https://`` as
|
||||
a scheme. See ``Examples`` for details.
|
||||
|
||||
Other comand line switches supported by owncloudcmd include the following:
|
||||
Other command line switches supported by ``owncloudcmd`` include the following:
|
||||
|
||||
``--user``, ``-u`` ``[user]``
|
||||
Use ``user`` as the login name.
|
||||
Specify the user's login name.
|
||||
|
||||
``--password``, ``-p`` ``[password]``
|
||||
Use ``password`` as the password.
|
||||
Specify the user's password.
|
||||
|
||||
``-n``
|
||||
Use ``netrc (5)`` for login.
|
||||
Use ``netrc (5)`` for login.
|
||||
|
||||
``--non-interactive``
|
||||
Do not prompt for questions.
|
||||
Do not prompt for questions.
|
||||
|
||||
``--silent``, ``-s``
|
||||
Inhibits verbose log output.
|
||||
Inhibits verbose log output.
|
||||
|
||||
``--trust``
|
||||
Trust any SSL certificate, including invalid ones.
|
||||
Trust any SSL certificate, including invalid ones.
|
||||
|
||||
``--httpproxy http://[user@pass:]<server>:<port>``
|
||||
Uses the specified ``server`` as the HTTP proxy.
|
||||
|
||||
``--unsyncedfolders [file]``
|
||||
File containing list of folders to not sync
|
||||
|
||||
Credential Handling
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default, ``owncloudcmd`` reads the client configuration and uses the
|
||||
credentials of the GUI synchronization client. If no client is configured, or if you choose
|
||||
to use a different user to synchronize, you can specify the user password
|
||||
setting with the usual URL pattern. For example::
|
||||
credentials of the GUI synchronization client. If no client is configured, or if
|
||||
you choose to use a different user to synchronize, you can specify the user
|
||||
password setting with the usual URL pattern. For example::
|
||||
|
||||
https://user:secret@192.168.178.2/remote.php/webdav
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
$ owncloudcmd / https://carla:secret@server/owncloud/remote.php/webdav/
|
||||
|
||||
To synchronize the ownCloud directory ``Music`` to the local directory
|
||||
``media/music``, through a proxy listening on port ``8080``, and on a gateway
|
||||
@@ -66,13 +60,5 @@ machine using IP address ``192.168.178.1``, the command line would be::
|
||||
$HOME/media/music \
|
||||
https://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
``owncloudcmd`` will enquire user name and password, unless they have
|
||||
``owncloudcmd`` will prompt for the user name and password, unless they have
|
||||
been specified on the command line or ``-n`` has been passed.
|
||||
|
||||
Using the legacy scheme, the command line would be::
|
||||
|
||||
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
|
||||
$HOME/media/music \
|
||||
ownclouds://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
|
||||
|
||||
+14
-10
@@ -61,12 +61,12 @@ Other issues can affect synchronization of your ownCloud files:
|
||||
ensure that the folder to which you are synchronizing is not shared with
|
||||
other synchronization applications.
|
||||
|
||||
- Synchronizing the same directory with ownCloud and other
|
||||
synchronization software such as Unison, rsync, Microsoft Windows Offline
|
||||
Folders, or other cloud services such as DropBox or Microsoft SkyDrive is not
|
||||
supported and should not be attempted. In the worst case, it is possible that
|
||||
synchronizing folders or files using ownCloud and other synchronization
|
||||
software or services can result in data loss.
|
||||
- Synchronizing the same directory with ownCloud and other synchronization
|
||||
software such as Unison, rsync, Microsoft Windows Offline Folders, or other
|
||||
cloud services such as DropBox or Microsoft SkyDrive is not supported and
|
||||
should not be attempted. In the worst case, it is possible that synchronizing
|
||||
folders or files using ownCloud and other synchronization software or
|
||||
services can result in data loss.
|
||||
|
||||
- If you find that only specific files are not synrchronized, the
|
||||
synchronization protocol might be having an effect. Some files are
|
||||
@@ -80,9 +80,13 @@ Other issues can affect synchronization of your ownCloud files:
|
||||
|
||||
.. note:: The data directory on the server is exclusive to ownCloud and must not be modified manually.
|
||||
|
||||
If you are using a different file backend on the server, you can try to exclude a bug in the
|
||||
- If you are using a different file backend on the server, you can try to exclude a bug in the
|
||||
backend by reverting to the built-in backend.
|
||||
|
||||
- If you are experiencing slow upload/download speed or similar performance issues
|
||||
be aware that those could be caused by on-access virus scanning solutions, either
|
||||
on the server (like the files_antivirus app) or the client.
|
||||
|
||||
Log Files
|
||||
---------
|
||||
|
||||
@@ -125,9 +129,9 @@ mentioned above to save the log to a file.
|
||||
.. note:: You can also open a log window for an already running session, by
|
||||
restarting the client using the following command:
|
||||
|
||||
* Windows: ``C:\Program Files (x86)\ownCloud\owncloud.exe --logwindow``
|
||||
* Mac OS X: ``/Applications/owncloud.app/Contents/MacOS/owncloud --logwindow``
|
||||
* Linux: ``owncloud --logwindow``
|
||||
* Windows: ``C:\Program Files (x86)\ownCloud\owncloud.exe --logwindow``
|
||||
* Mac OS X: ``/Applications/owncloud.app/Contents/MacOS/owncloud --logwindow``
|
||||
* Linux: ``owncloud --logwindow``
|
||||
|
||||
Saving Files Directly
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
@interface ContentManager : NSObject
|
||||
{
|
||||
NSMutableDictionary* _fileNamesCache;
|
||||
NSMutableDictionary* _oldFileNamesCache;
|
||||
BOOL _fileIconsEnabled;
|
||||
BOOL _hasChangedContent;
|
||||
|
||||
@@ -35,10 +36,9 @@
|
||||
- (void)enableFileIcons:(BOOL)enable;
|
||||
- (NSNumber*)iconByPath:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (void)removeAllIcons;
|
||||
- (void)removeIcons:(NSArray*)paths;
|
||||
- (void)setIcons:(NSDictionary*)iconDictionary filterByFolder:(NSString*)filterFolder;
|
||||
- (void)setResultForPath:(NSString*)path result:(NSString*)result;
|
||||
- (void)clearFileNameCacheForPath:(NSString*)path;
|
||||
- (void)clearFileNameCache;
|
||||
- (void)reFetchFileNameCacheForPath:(NSString*)path;
|
||||
- (void)repaintAllWindows;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ static ContentManager* sharedInstance = nil;
|
||||
if (self)
|
||||
{
|
||||
_fileNamesCache = [[NSMutableDictionary alloc] init];
|
||||
_oldFileNamesCache = [[NSMutableDictionary alloc] init];
|
||||
_fileIconsEnabled = TRUE;
|
||||
_hasChangedContent = TRUE;
|
||||
}
|
||||
@@ -41,6 +42,7 @@ static ContentManager* sharedInstance = nil;
|
||||
{
|
||||
[self removeAllIcons];
|
||||
[_fileNamesCache release];
|
||||
[_oldFileNamesCache release];
|
||||
sharedInstance = nil;
|
||||
|
||||
[super dealloc];
|
||||
@@ -148,84 +150,48 @@ static ContentManager* sharedInstance = nil;
|
||||
|
||||
if( result == nil ) {
|
||||
// start the async call
|
||||
NSNumber *askState = [[RequestManager sharedInstance] askForIcon:normalizedPath isDirectory:isDir];
|
||||
[_fileNamesCache setObject:askState forKey:normalizedPath];
|
||||
|
||||
[[RequestManager sharedInstance] askForIcon:normalizedPath isDirectory:isDir];
|
||||
result = [NSNumber numberWithInt:0];
|
||||
} else if( [result intValue] == -1 ) {
|
||||
// the socket call is underways.
|
||||
result = [NSNumber numberWithInt:0];
|
||||
} else {
|
||||
// there is a proper icon index
|
||||
// Set 0 into the cache, meaning "don't have an icon, but already requested it"
|
||||
[_fileNamesCache setObject:result forKey:normalizedPath];
|
||||
}
|
||||
// NSLog(@"iconByPath return value %d", [result intValue]);
|
||||
if ([result intValue] == 0) {
|
||||
// Show the old state while we wait for the new one
|
||||
NSNumber* oldResult = [_oldFileNamesCache objectForKey:normalizedPath];
|
||||
if (oldResult)
|
||||
result = oldResult;
|
||||
}
|
||||
// NSLog(@"iconByPath return value %d", [result intValue]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// called as a result of an UPDATE_VIEW message.
|
||||
// it clears the entries from the hash to make it call again home to the desktop client.
|
||||
- (void)clearFileNameCacheForPath:(NSString*)path
|
||||
// Clears the entries from the hash to make it call again home to the desktop client.
|
||||
- (void)clearFileNameCache
|
||||
{
|
||||
//NSLog(@"%@", NSStringFromSelector(_cmd));
|
||||
NSMutableArray *keysToDelete = [NSMutableArray array];
|
||||
|
||||
if( path != nil ) {
|
||||
for (id p in [_fileNamesCache keyEnumerator]) {
|
||||
//do stuff with obj
|
||||
if ( [p hasPrefix:path] ) {
|
||||
[keysToDelete addObject:p];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// clear the entire fileNameCache
|
||||
[_fileNamesCache release];
|
||||
_fileNamesCache = [[NSMutableDictionary alloc] init];
|
||||
return;
|
||||
}
|
||||
|
||||
if( [keysToDelete count] > 0 ) {
|
||||
NSLog( @"Entries to delete: %lu", (unsigned long)[keysToDelete count]);
|
||||
[_fileNamesCache removeObjectsForKeys:keysToDelete];
|
||||
}
|
||||
[_fileNamesCache release];
|
||||
_fileNamesCache = [[NSMutableDictionary alloc] init];
|
||||
[_oldFileNamesCache removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)reFetchFileNameCacheForPath:(NSString*)path
|
||||
{
|
||||
NSLog(@"%@", NSStringFromSelector(_cmd));
|
||||
//NSLog(@"%@", NSStringFromSelector(_cmd));
|
||||
|
||||
for (id p in [_fileNamesCache keyEnumerator]) {
|
||||
if ( path && [p hasPrefix:path] ) {
|
||||
[[RequestManager sharedInstance] askForIcon:p isDirectory:false]; // FIXME isDirectory parameter
|
||||
//[_fileNamesCache setObject:askState forKey:p]; We don't do this since we want to keep the old icon meanwhile
|
||||
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), p);
|
||||
}
|
||||
}
|
||||
// We won't request the new state if if finds the path in _fileNamesCache
|
||||
// Move all entries to _oldFileNamesCache so that the get re-requested, but
|
||||
// still available while we refill the cache
|
||||
[_oldFileNamesCache addEntriesFromDictionary:_fileNamesCache];
|
||||
[_fileNamesCache removeAllObjects];
|
||||
|
||||
// Ask for directory itself
|
||||
if ([path hasSuffix:@"/"]) {
|
||||
path = [path substringToIndex:path.length - 1];
|
||||
}
|
||||
[[RequestManager sharedInstance] askForIcon:path isDirectory:true];
|
||||
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), path);
|
||||
[self repaintAllWindows];
|
||||
}
|
||||
|
||||
|
||||
- (void)removeAllIcons
|
||||
{
|
||||
[_fileNamesCache removeAllObjects];
|
||||
|
||||
[self repaintAllWindows];
|
||||
}
|
||||
|
||||
- (void)removeIcons:(NSArray*)paths
|
||||
{
|
||||
for (NSString* path in paths)
|
||||
{
|
||||
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
|
||||
|
||||
[_fileNamesCache removeObjectForKey:normalizedPath];
|
||||
}
|
||||
[_oldFileNamesCache removeAllObjects];
|
||||
|
||||
[self repaintAllWindows];
|
||||
}
|
||||
@@ -361,6 +327,7 @@ static ContentManager* sharedInstance = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
[_oldFileNamesCache removeObjectForKey:normalizedPath];
|
||||
[_fileNamesCache setObject:iconId forKey:normalizedPath];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
NSMutableArray* _requestQueue;
|
||||
NSMutableDictionary* _registeredPathes;
|
||||
NSMutableSet* _requestedPaths;
|
||||
|
||||
NSString *_shareMenuTitle;
|
||||
|
||||
@@ -34,7 +35,7 @@
|
||||
|
||||
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (void)askOnSocket:(NSString*)path query:(NSString*)verb;
|
||||
- (NSNumber*)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (void)menuItemClicked:(NSDictionary*)actionDictionary;
|
||||
- (void)start;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ static RequestManager* sharedInstance = nil;
|
||||
_isConnected = NO;
|
||||
|
||||
_registeredPathes = [[NSMutableDictionary alloc] init];
|
||||
_requestedPaths = [[NSMutableSet alloc] init];
|
||||
|
||||
_shareMenuTitle = nil;
|
||||
|
||||
@@ -101,28 +102,23 @@ static RequestManager* sharedInstance = nil;
|
||||
return registered;
|
||||
}
|
||||
|
||||
- (NSNumber*)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
|
||||
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
|
||||
{
|
||||
NSString *verb = @"RETRIEVE_FILE_STATUS";
|
||||
NSNumber *res = [NSNumber numberWithInt:0];
|
||||
|
||||
if( [self isRegisteredPath:path isDirectory:isDir] ) {
|
||||
[_requestedPaths addObject:path];
|
||||
if( _isConnected ) {
|
||||
if(isDir) {
|
||||
verb = @"RETRIEVE_FOLDER_STATUS";
|
||||
}
|
||||
|
||||
[self askOnSocket:path query:verb];
|
||||
|
||||
NSNumber *res_minus_one = [NSNumber numberWithInt:0];
|
||||
|
||||
return res_minus_one;
|
||||
} else {
|
||||
[_requestQueue addObject:path];
|
||||
[self start]; // try again to connect
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,9 +143,13 @@ static RequestManager* sharedInstance = nil;
|
||||
path, [chunks objectAtIndex:i+1] ];
|
||||
}
|
||||
}
|
||||
[contentman setResultForPath:path result:[chunks objectAtIndex:1]];
|
||||
// The client will broadcast all changes, do not fill the cache for paths that Finder didn't ask for.
|
||||
if ([_requestedPaths containsObject:path]) {
|
||||
[contentman setResultForPath:path result:[chunks objectAtIndex:1]];
|
||||
}
|
||||
} else if( [[chunks objectAtIndex:0] isEqualToString:@"UPDATE_VIEW"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[_requestedPaths removeAllObjects];
|
||||
[contentman reFetchFileNameCacheForPath:path];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"REGISTER_PATH"] ) {
|
||||
NSNumber *one = [NSNumber numberWithInt:1];
|
||||
@@ -198,10 +198,11 @@ static RequestManager* sharedInstance = nil;
|
||||
for( NSString *path in _requestQueue ) {
|
||||
[self askOnSocket:path query:@"RETRIEVE_FILE_STATUS"];
|
||||
}
|
||||
[_requestQueue removeAllObjects];
|
||||
}
|
||||
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
[contentman clearFileNameCacheForPath:nil];
|
||||
[contentman clearFileNameCache];
|
||||
[contentman repaintAllWindows];
|
||||
|
||||
// Read for the UPDATE_VIEW requests
|
||||
@@ -218,10 +219,11 @@ static RequestManager* sharedInstance = nil;
|
||||
// clear the registered pathes.
|
||||
[_registeredPathes release];
|
||||
_registeredPathes = [[NSMutableDictionary alloc] init];
|
||||
[_requestedPaths removeAllObjects];
|
||||
|
||||
// clear the caches in conent manager
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
[contentman clearFileNameCacheForPath:nil];
|
||||
[contentman clearFileNameCache];
|
||||
[contentman repaintAllWindows];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
# osascript $HOME/owncloud.com/client/shell_integration/MacOSX/unload.scpt
|
||||
SELFPATH=`dirname $0`
|
||||
# osascript $SELFPATH/unload.scpt
|
||||
|
||||
sudo rm -rf /Library/ScriptingAdditions/SyncStateFinder.osax
|
||||
# Klaas' machine
|
||||
@@ -12,6 +13,6 @@ OSAXDIR=$HOME/Library/Developer/Xcode/DerivedData/OwnCloud-*/Build/Products/Debu
|
||||
|
||||
sudo killall Finder
|
||||
sleep 1
|
||||
osascript $HOME/owncloud.com/client/shell_integration/MacOSX/load.scpt
|
||||
osascript $HOME/owncloud.com/client/shell_integration/MacOSX/check.scpt
|
||||
osascript $SELFPATH/load.scpt
|
||||
osascript $SELFPATH/check.scpt
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ class SocketConnect(GObject.GObject):
|
||||
print("Sending failed.")
|
||||
self.reconnect()
|
||||
else:
|
||||
print "Cannot send, not connected!"
|
||||
print("Cannot send, not connected!")
|
||||
|
||||
def addListener(self, listener):
|
||||
self._listeners.append(listener)
|
||||
@@ -85,7 +85,7 @@ class SocketConnect(GObject.GObject):
|
||||
self.connected = True
|
||||
print("Setting connected to %r" % self.connected )
|
||||
self._watch_id = GObject.io_add_watch(self._sock, GObject.IO_IN, self._handle_notify)
|
||||
print "Socket watch id: "+str(self._watch_id)
|
||||
print("Socket watch id: "+str(self._watch_id))
|
||||
return False # don't run again
|
||||
except Exception as e:
|
||||
print("Could not connect to unix socket." + str(e))
|
||||
@@ -175,7 +175,7 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
|
||||
|
||||
def menu_share(self, menu, file):
|
||||
filename = get_local_path(file.get_uri())
|
||||
print "Share file "+filename
|
||||
print("Share file "+filename)
|
||||
socketConnect.sendCommand("SHARE:"+filename+"\n")
|
||||
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ IFACEMETHODIMP OCContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT
|
||||
|
||||
assert(!info.shareMenuTitle.empty());
|
||||
MENUITEMINFO mii = { sizeof(mii) };
|
||||
mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
|
||||
mii.wID = idCmdFirst + IDM_SHARE;
|
||||
mii.fType = MFT_STRING;
|
||||
mii.dwTypeData = &info.shareMenuTitle[0];
|
||||
|
||||
@@ -83,7 +83,6 @@
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OCCONTEXTMENU_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\OCUtil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
@@ -101,8 +100,8 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OCCONTEXTMENU_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\OCUtil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -132,6 +131,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\OCUtil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -145,6 +146,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\OCUtil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -136,6 +137,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@@ -98,6 +98,8 @@ void RemotePathChecker::workerThreadLoop()
|
||||
++it;
|
||||
}
|
||||
}
|
||||
// Assume that we won't need this at this point, UNREGISTER_PATH is rare
|
||||
_oldCache.clear();
|
||||
}
|
||||
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
|
||||
} else if (StringUtil::begins_with(response, wstring(L"STATUS:")) ||
|
||||
@@ -115,13 +117,16 @@ void RemotePathChecker::workerThreadLoop()
|
||||
auto responseStatus = response.substr(statusBegin+1, statusEnd - statusBegin-1);
|
||||
auto responsePath = response.substr(statusEnd+1);
|
||||
auto state = _StrToFileState(responseStatus);
|
||||
auto erased = asked.erase(responsePath);
|
||||
bool wasAsked = asked.erase(responsePath) > 0;
|
||||
|
||||
bool changed = false;
|
||||
{ std::unique_lock<std::mutex> lock(_mutex);
|
||||
auto &it = _cache[responsePath];
|
||||
changed = (it != state);
|
||||
it = state;
|
||||
bool wasCached = _cache.find(responsePath) != _cache.end();
|
||||
if (wasAsked || wasCached) {
|
||||
auto &it = _cache[responsePath];
|
||||
changed = (it != state);
|
||||
it = state;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
|
||||
@@ -129,20 +134,25 @@ void RemotePathChecker::workerThreadLoop()
|
||||
}
|
||||
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
|
||||
// Keep the old states to continue having something to display while the new state is
|
||||
// requested from the client, triggered by clearing _cache.
|
||||
_oldCache.insert(_cache.cbegin(), _cache.cend());
|
||||
|
||||
// Swap to make a copy of the cache under the mutex and clear the one stored.
|
||||
std::unordered_map<std::wstring, FileState> cache;
|
||||
swap(cache, _cache);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Let explorer know about the invalidated cache entries, it will re-request the ones it needs.
|
||||
for (auto it = cache.begin(); it != cache.end(); ++it) {
|
||||
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, it->first.data(), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (socket.Event() == INVALID_HANDLE_VALUE) {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cache.clear();
|
||||
_oldCache.clear();
|
||||
_watchedDirectories.clear();
|
||||
_connected = connected = false;
|
||||
}
|
||||
@@ -195,11 +205,17 @@ bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, int* state)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Re-request the status while we display what we have in _oldCache
|
||||
_pending.push(filePath);
|
||||
|
||||
it = _oldCache.find(path);
|
||||
bool foundInOldCache = it != _oldCache.end();
|
||||
if (foundInOldCache)
|
||||
*state = it->second;
|
||||
|
||||
lock.unlock();
|
||||
SetEvent(_newQueries);
|
||||
return false;
|
||||
|
||||
return foundInOldCache;
|
||||
}
|
||||
|
||||
RemotePathChecker::FileState RemotePathChecker::_StrToFileState(const std::wstring &str)
|
||||
|
||||
@@ -52,6 +52,7 @@ private:
|
||||
std::queue<std::wstring> _pending;
|
||||
|
||||
std::unordered_map<std::wstring, FileState> _cache;
|
||||
std::unordered_map<std::wstring, FileState> _oldCache;
|
||||
std::vector<std::wstring> _watchedDirectories;
|
||||
bool _connected;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "qtlocalpeer.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDataStream>
|
||||
#include <QTime>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
|
||||
@@ -5,6 +5,10 @@ set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
set(synclib_NAME ${APPLICATION_EXECUTABLE}sync)
|
||||
|
||||
if (APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
endif()
|
||||
|
||||
add_subdirectory(libsync)
|
||||
if (NOT BUILD_LIBRARIES_ONLY)
|
||||
add_subdirectory(gui)
|
||||
|
||||
+8
-1
@@ -194,6 +194,9 @@ void parseOptions( const QStringList& app_args, CmdOptions *options )
|
||||
if (options->target_url.startsWith("http"))
|
||||
options->target_url.replace(0, 4, "owncloud");
|
||||
options->source_dir = args.takeLast();
|
||||
if (!options->source_dir.endsWith('/')) {
|
||||
options->source_dir.append('/');
|
||||
}
|
||||
if( !QFile::exists( options->source_dir )) {
|
||||
std::cerr << "Source dir '" << qPrintable(options->source_dir) << "' does not exist." << std::endl;
|
||||
exit(1);
|
||||
@@ -286,6 +289,8 @@ void selectiveSyncFixup(OCC::SyncJournalDb *journal, const QStringList &newList)
|
||||
int main(int argc, char **argv) {
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
qsrand(QTime::currentTime().msec() * QCoreApplication::applicationPid());
|
||||
|
||||
CmdOptions options;
|
||||
options.silent = false;
|
||||
options.trustSSL = false;
|
||||
@@ -442,7 +447,9 @@ restart_sync:
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
qCritical() << "Could not open file containing the list of unsynced folders: " << options.unsyncedfolders;
|
||||
} else {
|
||||
selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n');
|
||||
// filter out empty lines and comments
|
||||
selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n').filter(QRegExp("\\S+")).filter(QRegExp("^[^#]"));
|
||||
|
||||
for (int i = 0; i < selectiveSyncList.count(); ++i) {
|
||||
if (!selectiveSyncList.at(i).endsWith(QLatin1Char('/'))) {
|
||||
selectiveSyncList[i].append(QLatin1Char('/'));
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
#include "account.h"
|
||||
#include "simplesslerrorhandler.h"
|
||||
|
||||
bool SimpleSslErrorHandler::handleErrors(QList<QSslError> errors, QList<QSslCertificate> *certs, OCC::AccountPtr account)
|
||||
bool SimpleSslErrorHandler::handleErrors(QList<QSslError> errors, const QSslConfiguration &conf, QList<QSslCertificate> *certs, OCC::AccountPtr account)
|
||||
{
|
||||
(void) account;
|
||||
(void) conf;
|
||||
|
||||
if (!certs) {
|
||||
qDebug() << "Certs parameter required but is NULL!";
|
||||
|
||||
@@ -20,7 +20,7 @@ class QSslCertificate;
|
||||
|
||||
class SimpleSslErrorHandler : public OCC::AbstractSslErrorHandler {
|
||||
public:
|
||||
bool handleErrors(QList<QSslError> errors, QList<QSslCertificate> *certs, OCC::AccountPtr) Q_DECL_OVERRIDE;
|
||||
bool handleErrors(QList<QSslError> errors, const QSslConfiguration &conf, QList<QSslCertificate> *certs, OCC::AccountPtr) Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // SIMPLESSLERRORHANDLER_H
|
||||
|
||||
@@ -154,10 +154,19 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
||||
qt_add_translation(client_I18N ${TRANSLATIONS})
|
||||
|
||||
IF( WIN32 )
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.rc
|
||||
@ONLY)
|
||||
set(client_version ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||
ENDIF()
|
||||
|
||||
set( final_src
|
||||
${MIRALL_RC_SRC}
|
||||
${client_SRCS}
|
||||
${client_UI_SRCS}
|
||||
${client_version}
|
||||
${guiMoc}
|
||||
${client_I18N}
|
||||
${3rdparty_SRC}
|
||||
|
||||
@@ -28,9 +28,6 @@ public:
|
||||
* @return the list of migrated folder definitions
|
||||
*/
|
||||
QStringList migrateFolderDefinitons();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ void AccountSettings::slotAddFolder( Folder *folder )
|
||||
if( ! folder || folder->alias().isEmpty() ) return;
|
||||
|
||||
QStandardItem *item = new QStandardItem();
|
||||
folderToModelItem( item, folder, _accountState && _accountState->isConnectedOrMaintenance());
|
||||
folderToModelItem( item, folder, _accountState && _accountState->isConnectedOrTemporarilyUnavailable());
|
||||
_model->appendRow( item );
|
||||
// in order to update the enabled state of the "Sync now" button
|
||||
connect(folder, SIGNAL(syncStateChange()), this, SLOT(slotFolderSyncStateChange()), Qt::UniqueConnection);
|
||||
@@ -398,6 +398,18 @@ void AccountSettings::slotSelectiveSync()
|
||||
}
|
||||
}
|
||||
|
||||
void AccountSettings::slotForceRemoteDiscoveryOnFolders()
|
||||
{
|
||||
FolderMan* folders = FolderMan::instance();
|
||||
foreach (Folder* folder, folders->map()) {
|
||||
if (folder->accountState() != _accountState) {
|
||||
continue;
|
||||
}
|
||||
|
||||
folder->journalDb()->forceRemoteDiscoveryNextSync();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountSettings::slotDoubleClicked( const QModelIndex& indx )
|
||||
{
|
||||
if( ! indx.isValid() ) return;
|
||||
@@ -537,7 +549,7 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
|
||||
}
|
||||
|
||||
if( item ) {
|
||||
folderToModelItem( item, folder, _accountState->isConnectedOrMaintenance() );
|
||||
folderToModelItem( item, folder, _accountState->isConnectedOrTemporarilyUnavailable() );
|
||||
} else {
|
||||
// the dialog is not visible.
|
||||
}
|
||||
@@ -777,6 +789,7 @@ void AccountSettings::slotIgnoreFilesEditor()
|
||||
_ignoreEditor = new IgnoreListEditor(this);
|
||||
_ignoreEditor->setAttribute( Qt::WA_DeleteOnClose, true );
|
||||
_ignoreEditor->open();
|
||||
connect(_ignoreEditor, SIGNAL(accepted()), SLOT(slotForceRemoteDiscoveryOnFolders()));
|
||||
} else {
|
||||
ownCloudGui::raiseDialog(_ignoreEditor);
|
||||
}
|
||||
@@ -794,7 +807,7 @@ void AccountSettings::slotAccountStateChanged(int state)
|
||||
foreach (Folder *folder, folderMan->map().values()) {
|
||||
slotUpdateFolderState(folder);
|
||||
}
|
||||
if (state == AccountState::Connected || state == AccountState::ServerMaintenance) {
|
||||
if (state == AccountState::Connected || state == AccountState::ServiceUnavailable) {
|
||||
QString user;
|
||||
if (AbstractCredentials *cred = account->credentials()) {
|
||||
user = cred->user();
|
||||
|
||||
@@ -83,6 +83,7 @@ protected slots:
|
||||
void slotOpenAccountWizard();
|
||||
void slotHideProgress();
|
||||
void slotSelectiveSync();
|
||||
void slotForceRemoteDiscoveryOnFolders();
|
||||
|
||||
private:
|
||||
QString shortenFilename( const QString& folder, const QString& file ) const;
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
<property name="text">
|
||||
<string>Connected with <server> as <user></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
+39
-11
@@ -43,7 +43,9 @@ void AccountStateManager::setAccountState(AccountState *accountState)
|
||||
emit accountStateRemoved(_accountState);
|
||||
}
|
||||
_accountState = accountState;
|
||||
emit accountStateAdded(accountState);
|
||||
if (accountState) {
|
||||
emit accountStateAdded(accountState);
|
||||
}
|
||||
}
|
||||
|
||||
void AccountStateManager::slotAccountAdded(AccountPtr account)
|
||||
@@ -54,13 +56,15 @@ void AccountStateManager::slotAccountAdded(AccountPtr account)
|
||||
AccountState::AccountState(AccountPtr account)
|
||||
: QObject(account.data())
|
||||
, _account(account)
|
||||
, _quotaInfo(new QuotaInfo(this))
|
||||
, _quotaInfo(0)
|
||||
, _state(AccountState::Disconnected)
|
||||
, _connectionStatus(ConnectionValidator::Undefined)
|
||||
, _waitingForNewCredentials(false)
|
||||
{
|
||||
qRegisterMetaType<AccountState*>("AccountState*");
|
||||
|
||||
_quotaInfo = new QuotaInfo(this); // Need to be initialized when 'this' is fully initialized
|
||||
|
||||
connect(account.data(), SIGNAL(invalidCredentials()),
|
||||
SLOT(slotInvalidCredentials()));
|
||||
connect(account.data(), SIGNAL(credentialsFetched(AbstractCredentials*)),
|
||||
@@ -110,9 +114,10 @@ void AccountState::setState(State state)
|
||||
} else if (oldState == SignedOut && _state == Disconnected) {
|
||||
checkConnectivity();
|
||||
}
|
||||
|
||||
emit stateChanged(_state);
|
||||
}
|
||||
|
||||
// might not have changed but the underlying _connectionErrors might have
|
||||
emit stateChanged(_state);
|
||||
}
|
||||
|
||||
QString AccountState::stateString(State state)
|
||||
@@ -125,8 +130,8 @@ QString AccountState::stateString(State state)
|
||||
return QLatin1String("Disconnected");
|
||||
case Connected:
|
||||
return QLatin1String("Connected");
|
||||
case ServerMaintenance:
|
||||
return QLatin1String("ServerMaintenance");
|
||||
case ServiceUnavailable:
|
||||
return QLatin1String("ServiceUnavailable");
|
||||
case NetworkError:
|
||||
return QLatin1String("NetworkError");
|
||||
case ConfigurationError:
|
||||
@@ -154,9 +159,9 @@ bool AccountState::isConnected() const
|
||||
return _state == Connected;
|
||||
}
|
||||
|
||||
bool AccountState::isConnectedOrMaintenance() const
|
||||
bool AccountState::isConnectedOrTemporarilyUnavailable() const
|
||||
{
|
||||
return isConnected() || _state == ServerMaintenance;
|
||||
return isConnected() || _state == ServiceUnavailable;
|
||||
}
|
||||
|
||||
QuotaInfo *AccountState::quotaInfo()
|
||||
@@ -170,7 +175,12 @@ void AccountState::checkConnectivity()
|
||||
return;
|
||||
}
|
||||
|
||||
if (_connectionValidator) {
|
||||
qDebug() << "ConnectionValidator already running, ignoring";
|
||||
return;
|
||||
}
|
||||
ConnectionValidator * conValidator = new ConnectionValidator(account());
|
||||
_connectionValidator = conValidator;
|
||||
connect(conValidator, SIGNAL(connectionResult(ConnectionValidator::Status,QStringList)),
|
||||
SLOT(slotConnectionValidatorResult(ConnectionValidator::Status,QStringList)));
|
||||
if (isConnected()) {
|
||||
@@ -179,6 +189,15 @@ void AccountState::checkConnectivity()
|
||||
conValidator->checkAuthentication();
|
||||
} else {
|
||||
// Check the server and then the auth.
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// There seems to be a bug in Qt on Windows where QNAM sometimes stops
|
||||
// working correctly after the computer woke up from sleep. See #2895 #2899
|
||||
// and #2973.
|
||||
// As an attempted workaround, reset the QNAM regularly if the account is
|
||||
// disconnected.
|
||||
account()->resetNetworkAccessManager();
|
||||
#endif
|
||||
conValidator->checkServerAndAuth();
|
||||
}
|
||||
}
|
||||
@@ -189,6 +208,7 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
|
||||
return;
|
||||
}
|
||||
|
||||
auto oldStatus = _connectionStatus;
|
||||
if (_connectionStatus != status) {
|
||||
qDebug() << "AccountState connection status change: "
|
||||
<< connectionStatusString(_connectionStatus) << "->"
|
||||
@@ -200,7 +220,9 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
|
||||
switch (status)
|
||||
{
|
||||
case ConnectionValidator::Connected:
|
||||
setState(Connected);
|
||||
if (oldStatus != ConnectionValidator::Connected) {
|
||||
setState(Connected);
|
||||
}
|
||||
break;
|
||||
case ConnectionValidator::Undefined:
|
||||
case ConnectionValidator::NotConfigured:
|
||||
@@ -221,8 +243,8 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
|
||||
case ConnectionValidator::UserCanceledCredentials:
|
||||
setState(SignedOut);
|
||||
break;
|
||||
case ConnectionValidator::ServerMaintenance:
|
||||
setState(ServerMaintenance);
|
||||
case ConnectionValidator::ServiceUnavailable:
|
||||
setState(ServiceUnavailable);
|
||||
break;
|
||||
case ConnectionValidator::Timeout:
|
||||
setState(NetworkError);
|
||||
@@ -250,6 +272,12 @@ void AccountState::slotCredentialsFetched(AbstractCredentials* credentials)
|
||||
return;
|
||||
}
|
||||
|
||||
// When new credentials become available we always want to restart the
|
||||
// connection validation, even if it's currently running.
|
||||
if (_connectionValidator) {
|
||||
delete _connectionValidator;
|
||||
}
|
||||
|
||||
checkConnectivity();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define ACCOUNTINFO_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QPointer>
|
||||
#include "utility.h"
|
||||
#include "connectionvalidator.h"
|
||||
|
||||
@@ -67,9 +68,9 @@ public:
|
||||
/// The account is successfully talking to the server.
|
||||
Connected,
|
||||
|
||||
/// The account is talking to the server, but the server is in
|
||||
/// maintenance mode.
|
||||
ServerMaintenance,
|
||||
/// There's a temporary problem with talking to the server,
|
||||
/// don't bother the user too much and try again.
|
||||
ServiceUnavailable,
|
||||
|
||||
/// Could not communicate with the server for some reason.
|
||||
/// We assume this may resolve itself over time and will try
|
||||
@@ -100,7 +101,7 @@ public:
|
||||
void setSignedOut(bool signedOut);
|
||||
|
||||
bool isConnected() const;
|
||||
bool isConnectedOrMaintenance() const;
|
||||
bool isConnectedOrTemporarilyUnavailable() const;
|
||||
|
||||
QuotaInfo *quotaInfo();
|
||||
|
||||
@@ -128,6 +129,7 @@ private:
|
||||
ConnectionStatus _connectionStatus;
|
||||
QStringList _connectionErrors;
|
||||
bool _waitingForNewCredentials;
|
||||
QPointer<ConnectionValidator> _connectionValidator;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(WITH_CRASHREPORTER)
|
||||
#include <libcrashreporter-handler/Handler.h>
|
||||
#endif
|
||||
|
||||
#include <QTranslator>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
@@ -106,6 +110,20 @@ Application::Application(int &argc, char **argv) :
|
||||
if (isRunning())
|
||||
return;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) && QT_VERSION < QT_VERSION_CHECK(5, 4, 2)
|
||||
// Workaround for QTBUG-44576: Make sure a stale QSettings lock file
|
||||
// is deleted. (Introduced in Qt 5.4.0 and fixed in Qt 5.4.2)
|
||||
{
|
||||
QString lockFilePath = ConfigFile().configFile() + QLatin1String(".lock");
|
||||
QLockFile(lockFilePath).removeStaleLockFile();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WITH_CRASHREPORTER)
|
||||
if (ConfigFile().crashReporter())
|
||||
_crashHandler.reset(new CrashReporter::Handler( QDir::tempPath(), true, CRASHREPORTER_EXECUTABLE ));
|
||||
#endif
|
||||
|
||||
setupLogging();
|
||||
setupTranslations();
|
||||
|
||||
@@ -171,7 +189,8 @@ Application::Application(int &argc, char **argv) :
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
// qDebug() << "* OCC shutdown";
|
||||
// Remove the account from the account manager so it can be deleted.
|
||||
AccountManager::instance()->setAccount(AccountPtr());
|
||||
}
|
||||
|
||||
void Application::slotLogin()
|
||||
@@ -260,7 +279,7 @@ void Application::slotAccountStateChanged(int state)
|
||||
folderMan->setSyncEnabled(true);
|
||||
folderMan->slotScheduleAllFolders();
|
||||
break;
|
||||
case AccountState::ServerMaintenance:
|
||||
case AccountState::ServiceUnavailable:
|
||||
case AccountState::SignedOut:
|
||||
case AccountState::ConfigurationError:
|
||||
case AccountState::NetworkError:
|
||||
@@ -394,7 +413,10 @@ void Application::parseOptions(const QStringList &options)
|
||||
} else if (option == QLatin1String("--confdir")) {
|
||||
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
|
||||
QString confDir = it.next();
|
||||
ConfigFile::setConfDir( confDir );
|
||||
if (!ConfigFile::setConfDir( confDir )) {
|
||||
std::cerr << "Invalid path passed to --confdir" << std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
} else {
|
||||
showHelp();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ class QMessageBox;
|
||||
class QSystemTrayIcon;
|
||||
class QSocket;
|
||||
|
||||
namespace CrashReporter {
|
||||
class Handler;
|
||||
}
|
||||
|
||||
namespace OCC {
|
||||
class Theme;
|
||||
class Folder;
|
||||
@@ -109,6 +113,9 @@ private:
|
||||
|
||||
QTimer _checkConnectionTimer;
|
||||
|
||||
#if defined(WITH_CRASHREPORTER)
|
||||
QScopedPointer<CrashReporter::Handler> _crashHandler;
|
||||
#endif
|
||||
QScopedPointer<FolderMan> _folderManager;
|
||||
|
||||
friend class ownCloudGui; // for _startupNetworkError
|
||||
|
||||
@@ -772,6 +772,7 @@ void Folder::startSync(const QStringList &pathList)
|
||||
_timeSinceLastSyncStart.restart();
|
||||
_syncResult.clearErrors();
|
||||
_syncResult.setStatus( SyncResult::SyncPrepare );
|
||||
_syncResult.setSyncFileItemVector(SyncFileItemVector());
|
||||
emit syncStateChange();
|
||||
|
||||
qDebug() << "*** Start syncing - client version"
|
||||
|
||||
@@ -873,6 +873,13 @@ void FolderMan::setDirtyProxy(bool value)
|
||||
foreach( Folder *f, _folderMap.values() ) {
|
||||
if(f) {
|
||||
f->setProxyDirty(value);
|
||||
|
||||
if (f->accountState() && f->accountState()->account()
|
||||
&& f->accountState()->account()->networkAccessManager()) {
|
||||
// Need to do this have us not use the old determined system proxy
|
||||
f->accountState()->account()->networkAccessManager()->setProxy(
|
||||
QNetworkProxy(QNetworkProxy::DefaultProxy));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+107
-21
@@ -239,10 +239,19 @@ FolderWizardRemotePath::FolderWizardRemotePath(AccountPtr account)
|
||||
|
||||
connect(_ui.addFolderButton, SIGNAL(clicked()), SLOT(slotAddRemoteFolder()));
|
||||
connect(_ui.refreshButton, SIGNAL(clicked()), SLOT(slotRefreshFolders()));
|
||||
connect(_ui.folderTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), SIGNAL(completeChanged()));
|
||||
connect(_ui.folderTreeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), SIGNAL(completeChanged()));
|
||||
connect(_ui.folderTreeWidget, SIGNAL(itemExpanded(QTreeWidgetItem*)), SLOT(slotItemExpanded(QTreeWidgetItem*)));
|
||||
connect(_ui.folderTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(slotCurrentItemChanged(QTreeWidgetItem*)));
|
||||
connect(_ui.folderEntry, SIGNAL(textEdited(QString)), SLOT(slotFolderEntryEdited(QString)));
|
||||
|
||||
_lscolTimer.setInterval(500);
|
||||
_lscolTimer.setSingleShot(true);
|
||||
connect(&_lscolTimer, SIGNAL(timeout()), SLOT(slotLsColFolderEntry()));
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
_ui.folderTreeWidget->header()->setSectionResizeMode(0,QHeaderView::ResizeToContents);
|
||||
// Make sure that there will be a scrollbar when the contents is too wide
|
||||
_ui.folderTreeWidget->header()->setStretchLastSection(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FolderWizardRemotePath::slotAddRemoteFolder()
|
||||
@@ -288,6 +297,8 @@ void FolderWizardRemotePath::slotCreateRemoteFolderFinished(QNetworkReply::Netwo
|
||||
qDebug() << "** webdav mkdir request finished";
|
||||
showWarn(tr("Folder was successfully created on %1.").arg(Theme::instance()->appNameGUI()));
|
||||
slotRefreshFolders();
|
||||
_ui.folderEntry->setText(static_cast<MkColJob *>(sender())->path());
|
||||
slotLsColFolderEntry();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,27 +326,58 @@ static QTreeWidgetItem* findFirstChild(QTreeWidgetItem *parent, const QString& t
|
||||
|
||||
void FolderWizardRemotePath::recursiveInsert(QTreeWidgetItem *parent, QStringList pathTrail, QString path)
|
||||
{
|
||||
QFileIconProvider prov;
|
||||
QIcon folderIcon = prov.icon(QFileIconProvider::Folder);
|
||||
if (pathTrail.size() == 0) {
|
||||
if (path.endsWith('/')) {
|
||||
path.chop(1);
|
||||
}
|
||||
parent->setToolTip(0, path);
|
||||
parent->setData(0, Qt::UserRole, path);
|
||||
} else {
|
||||
QTreeWidgetItem *item = findFirstChild(parent, pathTrail.first());
|
||||
if (!item) {
|
||||
item = new QTreeWidgetItem(parent);
|
||||
item->setIcon(0, folderIcon);
|
||||
item->setText(0, pathTrail.first());
|
||||
item->setData(0, Qt::UserRole, pathTrail.first());
|
||||
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
}
|
||||
if (pathTrail.isEmpty())
|
||||
return;
|
||||
|
||||
pathTrail.removeFirst();
|
||||
recursiveInsert(item, pathTrail, path);
|
||||
const QString parentPath = parent->data(0, Qt::UserRole).toString();
|
||||
const QString folderName = pathTrail.first();
|
||||
QString folderPath;
|
||||
if (parentPath == QLatin1String("/")) {
|
||||
folderPath = folderName;
|
||||
} else {
|
||||
folderPath = parentPath + "/" + folderName;
|
||||
}
|
||||
QTreeWidgetItem *item = findFirstChild(parent, folderName);
|
||||
if (!item) {
|
||||
item = new QTreeWidgetItem(parent);
|
||||
QFileIconProvider prov;
|
||||
QIcon folderIcon = prov.icon(QFileIconProvider::Folder);
|
||||
item->setIcon(0, folderIcon);
|
||||
item->setText(0, folderName);
|
||||
item->setData(0, Qt::UserRole, folderPath);
|
||||
item->setToolTip(0, folderPath);
|
||||
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
}
|
||||
|
||||
pathTrail.removeFirst();
|
||||
recursiveInsert(item, pathTrail, path);
|
||||
}
|
||||
|
||||
bool FolderWizardRemotePath::selectByPath(QString path)
|
||||
{
|
||||
if (path.startsWith(QLatin1Char('/'))) {
|
||||
path = path.mid(1);
|
||||
}
|
||||
if (path.endsWith(QLatin1Char('/'))) {
|
||||
path.chop(1);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *it = _ui.folderTreeWidget->topLevelItem(0);
|
||||
if (!path.isEmpty()) {
|
||||
const QStringList pathTrail = path.split(QLatin1Char('/'));
|
||||
foreach (const QString& path, pathTrail) {
|
||||
if (!it) {
|
||||
return false;
|
||||
}
|
||||
it = findFirstChild(it, path);
|
||||
}
|
||||
}
|
||||
if (!it) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_ui.folderTreeWidget->setCurrentItem(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FolderWizardRemotePath::slotUpdateDirectories(const QStringList &list)
|
||||
@@ -367,6 +409,7 @@ void FolderWizardRemotePath::slotRefreshFolders()
|
||||
SLOT(slotUpdateDirectories(QStringList)));
|
||||
job->start();
|
||||
_ui.folderTreeWidget->clear();
|
||||
_ui.folderEntry->clear();
|
||||
}
|
||||
|
||||
void FolderWizardRemotePath::slotItemExpanded(QTreeWidgetItem *item)
|
||||
@@ -379,6 +422,49 @@ void FolderWizardRemotePath::slotItemExpanded(QTreeWidgetItem *item)
|
||||
job->start();
|
||||
}
|
||||
|
||||
void FolderWizardRemotePath::slotCurrentItemChanged(QTreeWidgetItem *item)
|
||||
{
|
||||
if (item) {
|
||||
QString dir = item->data(0, Qt::UserRole).toString();
|
||||
if (!dir.startsWith(QLatin1Char('/'))) {
|
||||
dir.prepend(QLatin1Char('/'));
|
||||
}
|
||||
_ui.folderEntry->setText(dir);
|
||||
}
|
||||
|
||||
emit completeChanged();
|
||||
}
|
||||
|
||||
void FolderWizardRemotePath::slotFolderEntryEdited(const QString& text)
|
||||
{
|
||||
if (selectByPath(text)) {
|
||||
_lscolTimer.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
_ui.folderTreeWidget->setCurrentItem(0);
|
||||
_lscolTimer.start(); // avoid sending a request on each keystroke
|
||||
}
|
||||
|
||||
void FolderWizardRemotePath::slotLsColFolderEntry()
|
||||
{
|
||||
QString path = _ui.folderEntry->text();
|
||||
if (path.startsWith(QLatin1Char('/')))
|
||||
path = path.mid(1);
|
||||
|
||||
LsColJob *job = new LsColJob(_account, path, this);
|
||||
job->setProperties(QList<QByteArray>() << "resourcetype");
|
||||
connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
|
||||
SLOT(slotTypedPathFound(QStringList)));
|
||||
job->start();
|
||||
}
|
||||
|
||||
void FolderWizardRemotePath::slotTypedPathFound(const QStringList& subpaths)
|
||||
{
|
||||
slotUpdateDirectories(subpaths);
|
||||
selectByPath(_ui.folderEntry->text());
|
||||
}
|
||||
|
||||
FolderWizardRemotePath::~FolderWizardRemotePath()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ class SelectiveSyncTreeView;
|
||||
class ownCloudInfo;
|
||||
|
||||
class FormatWarningsWizardPage : public QWizardPage {
|
||||
Q_OBJECT
|
||||
protected:
|
||||
QString formatWarnings(const QStringList &warnings) const;
|
||||
};
|
||||
@@ -86,11 +87,17 @@ protected slots:
|
||||
void slotUpdateDirectories(const QStringList&);
|
||||
void slotRefreshFolders();
|
||||
void slotItemExpanded(QTreeWidgetItem*);
|
||||
void slotCurrentItemChanged(QTreeWidgetItem*);
|
||||
void slotFolderEntryEdited(const QString& text);
|
||||
void slotLsColFolderEntry();
|
||||
void slotTypedPathFound(const QStringList& subpaths);
|
||||
private:
|
||||
void recursiveInsert(QTreeWidgetItem *parent, QStringList pathTrail, QString path);
|
||||
bool selectByPath(QString path);
|
||||
Ui_FolderWizardTargetPage _ui;
|
||||
bool _warnWasVisible;
|
||||
AccountPtr _account;
|
||||
QTimer _lscolTimer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="3" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="folderEntry"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QFrame" name="warnFrame">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
@@ -179,7 +182,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
||||
@@ -43,7 +43,6 @@ IgnoreListEditor::IgnoreListEditor(QWidget *parent) :
|
||||
connect(this, SIGNAL(accepted()), SLOT(slotUpdateLocalIgnoreList()));
|
||||
ui->removePushButton->setEnabled(false);
|
||||
connect(ui->listWidget, SIGNAL(itemSelectionChanged()), SLOT(slotItemSelectionChanged()));
|
||||
connect(ui->listWidget, SIGNAL(itemActivated(QListWidgetItem*)), SLOT(slotItemChanged(QListWidgetItem*)));
|
||||
connect(ui->removePushButton, SIGNAL(clicked()), SLOT(slotRemoveCurrentItem()));
|
||||
connect(ui->addPushButton, SIGNAL(clicked()), SLOT(slotAddPattern()));
|
||||
connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(slotEditPattern(QListWidgetItem*)));
|
||||
|
||||
@@ -28,13 +28,6 @@
|
||||
|
||||
#include "updater/updater.h"
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#ifdef WITH_CRASHREPORTER
|
||||
#include "configfile.h"
|
||||
#include <libcrashreporter-handler/Handler.h>
|
||||
#endif
|
||||
|
||||
#include <QTimer>
|
||||
#include <QMessageBox>
|
||||
|
||||
@@ -59,12 +52,6 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
OCC::Application app(argc, argv);
|
||||
|
||||
|
||||
#ifdef WITH_CRASHREPORTER
|
||||
if (ConfigFile().crashReporter())
|
||||
new CrashReporter::Handler( QDir::tempPath(), true, CRASHREPORTER_EXECUTABLE );
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
@@ -221,7 +221,12 @@ void ownCloudGui::slotComputeOverallSyncStatus()
|
||||
_tray->setToolTip(tr("Please sign in"));
|
||||
return;
|
||||
}
|
||||
if (!a->isConnectedOrMaintenance()) {
|
||||
if (a->state() == AccountState::ServiceUnavailable) {
|
||||
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
||||
_tray->setToolTip(tr("Server is temporarily unavailable"));
|
||||
return;
|
||||
}
|
||||
if (!a->isConnected()) {
|
||||
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
||||
_tray->setToolTip(tr("Disconnected from server"));
|
||||
return;
|
||||
|
||||
@@ -145,6 +145,9 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
|
||||
}
|
||||
AccountPtr account = _ocWizard->account();
|
||||
account->setUrl(url);
|
||||
// Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth()
|
||||
// when there was a previous account.
|
||||
account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
|
||||
// Set fake credentials beforfe we check what credential it actually is.
|
||||
account->setCredentials(CredentialsFactory::create("dummy"));
|
||||
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), this);
|
||||
@@ -186,6 +189,10 @@ void OwncloudSetupWizard::slotNoOwnCloudFoundAuth(QNetworkReply *reply)
|
||||
.arg(Theme::instance()->appNameGUI(),
|
||||
reply->url().toString(),
|
||||
reply->errorString()), checkDowngradeAdvised(reply));
|
||||
|
||||
// Allow the credentials dialog to pop up again for the same URL.
|
||||
// Maybe the user just clicked 'Cancel' by accident or changed his mind.
|
||||
_ocWizard->account()->resetSslCertErrorState();
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::slotNoOwnCloudFoundAuthTimeout(const QUrl&url)
|
||||
@@ -214,11 +221,72 @@ void OwncloudSetupWizard::testOwnCloudConnect()
|
||||
auto *job = new PropfindJob(account, "/", this);
|
||||
job->setIgnoreCredentialFailure(true);
|
||||
job->setProperties(QList<QByteArray>() << "getlastmodified");
|
||||
connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep()));
|
||||
connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotConnectionCheck(QNetworkReply*)));
|
||||
connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep()));
|
||||
connect(job, SIGNAL(finishedWithError()), this, SLOT(slotAuthError()));
|
||||
job->start();
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::slotAuthError()
|
||||
{
|
||||
QString errorMsg;
|
||||
|
||||
PropfindJob* job = qobject_cast<PropfindJob*>(sender());
|
||||
if (!job) {
|
||||
qWarning() << "Can't check for authed redirects. This slot should be invoked from PropfindJob!";
|
||||
return;
|
||||
}
|
||||
QNetworkReply* reply = job->reply();
|
||||
|
||||
// If there were redirects on the *authed* requests, also store
|
||||
// the updated server URL, similar to redirects on status.php.
|
||||
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||
if (!redirectUrl.isEmpty()) {
|
||||
qDebug() << "authed request was redirected to" << redirectUrl.toString();
|
||||
|
||||
// strip the expected path
|
||||
QString path = redirectUrl.path();
|
||||
static QString expectedPath = "/" + _ocWizard->account()->davPath();
|
||||
if (path.endsWith(expectedPath)) {
|
||||
path.chop(expectedPath.size());
|
||||
redirectUrl.setPath(path);
|
||||
|
||||
qDebug() << "setting account url to" << redirectUrl.toString();
|
||||
_ocWizard->account()->setUrl(redirectUrl);
|
||||
testOwnCloudConnect();
|
||||
return;
|
||||
}
|
||||
errorMsg = tr("The authenticated request to the server was redirected to "
|
||||
"'%1'. The URL is bad, the server is misconfigured.")
|
||||
.arg(redirectUrl.toString());
|
||||
|
||||
// A 404 is actually a success: we were authorized to know that the folder does
|
||||
// not exist. It will be created later...
|
||||
} else if (reply->error() == QNetworkReply::ContentNotFoundError) {
|
||||
_ocWizard->successfulStep();
|
||||
return;
|
||||
|
||||
// Provide messages for other errors, such as invalid credentials.
|
||||
} else if (reply->error() != QNetworkReply::NoError) {
|
||||
if (!_ocWizard->account()->credentials()->stillValid(reply)) {
|
||||
errorMsg = tr("Access forbidden by server. To verify that you have proper access, "
|
||||
"<a href=\"%1\">click here</a> to access the service with your browser.")
|
||||
.arg(_ocWizard->account()->url().toString());
|
||||
} else {
|
||||
errorMsg = errorMessage(reply->errorString(), reply->readAll());
|
||||
}
|
||||
|
||||
// Something else went wrong, maybe the response was 200 but with invalid data.
|
||||
} else {
|
||||
errorMsg = tr("There was an invalid response to an authenticated webdav request");
|
||||
}
|
||||
|
||||
_ocWizard->show();
|
||||
if (_ocWizard->currentId() == WizardCommon::Page_ShibbolethCreds) {
|
||||
_ocWizard->back();
|
||||
}
|
||||
_ocWizard->displayError(errorMsg, _ocWizard->currentId() == WizardCommon::Page_ServerSetup && checkDowngradeAdvised(reply));
|
||||
}
|
||||
|
||||
bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply)
|
||||
{
|
||||
if(reply->url().scheme() != QLatin1String("https")) {
|
||||
@@ -242,29 +310,6 @@ bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply)
|
||||
return true;
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::slotConnectionCheck(QNetworkReply* reply)
|
||||
{
|
||||
QString msg = reply->errorString();
|
||||
switch (reply->error()) {
|
||||
case QNetworkReply::NoError:
|
||||
case QNetworkReply::ContentNotFoundError:
|
||||
_ocWizard->successfulStep();
|
||||
break;
|
||||
default:
|
||||
if (!_ocWizard->account()->credentials()->stillValid(reply)) {
|
||||
msg = tr("Access forbidden by server. To verify that you have proper access, "
|
||||
"<a href=\"%1\">click here</a> to access the service with your browser.")
|
||||
.arg(_ocWizard->account()->url().toString());
|
||||
}
|
||||
_ocWizard->show();
|
||||
if (_ocWizard->currentId() == WizardCommon::Page_ShibbolethCreds) {
|
||||
_ocWizard->back();
|
||||
}
|
||||
_ocWizard->displayError(msg, _ocWizard->currentId() == WizardCommon::Page_ServerSetup && checkDowngradeAdvised(reply));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFolder, const QString& remoteFolder)
|
||||
{
|
||||
qDebug() << "Setup local sync folder for new oC connection " << localFolder;
|
||||
@@ -291,7 +336,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo
|
||||
}
|
||||
if (nextStep) {
|
||||
EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), _ocWizard->account()->davPath() + remoteFolder, this);
|
||||
connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotAuthCheckReply(QNetworkReply*)));
|
||||
connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotRemoteFolderExists(QNetworkReply*)));
|
||||
job->start();
|
||||
} else {
|
||||
finalizeSetup( false );
|
||||
@@ -299,7 +344,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo
|
||||
}
|
||||
|
||||
// ### TODO move into EntityExistsJob once we decide if/how to return gui strings from jobs
|
||||
void OwncloudSetupWizard::slotAuthCheckReply(QNetworkReply *reply)
|
||||
void OwncloudSetupWizard::slotRemoteFolderExists(QNetworkReply *reply)
|
||||
{
|
||||
bool ok = true;
|
||||
QString error;
|
||||
@@ -519,8 +564,10 @@ bool DetermineAuthTypeJob::finished()
|
||||
} else if (redirection.toString().endsWith(account()->davPath())) {
|
||||
// do a new run
|
||||
_redirects++;
|
||||
resetTimeout();
|
||||
setReply(getRequest(redirection));
|
||||
setupConnections(reply());
|
||||
return false; // don't discard
|
||||
} else {
|
||||
QRegExp shibbolethyWords("SAML|wayf");
|
||||
|
||||
|
||||
@@ -62,10 +62,10 @@ private slots:
|
||||
void slotNoOwnCloudFoundAuthTimeout(const QUrl&url);
|
||||
|
||||
void slotConnectToOCUrl(const QString&);
|
||||
void slotConnectionCheck(QNetworkReply*);
|
||||
void slotAuthError();
|
||||
|
||||
void slotCreateLocalAndRemoteFolders(const QString&, const QString&);
|
||||
void slotAuthCheckReply(QNetworkReply*);
|
||||
void slotRemoteFolderExists(QNetworkReply*);
|
||||
void slotCreateRemoteFolderFinished(QNetworkReply::NetworkError);
|
||||
void slotAssistantFinished( int );
|
||||
void slotSkipFolderConfiguration();
|
||||
|
||||
@@ -73,16 +73,10 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
|
||||
_copyBtn->setToolTip( tr("Copy the activity list to the clipboard."));
|
||||
_copyBtn->setEnabled(false);
|
||||
connect(_copyBtn, SIGNAL(clicked()), SLOT(copyToClipboard()));
|
||||
|
||||
ConfigFile cfg;
|
||||
cfg.restoreGeometryHeader(_ui->_treeWidget->header());
|
||||
}
|
||||
|
||||
ProtocolWidget::~ProtocolWidget()
|
||||
{
|
||||
ConfigFile cfg;
|
||||
cfg.saveGeometryHeader(_ui->_treeWidget->header() );
|
||||
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
@@ -137,6 +131,20 @@ void ProtocolWidget::slotRetrySync()
|
||||
folderMan->slotScheduleAllFolders();
|
||||
}
|
||||
|
||||
void ProtocolWidget::showEvent(QShowEvent *ev)
|
||||
{
|
||||
ConfigFile cfg;
|
||||
cfg.restoreGeometryHeader(_ui->_treeWidget->header());
|
||||
QWidget::showEvent(ev);
|
||||
}
|
||||
|
||||
void ProtocolWidget::hideEvent(QHideEvent *ev)
|
||||
{
|
||||
ConfigFile cfg;
|
||||
cfg.saveGeometryHeader(_ui->_treeWidget->header() );
|
||||
QWidget::hideEvent(ev);
|
||||
}
|
||||
|
||||
void ProtocolWidget::cleanIgnoreItems(const QString& folder)
|
||||
{
|
||||
int itemCnt = _ui->_treeWidget->topLevelItemCount();
|
||||
@@ -159,16 +167,11 @@ void ProtocolWidget::cleanIgnoreItems(const QString& folder)
|
||||
|
||||
QString ProtocolWidget::timeString(QDateTime dt, QLocale::FormatType format) const
|
||||
{
|
||||
QLocale loc = QLocale::system();
|
||||
QString timeStr;
|
||||
|
||||
if( format == QLocale::NarrowFormat ) {
|
||||
timeStr = loc.toString(dt, QLocale::NarrowFormat);
|
||||
} else {
|
||||
timeStr = loc.toString(dt, format);
|
||||
}
|
||||
|
||||
return timeStr;
|
||||
const QLocale loc = QLocale::system();
|
||||
QString dtFormat = loc.dateTimeFormat(format);
|
||||
static const QRegExp re("(HH|H|hh|h):mm(?!:s)");
|
||||
dtFormat.replace(re, "\\1:mm:ss");
|
||||
return loc.toString(dt, dtFormat);
|
||||
}
|
||||
|
||||
void ProtocolWidget::slotOpenFile( QTreeWidgetItem *item, int )
|
||||
@@ -203,7 +206,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
|
||||
const QString longTimeStr = timeString(timestamp, QLocale::LongFormat);
|
||||
|
||||
columns << timeStr;
|
||||
columns << fixupFilename(item._file);
|
||||
columns << fixupFilename(item._originalFile);
|
||||
columns << folder;
|
||||
|
||||
// If the error string is set, it's prefered because it is a useful user message.
|
||||
|
||||
@@ -39,8 +39,6 @@ public:
|
||||
explicit ProtocolWidget(QWidget *parent = 0);
|
||||
~ProtocolWidget();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void slotProgressInfo( const QString& folder, const Progress::Info& progress );
|
||||
void slotOpenFile( QTreeWidgetItem* item, int );
|
||||
@@ -49,6 +47,10 @@ protected slots:
|
||||
void copyToClipboard();
|
||||
void slotRetrySync();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *);
|
||||
void hideEvent(QHideEvent *);
|
||||
|
||||
signals:
|
||||
void guiLog(const QString&, const QString&);
|
||||
|
||||
|
||||
@@ -26,10 +26,33 @@
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
#include <QScopedValueRollback>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QLabel>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
|
||||
class SelectiveSyncTreeViewItem : public QTreeWidgetItem {
|
||||
public:
|
||||
SelectiveSyncTreeViewItem(int type = QTreeWidgetItem::Type)
|
||||
: QTreeWidgetItem(type) { }
|
||||
SelectiveSyncTreeViewItem(const QStringList &strings, int type = QTreeWidgetItem::Type)
|
||||
: QTreeWidgetItem(strings, type) { }
|
||||
SelectiveSyncTreeViewItem(QTreeWidget *view, int type = QTreeWidgetItem::Type)
|
||||
: QTreeWidgetItem(view, type) { }
|
||||
SelectiveSyncTreeViewItem(QTreeWidgetItem *parent, int type = QTreeWidgetItem::Type)
|
||||
: QTreeWidgetItem(parent, type) { }
|
||||
|
||||
private:
|
||||
bool operator<(const QTreeWidgetItem &other)const {
|
||||
int column = treeWidget()->sortColumn();
|
||||
if (column == 1) {
|
||||
return data(1, Qt::UserRole).toLongLong() < other.data(1, Qt::UserRole).toLongLong();
|
||||
}
|
||||
return QTreeWidgetItem::operator <(other);
|
||||
}
|
||||
};
|
||||
|
||||
SelectiveSyncTreeView::SelectiveSyncTreeView(AccountPtr account, QWidget* parent)
|
||||
: QTreeWidget(parent), _inserting(false), _account(account)
|
||||
{
|
||||
@@ -101,9 +124,9 @@ void SelectiveSyncTreeView::recursiveInsert(QTreeWidgetItem* parent, QStringList
|
||||
parent->setToolTip(0, path);
|
||||
parent->setData(0, Qt::UserRole, path);
|
||||
} else {
|
||||
QTreeWidgetItem *item = findFirstChild(parent, pathTrail.first());
|
||||
SelectiveSyncTreeViewItem *item = static_cast<SelectiveSyncTreeViewItem*>(findFirstChild(parent, pathTrail.first()));
|
||||
if (!item) {
|
||||
item = new QTreeWidgetItem(parent);
|
||||
item = new SelectiveSyncTreeViewItem(parent);
|
||||
if (parent->checkState(0) == Qt::Checked
|
||||
|| parent->checkState(0) == Qt::PartiallyChecked) {
|
||||
item->setCheckState(0, Qt::Checked);
|
||||
@@ -138,7 +161,7 @@ void SelectiveSyncTreeView::slotUpdateDirectories(const QStringList&list)
|
||||
QScopedValueRollback<bool> isInserting(_inserting);
|
||||
_inserting = true;
|
||||
|
||||
QTreeWidgetItem *root = topLevelItem(0);
|
||||
SelectiveSyncTreeViewItem *root = static_cast<SelectiveSyncTreeViewItem*>(topLevelItem(0));
|
||||
|
||||
if (!root && list.size() <= 1) {
|
||||
_loading->setText(tr("No subfolders currently on the server."));
|
||||
@@ -149,7 +172,7 @@ void SelectiveSyncTreeView::slotUpdateDirectories(const QStringList&list)
|
||||
}
|
||||
|
||||
if (!root) {
|
||||
root = new QTreeWidgetItem(this);
|
||||
root = new SelectiveSyncTreeViewItem(this);
|
||||
root->setText(0, _rootName);
|
||||
root->setIcon(0, Theme::instance()->applicationIcon());
|
||||
root->setData(0, Qt::UserRole, QString());
|
||||
|
||||
+114
-76
@@ -21,6 +21,7 @@
|
||||
#include "folder.h"
|
||||
#include "theme.h"
|
||||
#include "syncresult.h"
|
||||
#include "configfile.h"
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
#include <QBuffer>
|
||||
@@ -44,6 +45,8 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
|
||||
_resharingAllowed(resharingAllowed)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setObjectName("SharingDialog"); // required as group for saveGeometry call
|
||||
|
||||
_ui->setupUi(this);
|
||||
_ui->pushButton_copy->setIcon(QIcon::fromTheme("edit-copy"));
|
||||
_ui->pushButton_copy->setEnabled(false);
|
||||
@@ -84,24 +87,31 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
|
||||
QIcon icon = icon_provider.icon(f_info);
|
||||
_ui->label_icon->setPixmap(icon.pixmap(40,40));
|
||||
|
||||
QString name;
|
||||
if( f_info.isDir() ) {
|
||||
name = tr("Share Directory");
|
||||
} else {
|
||||
name = tr("Share File");
|
||||
}
|
||||
_ui->groupBox->setTitle(name);
|
||||
|
||||
QString lPath(_localPath);
|
||||
if( lPath.length() > 50) {
|
||||
lPath = QLatin1String("...")+lPath.right(50);
|
||||
}
|
||||
_ui->label_name->setText(tr("Local path: %1").arg(lPath));
|
||||
QFileInfo lPath(_localPath);
|
||||
QString fileName = lPath.fileName();
|
||||
_ui->label_name->setText(tr("%1").arg(fileName));
|
||||
QFont f( _ui->label_name->font());
|
||||
f.setPointSize( f.pointSize() * 1.4 );
|
||||
_ui->label_name->setFont( f );
|
||||
|
||||
_ui->label_sharePath->setWordWrap(true);
|
||||
_ui->label_sharePath->setText(tr("%1 path: %2").arg(Theme::instance()->appNameGUI()).arg(_sharePath));
|
||||
QString ocDir(_sharePath);
|
||||
ocDir.truncate(ocDir.length()-fileName.length());
|
||||
|
||||
if( ocDir == QLatin1String("/")) {
|
||||
_ui->label_sharePath->setText(QString());
|
||||
} else {
|
||||
if( ocDir.startsWith(QLatin1Char('/')) ) {
|
||||
ocDir = ocDir.mid(1, -1);
|
||||
}
|
||||
if( ocDir.endsWith(QLatin1Char('/')) ) {
|
||||
ocDir.chop(1);
|
||||
}
|
||||
_ui->label_sharePath->setText(tr("Folder: %2").arg(ocDir));
|
||||
}
|
||||
|
||||
this->setWindowTitle(tr("%1 Sharing").arg(Theme::instance()->appNameGUI()));
|
||||
_ui->label_password->setText(tr("Set p&assword"));
|
||||
_ui->checkBox_password->setText(tr("P&assword protect"));
|
||||
// check if the file is already inside of a synced folder
|
||||
if( sharePath.isEmpty() ) {
|
||||
// The file is not yet in an ownCloud synced folder. We could automatically
|
||||
@@ -128,6 +138,21 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
|
||||
_ui->errorLabel->hide();
|
||||
}
|
||||
|
||||
void ShareDialog::done( int r ) {
|
||||
ConfigFile cfg;
|
||||
cfg.saveGeometry(this);
|
||||
QDialog::done(r);
|
||||
}
|
||||
|
||||
static int getJsonReturnCode(const QVariantMap &json, QString &message)
|
||||
{
|
||||
//TODO proper checking
|
||||
int code = json.value("ocs").toMap().value("meta").toMap().value("statuscode").toInt();
|
||||
message = json.value("ocs").toMap().value("meta").toMap().value("message").toString();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void ShareDialog::setExpireDate(const QDate &date)
|
||||
{
|
||||
if( _public_share_id == 0 ) {
|
||||
@@ -146,16 +171,14 @@ void ShareDialog::setExpireDate(const QDate &date)
|
||||
|
||||
OcsShareJob *job = new OcsShareJob("PUT", url, _account, this);
|
||||
job->setPostParams(postParams);
|
||||
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotExpireSet(QString)));
|
||||
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotExpireSet(QVariantMap)));
|
||||
job->start();
|
||||
}
|
||||
|
||||
void ShareDialog::slotExpireSet(const QString &reply)
|
||||
void ShareDialog::slotExpireSet(const QVariantMap &reply)
|
||||
{
|
||||
QString message;
|
||||
int code = checkJsonReturnCode(reply, message);
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Status code: " << code;
|
||||
int code = getJsonReturnCode(reply, message);
|
||||
if (code != 100) {
|
||||
displayError(code);
|
||||
}
|
||||
@@ -218,18 +241,15 @@ void ShareDialog::setPassword(const QString &password)
|
||||
}
|
||||
OcsShareJob *job = new OcsShareJob(verb, url, _account, this);
|
||||
job->setPostParams(requestParams);
|
||||
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotPasswordSet(QString)));
|
||||
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotPasswordSet(QVariantMap)));
|
||||
job->start();
|
||||
_passwordJobRunning = true;
|
||||
}
|
||||
|
||||
void ShareDialog::slotPasswordSet(const QString &reply)
|
||||
void ShareDialog::slotPasswordSet(const QVariantMap &reply)
|
||||
{
|
||||
QString message;
|
||||
int code = checkJsonReturnCode(reply, message);
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Status code: " << code;
|
||||
|
||||
int code = getJsonReturnCode(reply, message);
|
||||
if (code != 100) {
|
||||
displayError(code);
|
||||
}
|
||||
@@ -251,23 +271,20 @@ void ShareDialog::getShares()
|
||||
params.append(qMakePair(QString::fromLatin1("path"), _sharePath));
|
||||
url.setQueryItems(params);
|
||||
OcsShareJob *job = new OcsShareJob("GET", url, _account, this);
|
||||
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotSharesFetched(QString)));
|
||||
job->addPassStatusCode(404); // don't report error if share doesn't exist yet
|
||||
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotSharesFetched(QVariantMap)));
|
||||
job->start();
|
||||
}
|
||||
|
||||
void ShareDialog::slotSharesFetched(const QString &reply)
|
||||
void ShareDialog::slotSharesFetched(const QVariantMap &reply)
|
||||
{
|
||||
QString message;
|
||||
int code = checkJsonReturnCode(reply, message);
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Status code: " << code;
|
||||
int code = getJsonReturnCode(reply, message);
|
||||
if (code != 100 && code != 404) {
|
||||
displayError(code);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
QVariantMap json = QtJson::parse(reply, success).toMap();
|
||||
ShareDialog::_shares = json.value("ocs").toMap().value("data").toList();
|
||||
ShareDialog::_shares = reply.value("ocs").toMap().value("data").toList();
|
||||
const QString versionString = AccountManager::instance()->account()->serverVersion();
|
||||
|
||||
Q_FOREACH(auto share, ShareDialog::_shares) {
|
||||
@@ -275,6 +292,7 @@ void ShareDialog::slotSharesFetched(const QString &reply)
|
||||
|
||||
if (data.value("share_type").toInt() == SHARETYPE_PUBLIC) {
|
||||
_public_share_id = data.value("id").toULongLong();
|
||||
_ui->pushButton_copy->show();
|
||||
|
||||
_ui->widget_shareLink->show();
|
||||
_ui->checkBox_shareLink->setChecked(true);
|
||||
@@ -331,28 +349,47 @@ void ShareDialog::slotSharesFetched(const QString &reply)
|
||||
}
|
||||
}
|
||||
|
||||
void ShareDialog::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QDialog::resizeEvent(e);
|
||||
redrawElidedUrl();
|
||||
}
|
||||
|
||||
void ShareDialog::redrawElidedUrl()
|
||||
{
|
||||
QString u;
|
||||
|
||||
if( !_shareUrl.isEmpty() ) {
|
||||
QFontMetrics fm( _ui->_labelShareLink->font() );
|
||||
int linkLengthPixel = _ui->_labelShareLink->width();
|
||||
|
||||
const QUrl realUrl(_shareUrl);
|
||||
QString elidedUrl = fm.elidedText(_shareUrl, Qt::ElideRight, linkLengthPixel);
|
||||
|
||||
u = QString("<a href=\"%1\">%2</a>").arg(realUrl.toString(QUrl::None)).arg(elidedUrl);
|
||||
}
|
||||
_ui->_labelShareLink->setText(u);
|
||||
}
|
||||
|
||||
void ShareDialog::setShareLink( const QString& url )
|
||||
{
|
||||
// FIXME: shorten the url for output.
|
||||
const QUrl realUrl(url);
|
||||
if( realUrl.isValid() ) {
|
||||
const QString u = QString("<a href=\"%1\">%2</a>").arg(realUrl.toString(QUrl::None)).arg(url);
|
||||
_ui->_labelShareLink->setText(u);
|
||||
_shareUrl = url;
|
||||
_ui->pushButton_copy->setEnabled(true);
|
||||
} else {
|
||||
_shareUrl.clear();
|
||||
_ui->_labelShareLink->setText(QString::null);
|
||||
}
|
||||
redrawElidedUrl();
|
||||
|
||||
}
|
||||
|
||||
void ShareDialog::slotDeleteShareFetched(const QString &reply)
|
||||
void ShareDialog::slotDeleteShareFetched(const QVariantMap &reply)
|
||||
{
|
||||
QString message;
|
||||
int code = checkJsonReturnCode(reply, message);
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Status code: " << code;
|
||||
int code = getJsonReturnCode(reply, message);
|
||||
if (code != 100) {
|
||||
displayError(code);
|
||||
}
|
||||
@@ -386,29 +423,31 @@ void ShareDialog::slotCheckBoxShareLinkClicked()
|
||||
postParams.append(qMakePair(QString::fromLatin1("shareType"), QString::number(SHARETYPE_PUBLIC)));
|
||||
OcsShareJob *job = new OcsShareJob("POST", url, _account, this);
|
||||
job->setPostParams(postParams);
|
||||
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotCreateShareFetched(QString)));
|
||||
job->addPassStatusCode(403); // "password required" is not an error
|
||||
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotCreateShareFetched(QVariantMap)));
|
||||
job->start();
|
||||
} else {
|
||||
_pi_link->startAnimation();
|
||||
QUrl url = Account::concatUrlPath(_account->url(), QString("ocs/v1.php/apps/files_sharing/api/v1/shares/%1").arg(_public_share_id));
|
||||
OcsShareJob *job = new OcsShareJob("DELETE", url, _account, this);
|
||||
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotDeleteShareFetched(QString)));
|
||||
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotDeleteShareFetched(QVariantMap)));
|
||||
job->start();
|
||||
}
|
||||
}
|
||||
|
||||
void ShareDialog::slotCreateShareFetched(const QString &reply)
|
||||
void ShareDialog::slotCreateShareFetched(const QVariantMap &reply)
|
||||
{
|
||||
QString message;
|
||||
int code = checkJsonReturnCode(reply, message);
|
||||
int code = getJsonReturnCode(reply, message);
|
||||
_pi_link->stopAnimation();
|
||||
|
||||
if (code == 403) {
|
||||
// there needs to be a password
|
||||
_ui->checkBox_password->setChecked(true);
|
||||
_ui->checkBox_password->setVisible(false);
|
||||
_ui->label_password->setText(tr("Public shå requires a password:"));
|
||||
_ui->checkBox_password->setEnabled(false);
|
||||
_ui->checkBox_password->setText(tr("Public shå requires a password"));
|
||||
_ui->lineEdit_password->setFocus();
|
||||
_ui->pushButton_copy->hide();
|
||||
_ui->widget_shareLink->show();
|
||||
|
||||
slotCheckBoxPasswordClicked();
|
||||
@@ -418,16 +457,9 @@ void ShareDialog::slotCreateShareFetched(const QString &reply)
|
||||
return;
|
||||
}
|
||||
|
||||
bool success;
|
||||
QVariantMap json = QtJson::parse(reply, success).toMap();
|
||||
_public_share_id = json.value("ocs").toMap().values("data")[0].toMap().value("id").toULongLong();
|
||||
QString url = json.value("ocs").toMap().values("data")[0].toMap().value("url").toString();
|
||||
|
||||
setShareLink(url);
|
||||
|
||||
setShareCheckBoxTitle(true);
|
||||
|
||||
_ui->widget_shareLink->show();
|
||||
_public_share_id = reply.value("ocs").toMap().values("data")[0].toMap().value("id").toULongLong();
|
||||
_ui->pushButton_copy->show();
|
||||
getShares();
|
||||
}
|
||||
|
||||
void ShareDialog::slotCheckBoxPasswordClicked()
|
||||
@@ -435,7 +467,7 @@ void ShareDialog::slotCheckBoxPasswordClicked()
|
||||
if (_ui->checkBox_password->checkState() == Qt::Checked) {
|
||||
_ui->lineEdit_password->show();
|
||||
_ui->pushButton_setPassword->show();
|
||||
_ui->lineEdit_password->setPlaceholderText(tr("Choose a password for the public link"));
|
||||
_ui->lineEdit_password->setPlaceholderText(tr("Password"));
|
||||
_ui->lineEdit_password->setFocus();
|
||||
} else {
|
||||
ShareDialog::setPassword(QString());
|
||||
@@ -469,26 +501,10 @@ void ShareDialog::slotPushButtonCopyLinkPressed()
|
||||
clipboard->setText(_shareUrl);
|
||||
}
|
||||
|
||||
int ShareDialog::checkJsonReturnCode(const QString &reply, QString &message)
|
||||
{
|
||||
bool success;
|
||||
QVariantMap json = QtJson::parse(reply, success).toMap();
|
||||
|
||||
if (!success) {
|
||||
qDebug() << Q_FUNC_INFO << "Failed to parse reply";
|
||||
}
|
||||
|
||||
//TODO proper checking
|
||||
int code = json.value("ocs").toMap().value("meta").toMap().value("statuscode").toInt();
|
||||
message = json.value("ocs").toMap().value("meta").toMap().value("message").toString();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void ShareDialog::setShareCheckBoxTitle(bool haveShares)
|
||||
{
|
||||
const QString noSharesTitle(tr("Check to &share by public link"));
|
||||
const QString haveSharesTitle(tr("&Shared by public link (uncheck to delete share)"));
|
||||
const QString noSharesTitle(tr("&Share link"));
|
||||
const QString haveSharesTitle(tr("&Share link"));
|
||||
|
||||
if( haveShares ) {
|
||||
_ui->checkBox_shareLink->setText( haveSharesTitle );
|
||||
@@ -641,6 +657,7 @@ OcsShareJob::OcsShareJob(const QByteArray &verb, const QUrl &url, AccountPtr acc
|
||||
_verb(verb),
|
||||
_url(url)
|
||||
{
|
||||
_passStatusCodes.append(100);
|
||||
setIgnoreCredentialFailure(true);
|
||||
}
|
||||
|
||||
@@ -649,6 +666,11 @@ void OcsShareJob::setPostParams(const QList<QPair<QString, QString> >& postParam
|
||||
_postParams = postParams;
|
||||
}
|
||||
|
||||
void OcsShareJob::addPassStatusCode(int code)
|
||||
{
|
||||
_passStatusCodes.append(code);
|
||||
}
|
||||
|
||||
void OcsShareJob::start()
|
||||
{
|
||||
QNetworkRequest req;
|
||||
@@ -680,7 +702,23 @@ void OcsShareJob::start()
|
||||
|
||||
bool OcsShareJob::finished()
|
||||
{
|
||||
emit jobFinished(reply()->readAll());
|
||||
const QString replyData = reply()->readAll();
|
||||
|
||||
bool success;
|
||||
QVariantMap json = QtJson::parse(replyData, success).toMap();
|
||||
if (!success) {
|
||||
qDebug() << "Could not parse reply to" << _verb << _url << _postParams
|
||||
<< ":" << replyData;
|
||||
}
|
||||
|
||||
QString message;
|
||||
const int statusCode = getJsonReturnCode(json, message);
|
||||
if (!_passStatusCodes.contains(statusCode)) {
|
||||
qDebug() << "Reply to" << _verb << _url << _postParams
|
||||
<< "has unexpected status code:" << statusCode << replyData;
|
||||
}
|
||||
|
||||
emit jobFinished(json);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+12
-8
@@ -29,17 +29,19 @@ public:
|
||||
explicit OcsShareJob(const QByteArray& verb, const QUrl& url, AccountPtr account, QObject* parent = 0);
|
||||
|
||||
void setPostParams(const QList<QPair<QString, QString> >& postParams);
|
||||
void addPassStatusCode(int code);
|
||||
|
||||
public slots:
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
signals:
|
||||
void jobFinished(QString reply);
|
||||
void jobFinished(QVariantMap reply);
|
||||
private slots:
|
||||
virtual bool finished() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
QByteArray _verb;
|
||||
QUrl _url;
|
||||
QList<QPair<QString, QString> > _postParams;
|
||||
QVector<int> _passStatusCodes;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +51,6 @@ class ShareDialog;
|
||||
|
||||
class AbstractCredentials;
|
||||
class QuotaInfo;
|
||||
class MirallAccessManager;
|
||||
class SyncResult;
|
||||
|
||||
class ShareDialog : public QDialog
|
||||
@@ -63,11 +64,11 @@ public:
|
||||
void getShares();
|
||||
|
||||
private slots:
|
||||
void slotSharesFetched(const QString &reply);
|
||||
void slotCreateShareFetched(const QString &reply);
|
||||
void slotDeleteShareFetched(const QString &reply);
|
||||
void slotPasswordSet(const QString &reply);
|
||||
void slotExpireSet(const QString &reply);
|
||||
void slotSharesFetched(const QVariantMap &reply);
|
||||
void slotCreateShareFetched(const QVariantMap &reply);
|
||||
void slotDeleteShareFetched(const QVariantMap &reply);
|
||||
void slotPasswordSet(const QVariantMap &reply);
|
||||
void slotExpireSet(const QVariantMap &reply);
|
||||
void slotCalendarClicked(const QDate &date);
|
||||
void slotCheckBoxShareLinkClicked();
|
||||
void slotCheckBoxPasswordClicked();
|
||||
@@ -76,11 +77,15 @@ private slots:
|
||||
void slotPasswordChanged(const QString& newText);
|
||||
void slotPushButtonCopyLinkPressed();
|
||||
void slotThumbnailFetched(const int &statusCode, const QByteArray &reply);
|
||||
|
||||
void done( int r );
|
||||
private:
|
||||
void setShareCheckBoxTitle(bool haveShares);
|
||||
void displayError(int code);
|
||||
void displayError(const QString& errMsg);
|
||||
void setShareLink( const QString& url );
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void redrawElidedUrl();
|
||||
|
||||
Ui::ShareDialog *_ui;
|
||||
AccountPtr _account;
|
||||
@@ -98,7 +103,6 @@ private:
|
||||
qulonglong _public_share_id;
|
||||
void setPassword(const QString &password);
|
||||
void setExpireDate(const QDate &date);
|
||||
int checkJsonReturnCode(const QString &reply, QString &message);
|
||||
|
||||
QProgressIndicator *_pi_link;
|
||||
QProgressIndicator *_pi_password;
|
||||
|
||||
+121
-96
@@ -6,23 +6,71 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>403</width>
|
||||
<height>296</height>
|
||||
<width>372</width>
|
||||
<height>241</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Share NewDocument.odt</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="label_icon">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>share label</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QProgressIndicator" name="pi_share" native="true"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_sharePath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ownCloud Path:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_shareLink">
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_shareLink">
|
||||
<property name="text">
|
||||
@@ -34,8 +82,14 @@
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QWidget" name="widget_shareLink" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
@@ -68,7 +122,7 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_copy">
|
||||
<property name="text">
|
||||
<string>Copy &Link</string>
|
||||
<string>Copy &link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -79,30 +133,36 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_password">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Set password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_password">
|
||||
<property name="text">
|
||||
<string>Set p&assword</string>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>checkBox_password</cstring>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_password">
|
||||
<property name="echoMode">
|
||||
@@ -112,15 +172,24 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_setPassword">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Set &Password</string>
|
||||
<string>Set &password </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_expire">
|
||||
<property name="text">
|
||||
@@ -140,80 +209,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Share Info</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="label_icon">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>share label</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QProgressIndicator" name="pi_share" native="true"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_sharePath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ownCloud Path:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@@ -227,7 +222,37 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>errorLabel</zorder>
|
||||
<zorder>widget_shareLink</zorder>
|
||||
<zorder>buttonBox</zorder>
|
||||
<zorder>checkBox_password</zorder>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
||||
+36
-16
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) by Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
||||
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* 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
|
||||
@@ -24,6 +25,7 @@
|
||||
#include "syncfileitem.h"
|
||||
#include "filesystem.h"
|
||||
#include "version.h"
|
||||
#include "accountstate.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
@@ -136,7 +138,9 @@ SocketApi::~SocketApi()
|
||||
{
|
||||
DEBUG << "dtor";
|
||||
_localServer.close();
|
||||
qDeleteAll(_listeners);
|
||||
// All remaining sockets will be destroyed with _localServer, their parent
|
||||
Q_ASSERT(_listeners.isEmpty() || _listeners.first()->parent() == &_localServer);
|
||||
_listeners.clear();
|
||||
slotClearExcludesList();
|
||||
}
|
||||
|
||||
@@ -163,7 +167,7 @@ void SocketApi::slotReadExcludes()
|
||||
|
||||
void SocketApi::slotNewConnection()
|
||||
{
|
||||
SocketType* socket = _localServer.nextPendingConnection();
|
||||
QLocalSocket* socket = _localServer.nextPendingConnection();
|
||||
|
||||
if( ! socket ) {
|
||||
return;
|
||||
@@ -185,8 +189,9 @@ void SocketApi::slotNewConnection()
|
||||
broadcastMessage(QLatin1String("ICON_PATH"), iconPath );
|
||||
#endif
|
||||
|
||||
foreach( QString alias, FolderMan::instance()->map().keys() ) {
|
||||
slotRegisterPath(alias);
|
||||
foreach( Folder *f, FolderMan::instance()->map() ) {
|
||||
QString message = buildRegisterPathMessage(f->path());
|
||||
sendMessage(socket, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +199,7 @@ void SocketApi::onLostConnection()
|
||||
{
|
||||
DEBUG << "Lost connection " << sender();
|
||||
|
||||
SocketType* socket = qobject_cast<SocketType*>(sender());
|
||||
QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
|
||||
_listeners.removeAll(socket);
|
||||
socket->deleteLater();
|
||||
}
|
||||
@@ -202,7 +207,7 @@ void SocketApi::onLostConnection()
|
||||
|
||||
void SocketApi::slotReadSocket()
|
||||
{
|
||||
SocketType* socket = qobject_cast<SocketType*>(sender());
|
||||
QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
|
||||
Q_ASSERT(socket);
|
||||
|
||||
while(socket->canReadLine()) {
|
||||
@@ -210,12 +215,12 @@ void SocketApi::slotReadSocket()
|
||||
QString command = line.split(":").first();
|
||||
QString function = QString(QLatin1String("command_")).append(command);
|
||||
|
||||
QString functionWithArguments = function + QLatin1String("(QString,SocketType*)");
|
||||
QString functionWithArguments = function + QLatin1String("(QString,QLocalSocket*)");
|
||||
int indexOfMethod = this->metaObject()->indexOfMethod(functionWithArguments.toAscii());
|
||||
|
||||
QString argument = line.remove(0, command.length()+1).trimmed();
|
||||
if(indexOfMethod != -1) {
|
||||
QMetaObject::invokeMethod(this, function.toAscii(), Q_ARG(QString, argument), Q_ARG(SocketType*, socket));
|
||||
QMetaObject::invokeMethod(this, function.toAscii(), Q_ARG(QString, argument), Q_ARG(QLocalSocket*, socket));
|
||||
} else {
|
||||
DEBUG << "The command is not supported by this version of the client:" << command << "with argument:" << argument;
|
||||
}
|
||||
@@ -226,7 +231,10 @@ void SocketApi::slotRegisterPath( const QString& alias )
|
||||
{
|
||||
Folder *f = FolderMan::instance()->folder(alias);
|
||||
if (f) {
|
||||
broadcastMessage(QLatin1String("REGISTER_PATH"), f->path() );
|
||||
QString message = buildRegisterPathMessage(f->path());
|
||||
foreach(QLocalSocket *socket, _listeners) {
|
||||
sendMessage(socket, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +337,7 @@ void SocketApi::slotSyncItemDiscovered(const QString &folder, const SyncFileItem
|
||||
|
||||
|
||||
|
||||
void SocketApi::sendMessage(SocketType *socket, const QString& message, bool doWait)
|
||||
void SocketApi::sendMessage(QLocalSocket *socket, const QString& message, bool doWait)
|
||||
{
|
||||
DEBUG << "Sending message: " << message;
|
||||
QString localMessage = message;
|
||||
@@ -364,12 +372,12 @@ void SocketApi::broadcastMessage( const QString& verb, const QString& path, cons
|
||||
|
||||
// sendMessage already has a debug output
|
||||
//DEBUG << "Broadcasting to" << _listeners.count() << "listeners: " << msg;
|
||||
foreach(SocketType *socket, _listeners) {
|
||||
foreach(QLocalSocket *socket, _listeners) {
|
||||
sendMessage(socket, msg, doWait);
|
||||
}
|
||||
}
|
||||
|
||||
void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, SocketType* socket)
|
||||
void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket)
|
||||
{
|
||||
// This command is the same as RETRIEVE_FILE_STATUS
|
||||
|
||||
@@ -377,7 +385,7 @@ void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, SocketTy
|
||||
command_RETRIEVE_FILE_STATUS(argument, socket);
|
||||
}
|
||||
|
||||
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, SocketType* socket)
|
||||
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSocket* socket)
|
||||
{
|
||||
if( !socket ) {
|
||||
qDebug() << "No valid socket object.";
|
||||
@@ -405,7 +413,7 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, SocketType
|
||||
sendMessage(socket, message);
|
||||
}
|
||||
|
||||
void SocketApi::command_SHARE(const QString& localFile, SocketType* socket)
|
||||
void SocketApi::command_SHARE(const QString& localFile, QLocalSocket* socket)
|
||||
{
|
||||
if (!socket) {
|
||||
qDebug() << Q_FUNC_INFO << "No valid socket object.";
|
||||
@@ -419,6 +427,10 @@ void SocketApi::command_SHARE(const QString& localFile, SocketType* socket)
|
||||
const QString message = QLatin1String("SHARE:NOP:")+QDir::toNativeSeparators(localFile);
|
||||
// files that are not within a sync folder are not synced.
|
||||
sendMessage(socket, message);
|
||||
} else if (!shareFolder->accountState()->isConnected()) {
|
||||
const QString message = QLatin1String("SHARE:NOTCONNECTED:")+QDir::toNativeSeparators(localFile);
|
||||
// if the folder isn't connected, don't open the share dialog
|
||||
sendMessage(socket, message);
|
||||
} else {
|
||||
const QString folderForPath = shareFolder->path();
|
||||
const QString remotePath = shareFolder->remotePath() + localFile.right(localFile.count()-folderForPath.count()+1);
|
||||
@@ -439,16 +451,24 @@ void SocketApi::command_SHARE(const QString& localFile, SocketType* socket)
|
||||
}
|
||||
}
|
||||
|
||||
void SocketApi::command_VERSION(const QString&, SocketType* socket)
|
||||
void SocketApi::command_VERSION(const QString&, QLocalSocket* socket)
|
||||
{
|
||||
sendMessage(socket, QLatin1String("VERSION:" MIRALL_VERSION_STRING ":" MIRALL_SOCKET_API_VERSION));
|
||||
}
|
||||
|
||||
void SocketApi::command_SHARE_MENU_TITLE(const QString &, SocketType* socket)
|
||||
void SocketApi::command_SHARE_MENU_TITLE(const QString &, QLocalSocket* socket)
|
||||
{
|
||||
sendMessage(socket, QLatin1String("SHARE_MENU_TITLE:") + tr("Share with %1", "parameter is ownCloud").arg(Theme::instance()->appNameGUI()));
|
||||
}
|
||||
|
||||
QString SocketApi::buildRegisterPathMessage(const QString& path)
|
||||
{
|
||||
QFileInfo fi(path);
|
||||
QString message = QLatin1String("REGISTER_PATH:");
|
||||
message.append(QDir::toNativeSeparators(fi.absoluteFilePath()));
|
||||
return message;
|
||||
}
|
||||
|
||||
SqlQuery* SocketApi::getSqlQuery( Folder *folder )
|
||||
{
|
||||
if( !folder ) {
|
||||
|
||||
+8
-13
@@ -37,8 +37,6 @@ class QStringList;
|
||||
|
||||
namespace OCC {
|
||||
|
||||
typedef QLocalSocket SocketType;
|
||||
|
||||
class SyncFileStatus;
|
||||
class Folder;
|
||||
|
||||
@@ -72,23 +70,20 @@ private:
|
||||
SyncJournalFileRecord dbFileRecord_capi( Folder *folder, QString fileName );
|
||||
SqlQuery *getSqlQuery( Folder *folder );
|
||||
|
||||
void sendMessage(SocketType* socket, const QString& message, bool doWait = false);
|
||||
void sendMessage(QLocalSocket* socket, const QString& message, bool doWait = false);
|
||||
void broadcastMessage(const QString& verb, const QString &path, const QString &status = QString::null, bool doWait = false);
|
||||
|
||||
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, SocketType* socket);
|
||||
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, SocketType* socket);
|
||||
Q_INVOKABLE void command_SHARE(const QString& localFile, SocketType* socket);
|
||||
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket);
|
||||
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSocket* socket);
|
||||
Q_INVOKABLE void command_SHARE(const QString& localFile, QLocalSocket* socket);
|
||||
|
||||
Q_INVOKABLE void command_VERSION(const QString& argument, SocketType* socket);
|
||||
Q_INVOKABLE void command_VERSION(const QString& argument, QLocalSocket* socket);
|
||||
|
||||
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, SocketType* socket);
|
||||
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QLocalSocket* socket);
|
||||
QString buildRegisterPathMessage(const QString& path);
|
||||
|
||||
#ifdef SOCKETAPI_TCP
|
||||
QTcpServer _localServer;
|
||||
#else
|
||||
QList<QLocalSocket*> _listeners;
|
||||
QLocalServer _localServer;
|
||||
#endif
|
||||
QList<SocketType*> _listeners;
|
||||
c_strlist_t *_excludes;
|
||||
QHash<Folder*, SqlQuery*> _dbQueries;
|
||||
QHash<Folder*, SqlDatabase*> _openDbs;
|
||||
|
||||
+34
-14
@@ -31,6 +31,10 @@ SslButton::SslButton(QWidget *parent) :
|
||||
{
|
||||
setPopupMode(QToolButton::InstantPopup);
|
||||
setAutoRaise(true);
|
||||
|
||||
setMenu(new QMenu(this));
|
||||
QObject::connect(menu(), SIGNAL(aboutToShow()),
|
||||
this, SLOT(slotUpdateMenu()));
|
||||
}
|
||||
|
||||
QString SslButton::protoToString(QSsl::SslProtocol proto)
|
||||
@@ -178,19 +182,39 @@ void SslButton::updateAccountState(AccountState *accountState)
|
||||
} else {
|
||||
setVisible(true);
|
||||
}
|
||||
AccountPtr account = accountState->account();
|
||||
if(QMenu *oldMenu = menu()) {
|
||||
oldMenu->hide(); // Need to be hidden because the QToolButton would be left in invalid state if the menu is deleted while it is visible
|
||||
setMenu(0);
|
||||
oldMenu->deleteLater(); // setMenu do not delete the previous menu.
|
||||
}
|
||||
_accountState = accountState;
|
||||
|
||||
AccountPtr account = _accountState->account();
|
||||
if (account->url().scheme() == QLatin1String("https")) {
|
||||
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-https.png"))));
|
||||
QPixmap pm(Theme::hidpiFileName(":/client/resources/lock-https.png"));
|
||||
setIcon(QIcon(pm));
|
||||
QSslCipher cipher = account->sslConfiguration().sessionCipher();
|
||||
setToolTip(tr("This connection is encrypted using %1 bit %2.\n").arg(cipher.usedBits()).arg(cipher.name()));
|
||||
QMenu *menu = new QMenu(this);
|
||||
} else {
|
||||
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png"))));
|
||||
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void SslButton::slotUpdateMenu() {
|
||||
menu()->clear();
|
||||
|
||||
if (!_accountState) {
|
||||
return;
|
||||
}
|
||||
|
||||
AccountPtr account = _accountState->account();
|
||||
|
||||
if (account->url().scheme() == QLatin1String("https")) {
|
||||
|
||||
QList<QSslCertificate> chain = account->sslConfiguration().peerCertificateChain();
|
||||
menu->addAction(tr("Certificate information:"))->setEnabled(false);
|
||||
|
||||
if (chain.isEmpty()) {
|
||||
qWarning() << "empty certificate chain";
|
||||
return;
|
||||
}
|
||||
|
||||
menu()->addAction(tr("Certificate information:"))->setEnabled(false);
|
||||
|
||||
QList<QSslCertificate> tmpChain;
|
||||
foreach(QSslCertificate cert, chain) {
|
||||
@@ -213,13 +237,9 @@ void SslButton::updateAccountState(AccountState *accountState)
|
||||
it.toBack();
|
||||
int i = 0;
|
||||
while (it.hasPrevious()) {
|
||||
menu->addMenu(buildCertMenu(menu, it.previous(), account->approvedCerts(), i));
|
||||
menu()->addMenu(buildCertMenu(menu(), it.previous(), account->approvedCerts(), i));
|
||||
i++;
|
||||
}
|
||||
setMenu(menu);
|
||||
} else {
|
||||
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png"))));
|
||||
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário