1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2026-04-04 03:11:32 +02:00

Compare commits

..

227 Commits

Author SHA1 Message Date
Kevin Ottens
78da725ac3 Merge pull request #2598 from nextcloud/bump_version_3.0.3
Bump version to 3.0.3
2020-10-29 11:30:42 +01:00
Kevin Ottens
571e2a1fdb Bump version to 3.0.3
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-29 11:28:47 +01:00
Nextcloud bot
4f9c2a5c65 [tx-robot] updated from transifex 2020-10-28 03:41:56 +00:00
Nextcloud bot
90195646f0 [tx-robot] updated from transifex 2020-10-27 03:41:36 +00:00
Kevin Ottens
a20454f9f7 Merge pull request #2592 from nextcloud/backport/2582/stable-3.0
[stable-3.0] Also output the event flags in the debug logs
2020-10-26 14:20:15 +01:00
Kevin Ottens
f1842447b2 Also output the event flags in the debug logs
When we skip a watcher event on mac, we log the file path but not the
event flags which came with it. Let's add it, it should help figure out
what's going on with #2578.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-26 13:15:59 +00:00
Nextcloud bot
d9971f9535 [tx-robot] updated from transifex 2020-10-26 03:36:50 +00:00
Nextcloud bot
31f9af23ac [tx-robot] updated from transifex 2020-10-25 03:38:19 +00:00
Nextcloud bot
3f33475569 [tx-robot] updated from transifex 2020-10-24 03:38:33 +00:00
Nextcloud bot
02bdf69aa8 [tx-robot] updated from transifex 2020-10-23 03:37:58 +00:00
Nextcloud bot
ce40c11149 [tx-robot] updated from transifex 2020-10-22 03:38:23 +00:00
Kevin Ottens
72812831ed Merge pull request #2577 from nextcloud/backport/2575/stable-3.0
[stable-3.0] Expose branding values to qtquick
2020-10-21 14:43:04 +02:00
Kevin Ottens
d1e08ef2d5 Use the Theme colors for the header part of the window
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 12:21:22 +00:00
Kevin Ottens
cf18844c5a Expose Theme on the QML side
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 12:21:22 +00:00
Kevin Ottens
2499ec3312 Expose the branding related members of Theme as properties
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 12:21:22 +00:00
Kevin Ottens
3539d6c2c8 Don't hardcode the color of text in the header
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 12:21:22 +00:00
Kevin Ottens
6b511f8749 Get rid of ncBlueHover
Use a similar trick of a semi-transparent rectangle on top when the
mouse area is hovered. This way it will always work whatever is the
background color.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 12:21:22 +00:00
Camila
76f83b4715 Merge pull request #2576 from nextcloud/backport/2572/stable-3.0
[stable-3.0] Avoid depth infinity propfind for e2ee
2020-10-21 14:11:36 +02:00
Kevin Ottens
eb1ec74095 Don't use depth infinity anymore to get the folders e2ee status
This way we avoid the expensive SQL query on the server at the price of
more round-trips since we're doing the recursive traversal by hand now.

Also it turns out this depth was used for all the other propfind calls
during sync when we want fresher information regarding a folder. This
was very inefficient in all cases and won't happen anymore.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 11:58:50 +00:00
Kevin Ottens
9c25dc5363 Make sure jobs don't outlive ClientSideEncryption
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 11:58:50 +00:00
Kevin Ottens
36274d6f65 Factor out the logic to start a new e2ee status job
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 11:58:50 +00:00
Kevin Ottens
ce7319e32a Mention the folder we listed in the debug logs
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 11:58:50 +00:00
Kevin Ottens
41db853d36 Change the way we store the job result
If there's more than one job we need to unite the maps not simply overwrite
them.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 11:58:50 +00:00
Kevin Ottens
507e9e3559 Start managing a list of GetFolderEncryptStatusJob
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 11:58:50 +00:00
Kevin Ottens
0e4ff6929e Add a way to know which folder was listed for encrypted status
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-21 11:58:50 +00:00
Nextcloud bot
463ebd1df8 [tx-robot] updated from transifex 2020-10-21 03:38:47 +00:00
Kevin Ottens
78f6d9f044 Merge pull request #2570 from nextcloud/backport/2568/stable-3.0
[stable-3.0] Fix crash when clicking on folder with status 403 in the main dialog.
2020-10-20 17:20:53 +02:00
Camila San
cc6ec22e5f Fix crash when clicking on folder with status 403 in the main dialog.
LsColJob was still being used after delete was called.

Signed-off-by: Camila San <hello@camila.codes>
2020-10-20 14:39:05 +00:00
Nextcloud bot
c831bfbc63 [tx-robot] updated from transifex 2020-10-20 03:37:49 +00:00
Kevin Ottens
d8017eccce Merge pull request #2567 from nextcloud/backport/2551/stable-3.0
[stable-3.0] Fix share dialog animation for enforced password policy
2020-10-19 17:28:08 +02:00
Kevin Ottens
4b9d9e3020 Stop the animation if we got an error message
Otherwise it would spin forever while we know we're not doing any work
anymore since we got a message from the server.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-19 15:10:44 +00:00
Kevin Ottens
cecb95548f Inform _emptyShareLinkWidget of linkShareRequiresPassword signals
All the other ShareLinkWidgets process that signal (which allows to
display error messages for instance) but not that one for some reason.
That being said it might need to deal with an enforced password
situation.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-19 15:10:44 +00:00
Kevin Ottens
bee8dbc471 Emit last to avoid use after delete crash
It turns out the shareDeleted() signal is connected to a function
cleaning up the ShareLinkWidget holding the last shared pointer to the
Share object. Since we use member variables for calling updateFolder()
this would lead to using deleted objects.

Just swap the call and the signal to have everything back in order.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-19 15:10:44 +00:00
Nextcloud bot
9722ac6ab8 [tx-robot] updated from transifex 2020-10-17 03:37:36 +00:00
Nextcloud bot
ad7daf6998 [tx-robot] updated from transifex 2020-10-16 03:38:12 +00:00
Nextcloud bot
76621647f7 [tx-robot] updated from transifex 2020-10-15 03:36:56 +00:00
Michael Schuster
6979b12488 [stable-3.0] Update comments
Everyone uses their private mail, so ensure people can get in touch.

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-15 02:23:49 +02:00
Nextcloud bot
9ed2e15788 [tx-robot] updated from transifex 2020-10-14 03:41:00 +00:00
Nextcloud bot
72d8d44e29 [tx-robot] updated from transifex 2020-10-13 03:39:09 +00:00
Kevin Ottens
1a068ae170 Merge pull request #2533 from nextcloud/backport/2530/stable-3.0
[stable-3.0] Repair the Windows build
2020-10-12 13:08:49 +02:00
Kevin Ottens
ec9b495071 Export the WordList functions
Now that they are used from gui/ they need to be properly exported so
that linking doesn't fail when visibility is activated (only on our
Windows build it seems).

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-12 09:56:06 +00:00
Nextcloud bot
d202868ba0 [tx-robot] updated from transifex 2020-10-12 03:36:34 +00:00
Nextcloud bot
d721cebbcb [tx-robot] updated from transifex 2020-10-11 03:34:46 +00:00
Nextcloud bot
1b288f2714 [tx-robot] updated from transifex 2020-10-10 03:41:09 +00:00
Nextcloud bot
6f897a6a58 [tx-robot] updated from transifex 2020-10-09 03:36:05 +00:00
Nextcloud bot
1598d90534 [tx-robot] updated from transifex 2020-10-08 03:36:22 +00:00
Michael Schuster
c0be82a1d1 Merge pull request #2524 from nextcloud/backport/2520/stable-3.0
[stable-3.0] Handle ask for optional password capability
2020-10-07 17:09:25 +02:00
Kevin Ottens
25bfee8854 If askForOptionalPassword is enabled preset a random password
This is the same approach used on the server side. Turns out I quite
like it, this avoids popping up a dialog to the user and since she won't
know the password she'll have to set a new one anyway or disable it.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-07 13:32:39 +00:00
Kevin Ottens
dfd3da9e8b Since we must ask for a password this can't be a default public link
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-07 13:32:39 +00:00
Kevin Ottens
4fbc8e5c42 Add sharePublicLinkAskOptionalPassword to Capabilities
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-07 13:32:39 +00:00
Nextcloud bot
d4529caf89 [tx-robot] updated from transifex 2020-10-07 03:35:25 +00:00
Nextcloud bot
e665f14012 [tx-robot] updated from transifex 2020-10-06 03:35:52 +00:00
Michael Schuster
d046bdf0ec Merge pull request #2513 from nextcloud/backport/2512/stable-3.0
[stable-3.0] Handle redirects when downloading updates
2020-10-05 17:30:42 +02:00
Kevin Ottens
ee832cdd83 Handle redirects when downloading updates
This is necessary for downloads coming from Github for instance. They
are systematically redirected and we'd just fail the download.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-05 14:57:08 +00:00
Kevin Ottens
72f2eb5c01 Merge pull request #2511 from nextcloud/backport/2500/stable-3.0
[stable-3.0] Windows MSI: Update Docs & add SKIPAUTOUPDATE property
2020-10-05 10:08:07 +02:00
Michael Schuster
6b826765e7 Docs: Be slightly more modern and use 64-bit examples
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-05 07:44:01 +00:00
Michael Schuster
61805c5063 Windows MSI: Add SKIPAUTOUPDATE property for the skipUpdateCheck setting
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-05 07:44:01 +00:00
Michael Schuster
f101d88ee5 Docs: Use our app name in the MSI docs
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-05 07:44:01 +00:00
Michael Schuster
4aa10465ff Windows MSI: Stay compatible with the upstream "StartMenuShortcuts" feature
Even though we only create a program shortcut in the Start Menu, try to make administrators lives easier by not diverging feature and option naming.

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-05 07:44:01 +00:00
Michael Schuster
3dc171e7b6 Docs: Adopt latest MSI doc enhancements from upstream master
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-05 07:44:01 +00:00
Dominik Schmidt
050b95a1cb Docs: Adopt upstream commit fe04300 for MSI installation
See: fe043006c8

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-05 07:44:01 +00:00
Michael Schuster
80df527387 Docs: Update macOS version info
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-05 07:44:01 +00:00
Nextcloud bot
2a16eb66cb [tx-robot] updated from transifex 2020-10-05 03:37:42 +00:00
Nextcloud bot
9d6669b0fd [tx-robot] updated from transifex 2020-10-04 03:38:02 +00:00
Nextcloud bot
b8fc7adc4c [tx-robot] updated from transifex 2020-10-03 03:39:49 +00:00
Michael Schuster
df751a528e Merge pull request #2502 from nextcloud/backport/2497/stable-3.0
[stable-3.0] macOS: Fix memory leak in FolderWatcherPrivate::startWatching
2020-10-02 20:09:49 +02:00
Michael Schuster
b26b7cd56c Fix source file access modes
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-02 17:31:22 +00:00
Michael Schuster
1e73d7dbc2 macOS: Fix memory leak in FolderWatcherPrivate::startWatching
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-10-02 17:31:22 +00:00
Nextcloud bot
47b07a4070 [tx-robot] updated from transifex 2020-10-02 03:31:38 +00:00
Michael Schuster
a8ebff14d8 Merge pull request #2498 from nextcloud/backport/2478/stable-3.0
[stable-3.0] Update propagateupload.cpp
2020-10-02 00:22:05 +02:00
Aldaris1985
073293ef2f Update propagateupload.cpp
Typo corrected.
2020-10-01 22:08:37 +00:00
Michael Schuster
3d1af65853 Merge pull request #2491 from nextcloud/backport/2486/stable-3.0
[stable-3.0] Connect signal guiLog to slot to display systray message.
2020-10-01 19:03:15 +02:00
Camila
681cb5a989 Correct the object name returned by the api.
The id was always 0 so no new systray messages were displayed.

Signed-off-by: Camila <hello@camila.codes>
2020-10-01 16:09:57 +00:00
Camila
9b1ad046cb Connect signal guiLog to slot to display systray message.
Signed-off-by: Camila <hello@camila.codes>
2020-10-01 16:09:57 +00:00
Nextcloud bot
68c03e0b57 [tx-robot] updated from transifex 2020-10-01 03:39:12 +00:00
Nextcloud bot
d2e2889a6d [tx-robot] updated from transifex 2020-09-30 03:38:42 +00:00
Nextcloud bot
e4505627ab [tx-robot] updated from transifex 2020-09-29 03:40:11 +00:00
Kevin Ottens
a30152b0bc Merge pull request #2479 from nextcloud/backport/2477/stable-3.0
[stable-3.0] Free IconJob after use
2020-09-28 14:18:49 +02:00
Dan Griffin
a73ade2991 Free IconJob after use
Signed-off-by: Dan Griffin <github.mk@xiragon.com>
2020-09-28 11:20:48 +00:00
Nextcloud bot
d8e5135c24 [tx-robot] updated from transifex 2020-09-28 03:36:56 +00:00
Nextcloud bot
1e30aa661b [tx-robot] updated from transifex 2020-09-27 03:36:15 +00:00
Nextcloud bot
c27a82deef [tx-robot] updated from transifex 2020-09-26 03:37:11 +00:00
Nextcloud bot
d24eaae8f7 [tx-robot] updated from transifex 2020-09-25 03:40:51 +00:00
Kevin Ottens
068ad89d8d Merge pull request #2471 from nextcloud/backport/2470/stable-3.0
[stable-3.0] Force tooltip wrap mode because it's not enabled in Qt 5.12...
2020-09-24 14:51:48 +02:00
Kevin Ottens
df6abcb68d Force tooltip wrap mode because it's not enabled in Qt 5.12...
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-24 12:50:29 +00:00
Nextcloud bot
17b991bda3 [tx-robot] updated from transifex 2020-09-24 03:37:43 +00:00
Michael Schuster
a909ffce28 Merge pull request #2465 from nextcloud/backport/2441/stable-3.0
[stable-3.0] Allow server URL to be pre-defined without enforcing it
2020-09-23 16:37:34 +02:00
Michael Schuster
25c8077378 Allow server URL to be pre-defined without enforcing it to be used unmodified
APPLICATION_SERVER_URL can be either empty or be specified. This commit adds the new CMake option APPLICATION_SERVER_URL_ENFORCE to decide whether to enforce the
URL's unmodified use (like before, default: ON) or to allow modification by the user (new).

By default APPLICATION_SERVER_URL_ENFORCE is set to ON, to no break with the previous implementation's expectations.

If APPLICATION_SERVER_URL is empty, APPLICATION_SERVER_URL_ENFORCE will be ignored by the Account Wizard.

The previous behaviour confused me a bit with branded builds. When the URL was (usually) specified but not forced, it was simply discarded, forcing the user to
manually supply it.

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-23 14:29:08 +00:00
Kevin Ottens
75f5cfff0b Merge pull request #2463 from nextcloud/backport/2409/stable-3.0
[stable-3.0] Use native text rendering for qml windows
2020-09-23 14:39:29 +02:00
Jeremy Plsek
991f84844e Use native text rendering for qml windows
Signed-off-by: Jeremy Plsek <jeremyplsek@gmail.com>
2020-09-23 14:12:14 +02:00
Nextcloud bot
90f2b01659 [tx-robot] updated from transifex 2020-09-23 03:36:40 +00:00
Nextcloud bot
7a9ed6cc0d [tx-robot] updated from transifex 2020-09-22 03:36:37 +00:00
Michael Schuster
3e7d09b520 Merge pull request #2458 from nextcloud/backport/2369/stable-3.0
[stable-3.0] Windows: MSI support & Win32 migration tools
2020-09-21 17:45:18 +02:00
Michael Schuster
24da469d72 Windows: Win32 migration tools code review
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-21 15:36:33 +00:00
Michael Schuster
71e86ad27c Windows MSI: Add MSI scripts and UI resources
Uses CMake to generate and install all required files in the "msi/" directory.

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-21 15:36:33 +00:00
Michael Schuster
a5500297f7 Windows: Add Win32 stand-alone migration tool NCNavRemove
Removes all Explorer Navigation Pane entries for a given ApplicationName, specified in NavRemove.ini in the working directory.

Also compiles a DLL with the same behaviour that exports:
- RemoveNavigationPaneEntries

Both tool variants are Mutex-protected.

Statically linked, optimized for binary size, no Qt dependencies.

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-21 15:36:32 +00:00
Michael Schuster
ea2d1be222 Windows MSI: Add helper DLL and shared migration tools code
The helper DLL will be utilized by Windows Installer with Custom Actions defined in the NCMsiHelper.wxs WiX fragment.

Exports:
- ExecNsisUninstaller
- RemoveNavigationPaneEntries

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-21 15:36:32 +00:00
Michael Schuster
1537577ade Windows MSI: Let CMake install Shell Extensions WiX fragment to "msi/"
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-21 15:36:32 +00:00
Michael Schuster
924ed77563 Windows MSI: Add Upgrade Code and migration tool build options to NEXTCLOUD.cmake
The Upgrade Code is a GUID (specified without brackets) for the MSI package to allow Windows Installer identify existing installations.

New build options (default: OFF):
- BUILD_WIN_MSI: Build all MSI scripts and a required helper DLL (to uninstall NSIS legacy installations and remove Explorer Navigation Pane entries)
- BUILD_WIN_TOOLS: Build additional migration tools (currently NCNavRemove, a stand-alone tool for Explorer entries removal)

The helper DLL and migration tools are set to be statically linked and optimized for binary size.

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-21 15:36:32 +00:00
Kevin Ottens
c44c8c8876 Merge pull request #2456 from nextcloud/backport/2439/stable-3.0
[stable-3.0] Fix missing subdirectory discovery on move operations in macOS
2020-09-21 16:05:59 +02:00
Dominique Fuchs
c3b0e98e3e Fix missing subdirectory discovery on move operations in macOS.
Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>

Add qAsConst to avoid detaching

Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>

Changed callchain to find and return possibly coalesced paths

Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>

Removed another qAsConst remnant, more func const-correctness.

Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>
2020-09-21 13:52:55 +00:00
Kevin Ottens
5ac3b98dfb Merge pull request #2455 from nextcloud/backport/2431/stable-3.0
[stable-3.0] Remove "This includes" due to tooltip order
2020-09-21 15:50:38 +02:00
Jeremy Plsek
c8ca587130 Remove "This includes" due to tooltip order
Signed-off-by: Jeremy Plsek <jeremyplsek@gmail.com>
2020-09-21 13:41:24 +00:00
Nextcloud bot
f9ae321353 [tx-robot] updated from transifex 2020-09-21 03:31:12 +00:00
Nextcloud bot
b7f7366d3a [tx-robot] updated from transifex 2020-09-20 03:30:53 +00:00
Nextcloud bot
67d815a4c5 [tx-robot] updated from transifex 2020-09-19 03:33:17 +00:00
Michael Schuster
2170d72aec Merge pull request #2448 from nextcloud/backport/2437/stable-3.0
[stable-3.0] If there's no description just say nothing
2020-09-18 22:03:27 +02:00
Kevin Ottens
bd3e246ce7 If there's no description just say nothing
Otherwise we get lots of "No description available" lines in the
activity list which is basically noise. Also trains the user to ignore
the secondary line.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-18 18:42:30 +00:00
Camila San
2da9edecbe Entitlement to sign the QtWebEngineProcess with an exception.
Fix for #1793: The problem seems to be related enabling hardened runtime.
This exception allows the webview to load.

Signed-off-by: Camila San <hello@camila.codes>
2020-09-18 15:02:54 +02:00
Nextcloud bot
c287b668d3 [tx-robot] updated from transifex 2020-09-18 03:29:55 +00:00
Nextcloud bot
568b738fa9 [tx-robot] updated from transifex 2020-09-17 04:11:58 +00:00
Michael Schuster
5125724e87 [stable-3.0] Add missing Polish.nsh from PR #2434 Windows: Fix NSIS language encoding (use UTF-8)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-16 16:12:18 +02:00
Kevin Ottens
b0f67d2e0d Merge pull request #2436 from nextcloud/backport/2435/stable-3.0
[stable-3.0] Fix incomplete journal upgrade from 2.x to 3.x
2020-09-16 14:23:10 +02:00
Dominique Fuchs
0fe6f075f1 Do not break out of outer loop when upgrading folders, continue instead
Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>

Remove awkward debug line a.k.a. whoops

Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>
2020-09-16 11:22:25 +00:00
Kevin Ottens
c3b6d3f04a Merge pull request #2434 from nextcloud/backport/2432/stable-3.0
[stable-3.0] Windows: Fix NSIS language encoding (use UTF-8)
2020-09-16 09:31:23 +02:00
Michael Schuster
ae57c1c752 Windows: Remove unused and outdated NSIS Transifex settings
The last translation update from Transifex was done in 2017, so the scripts and settings were never used for Nextcloud.

This commit removes the unused scripts and "Auto-generated" comments in the translation files.

Some files have been modified over time either way and MSI will replace NSIS soon.

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-16 07:14:10 +00:00
Michael Schuster
e6975840a7 Windows: Fix NSIS language encoding (use UTF-8 instead of Win code pages)
The old conversion to specific code pages caused display errors (see issue #2393 for Russian).

Based on bin/l10n.sh, the files in this commit were converted to UTF-8 using iconv with the following parameters:

  iconv -f CP1252 -t UTF-8 -o German.nsh German.nsh
  iconv -f CP1252 -t UTF-8 -o Galician.nsh Galician.nsh
  iconv -f CP1253 -t UTF-8 -o Greek.nsh Greek.nsh
  iconv -f CP1250 -t UTF-8 -o Slovenian.nsh Slovenian.nsh
  iconv -f CP1257 -t UTF-8 -o Estonian.nsh Estonian.nsh
  iconv -f CP1252 -t UTF-8 -o Italian.nsh Italian.nsh
  iconv -f CP1252 -t UTF-8 -o PortugueseBR.nsh PortugueseBR.nsh
  iconv -f CP1252 -t UTF-8 -o Spanish.nsh Spanish.nsh
  iconv -f CP1252 -t UTF-8 -o Dutch.nsh Dutch.nsh
  iconv -f CP1252 -t UTF-8 -o Finnish.nsh Finnish.nsh
  iconv -f CP932 -t UTF-8 -o Japanese.nsh Japanese.nsh
  iconv -f CP1250 -t UTF-8 -o Slovak.nsh Slovak.nsh
  iconv -f CP1254 -t UTF-8 -o Turkish.nsh Turkish.nsh
  iconv -f CP1252 -t UTF-8 -o Norwegian.nsh Norwegian.nsh
  iconv -f CP852  -t UTF-8 -o Czech.nsh Czech.nsh

The installer script nextcloud.nsi in the client-building repo needs the following line (to be added on top):
  Unicode true

Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-09-16 07:14:10 +00:00
Nextcloud bot
f15c627c82 [tx-robot] updated from transifex 2020-09-16 03:27:00 +00:00
Kevin Ottens
d0b19559d3 Merge pull request #2430 from nextcloud/backport/2351/stable-3.0
[stable-3.0] Fix clang tidy errors in csync tests
2020-09-15 16:18:30 +02:00
Kevin Ottens
c9fe7fa735 Switch to newer CI image to build csync tests
This new image brings the cmocka dependency and thus will make the CI
build the csync tests which depend on it.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 14:03:44 +00:00
Kevin Ottens
d6b057e7e8 Fix bugprone-narrowing-conversion errors in csync tests
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 14:03:44 +00:00
Kevin Ottens
e8c92ec50f Fix modernize-use-nullptr errors in csync tests
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 14:03:44 +00:00
Kevin Ottens
ce55a4678c Fix modernize-use-auto errors in csync tests
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 14:03:44 +00:00
Kevin Ottens
e4004035fe Fix modernize-deprecated-headers errors in csync tests
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 14:03:44 +00:00
Kevin Ottens
6125aca847 Merge pull request #2429 from nextcloud/backport/2247/stable-3.0
[stable-3.0] Improve drone config
2020-09-15 16:02:39 +02:00
Kevin Ottens
ddd1552047 Make sure wget looks for the certificates at the right place
Might happen because we got too many copies of OpenSSL around

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:01 +00:00
Kevin Ottens
de38a1e309 Switch to Ninja for the clang build
Clang is generally slower to compile than GCC so use a faster Make for
that build variant. This also allows us to verify our CMake files don't
do anything Make specific.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:01 +00:00
Kevin Ottens
3afa836744 Parallelize the clang-tidy runs
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:01 +00:00
Kevin Ottens
66a19e533a Split cmake and compile into separate pipeline steps
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:01 +00:00
Kevin Ottens
00fa184507 Switch to actual commands inside of the steps
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:00 +00:00
Kevin Ottens
169bf7f032 Split the CI pipelines into proper steps
Will make it easier to navigate the logs

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:00 +00:00
Kevin Ottens
771263aa25 Now make sure we're not picking up generated headers
This could happen (and started to happen more with clang-tidy 10) that
clang-tidy picked up errors in headers from the build directory. Now
that we moved the build directory out of source, we can simply filter
headers based on the pwd.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:00 +00:00
Kevin Ottens
a6cab38ebd Move the build in a volume to be reused between steps
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:00 +00:00
Kevin Ottens
9b08f287d3 Remove unneeded environment variables
Those are set by the base CI image anyway, no need to do the work again.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:00 +00:00
Kevin Ottens
82e42c6f78 Switch to the newer base CI image
We can now spare building QtKeychain over and over shortening a bit the
build. We also update to latest gcc and clang.

Note that I didn't switch the AppImage pipeline to the newer image to
keep the binary compatibility promise required by linuxdeployqt.
Probably would make sense to do a specific image for AppImage with some
other of the cleanups I did there (in particular to avoid building
qtkeychain every time).

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:00 +00:00
Kevin Ottens
1003b0745f Parallelize the CI build
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:53:00 +00:00
Kevin Ottens
4af3e3f7ec Merge pull request #2428 from nextcloud/backport/2424/stable-3.0
[stable-3.0] Try to enable the CI on stable branches as well
2020-09-15 15:52:17 +02:00
Kevin Ottens
0a11df6824 Try to enable the CI on stable branches as well
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 13:25:42 +00:00
Kevin Ottens
b3776b622c Merge pull request #2426 from nextcloud/backport/2412/stable-3.0
[stable-3.0] Include list info in tooltip
2020-09-15 13:51:49 +02:00
Jeremy Plsek
30f84c3e35 Include list info in tooltip
Also extend the tooltip timeout

Signed-off-by: Jeremy Plsek <jeremyplsek@gmail.com>
2020-09-15 11:51:19 +00:00
Kevin Ottens
161be14dc6 Merge pull request #2422 from nextcloud/backport/2417/stable-3.0
[stable-3.0] Fix menu popup in main dialog
2020-09-15 12:02:42 +02:00
Kevin Ottens
d4809ebe4c Make sure menu are closed when button is clicked again
This way we also made sure all the Menu are currently on the same close
policy.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 09:03:55 +00:00
Kevin Ottens
ee1096f802 Delay binding on the menu width
Indee the MenuItem might not be linked to its Menu at creation time
which will make the binding fail and give a warning. Delay for the menu
availability.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 09:03:55 +00:00
Kevin Ottens
89113db3ce Remove pre-QQC2.3 workaround
Now that we depend on Qt 5.12 anyway, the count property is available
just fine on the Menu item.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 09:03:55 +00:00
Kevin Ottens
020d8761bf Merge pull request #2421 from nextcloud/backport/2418/stable-3.0
[stable-3.0] Use QGuiApplication::primaryScreen() as fallback for Systray::currentScreen()
2020-09-15 10:47:00 +02:00
Kevin Ottens
1dd53d3797 Use QGuiApplication::primaryScreen() as fallback for Systray::currentScreen()
Under Wayland QCursor::pos() is unlikely to give us anything meaningful,
so fallback to the primary screen information.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-15 08:46:04 +00:00
Nextcloud bot
3c7cc7c0a9 [tx-robot] updated from transifex 2020-09-15 03:21:23 +00:00
Kevin Ottens
e98911503c Merge pull request #2415 from nextcloud/backport/2357/stable-3.0
[stable-3.0] syncjournaldb: index e2eMangledName column in metadata
2020-09-14 09:33:25 +02:00
Jan Schmidt
e41a000db8 syncjournaldb: index e2eMangledName column in metadata
Add an index on the e2eMangledName column in the metadata table
to speed up file sync by orders of magnitude on directories with
a large number of files.

Signed-off-by: Jan Schmidt <jan@centricular.com>
2020-09-14 07:25:00 +00:00
Nextcloud bot
1918e7f6be [tx-robot] updated from transifex 2020-09-12 03:18:46 +00:00
Nextcloud bot
87e38df6a2 [tx-robot] updated from transifex 2020-09-11 03:19:38 +00:00
Kevin Ottens
131a486c13 Don't use a confusing "royal you" in the sync messages
Users get rightfully confused with the "You changed ..." messages in the
activity list for syncs. Indeed, some of those changes might be coming
from the server in which case we don't really know who did the change.

So now we use the old "Synced ..." messages for changes pulled from the
server and we have a more precise "You changed ..." (renamed, deleted,
created) when the changes were initiated locally (since there we know
the user reading the message did it).

Also changed how the messages are constructed so that they can be
properly translated.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-09-10 17:16:43 +02:00
Camila
ab563dcef4 Add README with instructions on how to build the documentation.
Signed-off-by: Camila <hello@camila.codes>
2020-09-10 12:20:06 +02:00
Camila
55da58d662 Update troubleshooting instructions with the newly added config file options.
Signed-off-by: Camila <hello@camila.codes>
2020-09-10 12:20:06 +02:00
Camila
5aeae28805 Click on activity list in systray open file in the file manager.
Clean up code, add more const and auto.

Signed-off-by: Camila <hello@camila.codes>
2020-09-10 11:43:32 +02:00
Camila
722fc8eb67 Fix tooltip for activity info.
Also improves readability of the items in the list.

Signed-off-by: Camila <hello@camila.codes>
2020-09-10 11:43:32 +02:00
Nextcloud bot
723ffc81fb [tx-robot] updated from transifex 2020-09-10 03:24:56 +00:00
Kevin Ottens
e8c6b1a1be Merge pull request #2388 from nextcloud/backport/2309/stable-3.0
[stable-3.0] Update copyright date and version displayed in the page title.
2020-09-08 15:52:12 +02:00
Camila
95fc81cf70 Update copyright date and version displayed in the page title.
- This is the title displayed at https://docs.nextcloud.com/desktop/x.y

Signed-off-by: Camila <hello@camila.codes>
2020-09-08 13:34:30 +00:00
Nextcloud bot
015f16088d [tx-robot] updated from transifex 2020-09-08 03:18:56 +00:00
Nextcloud bot
6f67ca5906 [tx-robot] updated from transifex 2020-09-06 03:28:02 +00:00
Nextcloud bot
3b58847c51 [tx-robot] updated from transifex 2020-09-05 03:28:18 +00:00
Nextcloud bot
2e96131926 [tx-robot] updated from transifex 2020-09-04 03:28:51 +00:00
Nextcloud bot
b9801772a1 [tx-robot] updated from transifex 2020-09-03 03:28:15 +00:00
Nextcloud bot
a3b506562c [tx-robot] updated from transifex 2020-09-02 03:30:48 +00:00
Nextcloud bot
6a4f22e046 [tx-robot] updated from transifex 2020-09-01 03:25:33 +00:00
Kevin Ottens
259aaf74cc Merge pull request #2346 from nextcloud/backport/2345/stable-3.0
[stable-3.0] Use httpd/unix-directory mimetype for E2EE folders
2020-08-31 13:14:57 +02:00
Kevin Ottens
75ac240030 Use httpd/unix-directory mimetype for E2EE folders
We don't do much with that mimetype on our end, but other clients
somehow don't expect inode/directory to let's lie. ;-)

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-31 11:12:34 +00:00
Nextcloud bot
b8556f9c0f [tx-robot] updated from transifex 2020-08-31 03:24:52 +00:00
Nextcloud bot
1c3abae484 [tx-robot] updated from transifex 2020-08-29 03:25:46 +00:00
Camila
d3833cc6ac stable-3.0 branch is now version 3.0.2.
Signed-off-by: Camila <hello@camila.codes>
2020-08-28 11:49:53 +02:00
Camila
0a62628f8a Bump version to 3.0.1.
Signed-off-by: Camila <hello@camila.codes>
2020-08-28 11:45:24 +02:00
Nextcloud bot
772a34ba46 [tx-robot] updated from transifex 2020-08-28 03:25:46 +00:00
Nextcloud bot
42ea6b5427 [tx-robot] updated from transifex 2020-08-27 03:28:47 +00:00
Michael Schuster
3ea57abfec Remove remaining QLinkedList includes in addition to #2300
Now the only remaining reference is in:

src/3rdparty/libcrashreporter-qt/3rdparty/drkonqi-parser/backtraceparser.cpp:269:        || line.functionName().startsWith(QLatin1String("QLinkedList")

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 5945f18d5a)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-27 03:41:14 +02:00
Michael Schuster
6f2156cacd Merge pull request #2323 from nextcloud/backport/2300/stable-3.0
[stable-3.0] Support client builds on VS2019 (QLinkedList is deprecated)
2020-08-27 02:22:45 +02:00
Michael Schuster
9e5225d83d Adapt code style in addition to #2300
- Use "!empty()" instead of "size() > 0" in std::list
- Add comments for namespace brackets

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit bd519ffe7a)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-27 02:13:06 +02:00
V.C
957dd16770 Code review changes implemented
Code review changes implemented for bandwidthmanager.cpp
1. Use auto instead of size_t
2. Check for empty instead of size comparisions

Signed-off-by: V.C <c******@rediffmail.com>
(cherry picked from commit b20ea25201)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-27 02:12:53 +02:00
V.C
95401e5985 Support client builds on VS2019
Scenario: Build fails on Qt 5.15.0 + VS2019 16.7.2
Root cause: QLinkedList seems to be depreciated. Advise to use std::list instead.
Fix: Used std::list insead of QLinkedList.

Signed-off-by: V.C <c******@rediffmail.com>
(cherry picked from commit af1bb7e98c)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-27 02:12:51 +02:00
Nextcloud bot
a15b66d525 [tx-robot] updated from transifex 2020-08-26 03:28:55 +00:00
Nextcloud bot
e0b53b3bda [tx-robot] updated from transifex 2020-08-25 03:31:22 +00:00
Nextcloud bot
2015aab626 [tx-robot] updated from transifex 2020-08-24 03:29:52 +00:00
Nextcloud bot
90402f8dcb [tx-robot] updated from transifex 2020-08-22 03:27:54 +00:00
Michael Schuster
0de6823cca Merge pull request #2304 from nextcloud/backport/2302/stable-3.0
[stable-3.0] Do not build for Eoan
2020-08-22 00:57:03 +02:00
István Váradi
c560db000a Do not build for Eoan
Signed-off-by: István Váradi <ivaradi@varadiistvan.hu>
2020-08-21 22:56:18 +00:00
Nextcloud bot
fba819e65b [tx-robot] updated from transifex 2020-08-21 03:29:21 +00:00
Michael Schuster
d02f1b80f3 Merge pull request #2297 from nextcloud/backport/2288/stable-3.0
[stable-3.0] Windows shell extensions: Use custom GUIDs and prepare for MSI
2020-08-20 21:39:48 +02:00
Michael Schuster
fc79e035c6 Fix spacing
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 4df8db4ff6)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:32:06 +02:00
Michael Schuster
ee332dcaec Windows shell extensions: Add WiX (MSI) fragment
Use CMake to generate a WXI fragment to handle the DLL registration and file deployment for the shellext components.

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit db05f65e0d)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:31:56 +02:00
Michael Schuster
b5fc4f86a7 Windows shell extensions: Change NCUtil Pipe name from ownCloud to APPLICATION_EXECUTABLE
Avoid interference with foreign pipes as this is always a bad idea ;p

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 11632da7ea)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:31:23 +02:00
Michael Schuster
3ac99c75b0 Windows shell extensions: Rename all files and classes from OC* to NC*, update version info
This also ensures a clear separation in the system registry.

SelfReg is not recommended by Microsoft and will be handled by the MSI package to allow proper Repair and Uninstall.
However, we keep it for backward compatibility with the NSIS installer.

For details see:
https://stackoverflow.com/questions/364187/how-do-you-register-a-win32-com-dll-file-in-wix-3#364210
https://docs.microsoft.com/en-us/windows/win32/msi/selfreg-table#remarks

Another fix by this commit:
The "Version" registry value in the NCOverlays self reg should be a key and not a value.

Details: https://wixtoolset.org/documentation/manual/v3/xsd/wix/class.html

Example:

  [HKCR\CLSID\{01234567-89AB-CDEF-0123-456789ABCDEF}\Version]
  @="1.0.0.0"

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 0ba5df597f)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:28:18 +02:00
Michael Schuster
a02e4a2913 Windows shell extensions: Use custom GUIDs via CMake and prepare MSI reg
Previously side by side installation with ownCloud or other NC custom builds would break the shell integration because the same GUIDs and registry keys were used.

Now we specify our custom GUIDs in NEXTCLOUD.cmake and use CMake to generate a header file and WiX (MSI) include file with these constants.

Note: Using generators like "guidgen" or "uuidgen" ensures that GUIDs are unique, as manual changes are not guaranteed to be.

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 8ce13b7bdb)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:28:10 +02:00
Hannah von Reth
a7b93e36ff Remove dead code
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 4675869fb3)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:28:02 +02:00
Hannah von Reth
a742a42f4c 2.7 has less automatic includes on Windows
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit bfd7707ff4)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:27:53 +02:00
Hannah von Reth
2537f0cd4c Cleanup Windows shell extensions
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 34e9e2f288)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:27:44 +02:00
Hannah von Reth
4e44f46b9e Remove outdated visual studio projects, we now use cmake
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 6c9a31f6ee)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:27:35 +02:00
Dominik Schmidt
b86bc92875 Avoid warning because /MT overrides /MD flag
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 13d4b91935)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:27:27 +02:00
Dominik Schmidt
c3b1e4bd9a Make OCUtil helper lib static and link it statically against crt
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit e4b53b12e1)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:27:11 +02:00
Olivier Goffart
3fd3f85558 Windows Shell Integration: Don't limit the size of the buffer
Otherwise we can't have operation that has many many filename

As reported in #6780

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 906556640d)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:27:01 +02:00
Christian Kamm
811b0eb6db Windows shellext: Update copyrights and company name
Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 77cc262337)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:26:52 +02:00
Olivier Goffart
7acc7dae35 windows shell extension: add OCUtil/resource.h
It's a copy from OCContextMenu/resources.h

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit 6274462036)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:26:42 +02:00
Christian Kamm
4c9e19b82c Windows shellext: Add rc for OCUtil #6554
To set the dll's metadata.

Signed-off-by: Michael Schuster <michael@schuster.ms>
(cherry picked from commit c6fc46aa09)
Signed-off-by: Michael Schuster <michael@schuster.ms>
2020-08-20 21:26:12 +02:00
Kevin Ottens
3770e75561 Merge pull request #2294 from nextcloud/backport/2292/stable-3.0
[stable-3.0] Disable context menu actions for E2EE files and folders
2020-08-20 18:39:02 +02:00
Kevin Ottens
14d4160729 Present sharing of E2EE files from the main dialog too
The visibility of the share button for the activity list is tied to the
path role in the ActivityListModel, so make sure we don't return a path
for E2EE files and folders.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-20 16:37:26 +00:00
Kevin Ottens
6dcf261abe Disable context menu actions for E2EE files and folders
Those files and folders are not shareable and the "Edit" or "Open in
browser" actions will lead to showing an error in the web GUI. No need
to lead users there so just disable them.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-20 16:37:26 +00:00
Nextcloud bot
3d3d6bf2d9 [tx-robot] updated from transifex 2020-08-20 03:31:35 +00:00
Nextcloud bot
a957a9924e [tx-robot] updated from transifex 2020-08-19 03:31:55 +00:00
Kevin Ottens
7de04654c5 Show the "Display mnemonic" button only when we know e2e is supported
Turns out that showing the button straight from the page ctor is a bit
too early. At that point the account might not be connected yet and thus
we wouldn't have proper information. Currently we were displaying that
button all the time, now we wait for the account to be connected to
decide to show it or not.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-18 18:01:07 +02:00
Kevin Ottens
a60fa8ba85 [stable-3.0] Make sure we don't assert when calling fileStatus
It happens that sometimes we leak a directory path ending with a slash,
but that violates fileStatus' precondition so let's catch it early and
skip such path.

Of course the right fix would be a larger swipe in the sync engine and
around it to not use naked strings anymore but rely on the typesystem.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-18 16:12:44 +02:00
Nextcloud bot
6ad1357ac0 [tx-robot] updated from transifex 2020-08-18 03:33:47 +00:00
Nextcloud bot
48b8848dcc [tx-robot] updated from transifex 2020-08-17 03:27:18 +00:00
Nextcloud bot
42f7d3e538 [tx-robot] updated from transifex 2020-08-16 03:27:23 +00:00
Nextcloud bot
ce126e6d7f [tx-robot] updated from transifex 2020-08-14 03:43:45 +00:00
Nextcloud bot
824e853b2a [tx-robot] updated from transifex 2020-08-13 03:29:42 +00:00
Nextcloud bot
97020728c1 [tx-robot] updated from transifex 2020-08-12 03:29:22 +00:00
Kevin Ottens
ff175088a3 Merge pull request #2259 from nextcloud/backport/2258/stable-3.0
[stable-3.0] Keep the E2EE info message around to allow displaying mnemonic
2020-08-11 15:13:02 +02:00
Kevin Ottens
0066de26bb Keep the E2EE info message around to allow displaying mnemonic
We lost the ability to display the E2EE mnemonic during the GUI
redesign and the info message wasn't displayed again on restart. So now
we display it every time, it still can be dismissed and the button text
is different in such a case to make the intent clearer.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-11 13:12:34 +00:00
Nextcloud bot
68f137fff5 [tx-robot] updated from transifex 2020-08-11 03:29:04 +00:00
Kevin Ottens
aa5ff75fa2 Merge pull request #2257 from nextcloud/backport/2255/stable-3.0
[stable-3.0] Restore E2EE old key storage format compatibility
2020-08-10 16:11:55 +02:00
Kevin Ottens
37a0474f09 Add support for BASE64 encoded '|' when decrypting
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-10 14:08:00 +00:00
Kevin Ottens
802c5f0a0a Move the private key salt handling in its own function
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-10 14:08:00 +00:00
Kevin Ottens
d45c8aee8e Ignore the salt part of the key during decryption
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-10 14:08:00 +00:00
Kevin Ottens
2424803bdd Restore the symmetry between *StringSymmetric functions
If we receive data without base64 encoding for encryption, it makes
sense to get it without base64 encoding out of decryption.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-10 14:07:59 +00:00
Kevin Ottens
63233bf09e Add unit tests for the encryption helpers
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-08-10 14:07:59 +00:00
Nextcloud bot
493cba2e55 [tx-robot] updated from transifex 2020-08-09 03:28:46 +00:00
Nextcloud bot
de3b56d999 [tx-robot] updated from transifex 2020-08-08 03:30:53 +00:00
Nextcloud bot
e3c10bde59 [tx-robot] updated from transifex 2020-08-07 03:31:19 +00:00
255 changed files with 4237 additions and 12830 deletions

View File

@@ -1,45 +1,22 @@
Checks: '-*,
bugprone-*,
-bugprone-forward-declaration-namespace,
cppcoreguidelines-init-variables,
misc-*,
-misc-non-private-member-variables-in-classes,
modernize-avoid-bind,
modernize-concat-nested-namespaces,
modernize-deprecated-headers,
modernize-deprecated-ios-base-aliases,
modernize-loop-convert,
modernize-make-*,
modernize-raw-string-literal,
modernize-redundant-void-arg,
modernize-replace-*,
modernize-return-braced-init-list,
modernize-shrink-to-fit,
modernize-unary-static-assert,
modernize-use-auto,
modernize-use-bool-literals,
modernize-use-default-member-init,
modernize-use-emplace,
modernize-use-equals-delete,
modernize-use-nodiscard,
modernize-use-equals-default,
modernize-use-noexcept,
modernize-user-override,
modernize-use-nullptr,
modernize-use-transparent-functors,
modernize-use-uncaught-exceptions,
modernize-use-using,
'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
FormatStyle: none
CheckOptions:
- key: bugprone-assert-side-effect.AssertMacros
value: 'assert;Q_ASSERT'
- key: bugprone-dangling-handle.HandleClasses
value: 'std::basic_string_view;std::experimental::basic_string_view;QStringView'
- key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression
value: 1
- key: modernize-use-default-member-init.UseAssignment
value: 1

View File

@@ -122,7 +122,7 @@ steps:
- name: build
image: nextcloudci/client-debian-ci:client-debian-ci-2
commands:
- /bin/bash -c "./admin/linux/debian/drone-build.sh" || echo "[WARNING] Debian build failed but this is a non-blocking CI event"
- /bin/bash -c "./admin/linux/debian/drone-build.sh"
environment:
DEBIAN_SECRET_KEY:
from_secret: DEBIAN_SECRET_KEY

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# You can add one username per supported platform and one custom link
custom: https://www.bountysource.com/teams/nextcloud/issues?tracker_ids=74294474

View File

@@ -1,41 +1,20 @@
<!--
Thanks for reporting issues back to Nextcloud!
Note: This is the **issue tracker of Nextcloud**, please do NOT use this to get answers to your questions or get help for fixing your installation. This is a place to report bugs to developers, after your server has been debugged. You can find help debugging your system on our home user forums: https://help.nextcloud.com or, if you use Nextcloud in a large organization, ask our engineers on https://portal.nextcloud.com. See also https://nextcloud.com/support for support options.
Nextcloud is an open source project backed by Nextcloud GmbH. Most of our volunteers are home users and thus primarily care about issues that affect home users. Our paid engineers prioritize issues of our customers. If you are neither a home user nor a customer, consider paying somebody to fix your issue, do it yourself or become a customer.
Please understand that at the moment, we are very busy with customer issues and some high priority development work. A lot of issues are getting reported. We can't always keep up and timely respond to all of them, but we try!
Guidelines for submitting issues:
* Please search the existing issues first, it's likely that your issue was already reported or even fixed.
- Go to https://github.com/nextcloud and type any word in the top search/command bar. You probably see something like "We couldnt find any repositories matching ..." then click "Issues" in the left navigation.
- You can also filter by appending e. g. "state:open" to the search string.
- More info on search syntax within github: https://help.github.com/articles/searching-issues
* Please fill in as much of the template below as possible. We know it is a pain sometimes, but especially without logs there is often not much we can do: really, if we would have seen the issue you encoutered before, we would already have fixed it. So we did NOT see it, and we will need YOUR help to find out what is wrong and fix it. The logs are absoutely crucial for that. Expect us to quickly close issues without logs or other information we need. If you don't have time to gather the required information, we don't either.
Please also note that we have a https://nextcloud.com/contribute/code-of-conduct/ that applies on Github. To summarize it: please, be kind. We try our best to be nice, too. If you can't be bothered to be polite, please just don't bother to report issues as we won't feel motivated to help you. Remember, we don't get paid to help you!
Dear user,
Please understand that at the moment, we are very busy with customer issues
and some high priority development work. A lot of issues are getting reported.
Right now we can't keep up and timely respond to all of them.
We're sorry for that and are expanding our team, if you're looking for a C++
job or know somebody who is, please point them to https://nextcloud.com/jobs
Don't forget that Github is not a support system or a place to ask for
features but only a place to report verified bugs - see nextcloud.com/support
for support options!
-->
<!--- Please keep the note below for others who read your bug report -->
### How to use GitHub
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are affected by the same issue.
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
* Subscribe to receive notifications on status change and new comments.
### Expected behaviour
Tell us what should happen
### Actual behaviour
Tell us what happens instead
<!--
Did you try end-to-end encryption before version 3.0? Following the instructions from this post might solve your problem since you might need to clean up the keys as that can break the functioning of >3.0 if you had a malformed key: https://help.nextcloud.com/t/help-test-the-latest-version-of-e2ee/87590
-->
### Steps to reproduce
1.
@@ -46,8 +25,8 @@ Did you try end-to-end encryption before version 3.0? Following the instructions
Client version:
<!---
Please try to only report a bug if it happens with the latest version
The latest version can be seen by checking https://nextcloud.com/install/#install-clients
In the case of end-to-end encryption bug reports the client must be at least 3.0 and the server at least 19 with the end to end encryption app version at least 1.5.2.
The latest version can be seen by checking https://download.nextcloud.com/desktop/
For support try our forums: https://help.nextcloud.com
--->
Operating system:
@@ -74,9 +53,7 @@ Storage backend (external storage):
Please use Gist (https://gist.github.com/) or a similar code paster for longer
logs.
1. Client logfile:
<!-- desktop client logs are a hard requirement for bug reports because we don't know how to do magic here :) -->
Output of `nextcloud --logdebug --logwindow` or `nextcloud --logdebug --logfile log.txt`
1. Client logfile: Output of `nextcloud --logwindow` or `nextcloud --logfile log.txt`
(On Windows using `cmd.exe`, you might need to first `cd` into the Nextcloud directory)
(See also https://docs.nextcloud.com/desktop/2.3/troubleshooting.html#log-files)

View File

@@ -199,6 +199,5 @@ X-GNOME-Autostart-Delay=3
# Translations
Icon[ko]=@APPLICATION_ICON_NAME@
Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
GenericName[ko]=폴더 동기화

View File

@@ -1,6 +1,6 @@
set( MIRALL_VERSION_MAJOR 3 )
set( MIRALL_VERSION_MINOR 1 )
set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_VERSION_MINOR 0 )
set( MIRALL_VERSION_PATCH 3 )
set( MIRALL_VERSION_YEAR 2020 )
set( MIRALL_SOVERSION 0 )

View File

@@ -21,16 +21,16 @@ if [ $SUFFIX != "master" ]; then
SUFFIX="PR-$SUFFIX"
fi
#QtKeyChain v0.10.0
#QtKeyChain master
cd /build
git clone https://github.com/frankosterfeld/qtkeychain.git
cd qtkeychain
git checkout v0.10.0
git checkout master
mkdir build
cd build
cmake -D CMAKE_INSTALL_PREFIX=/usr ../
make -j4
make install
make DESTDIR=/app install
#Build client
cd /build
@@ -39,6 +39,8 @@ cd build-client
cmake -D CMAKE_INSTALL_PREFIX=/usr \
-D NO_SHIBBOLETH=1 \
-D BUILD_UPDATER=ON \
-D QTKEYCHAIN_LIBRARY=/app/usr/lib/x86_64-linux-gnu/libqt5keychain.so \
-D QTKEYCHAIN_INCLUDE_DIR=/app/usr/include/qt5keychain/ \
-DMIRALL_VERSION_SUFFIX=PR-$DRONE_PULL_REQUEST \
-DMIRALL_VERSION_BUILD=$DRONE_BUILD_NUMBER \
$DRONE_WORKSPACE

View File

@@ -76,7 +76,7 @@ for distribution in ${UBUNTU_DISTRIBUTIONS} ${DEBIAN_DISTRIBUTIONS}; do
git merge ${DRONE_COMMIT}
admin/linux/debian/scripts/git2changelog.py /tmp/tmpchangelog ${distribution} ${revdate} ${basever}
admin/linux/debian/scripts/git2changelog.py /tmp/tmpchangelog ${distribution} ${revdate}
cat /tmp/tmpchangelog debian/changelog > debian/changelog.new
mv debian/changelog.new debian/changelog

View File

@@ -31,7 +31,7 @@ def getCommitVersion(commit):
try:
for line in subprocess.check_output(["git", "show",
commit + ":VERSION.cmake"]).splitlines():
m = re.match("set\( MIRALL_VERSION_([A-Z]+) +([0-9]+) *\)", line)
m = re.match("set\( MIRALL_VERSION_([A-Z]+) +([0-9])+ *\)", line)
if m is not None:
kind=m.group(1)
version=m.group(2)
@@ -48,7 +48,7 @@ def getCommitVersion(commit):
except:
return None
def collectEntries(baseCommit, baseVersion, kind, finalBaseVersion, finalRevDate, config):
def collectEntries(baseCommit, baseVersion, kind, finalRevDate, config):
newVersionCommit = None
newVersionTag = None
@@ -89,6 +89,7 @@ def collectEntries(baseCommit, baseVersion, kind, finalBaseVersion, finalRevDate
newVersionOrigTag = lastVersionTag
(baseVersion, _kind) = result
version=getCommitVersion(commit)
if version and version!=lastCMAKEVersion:
tag = "v" + version
@@ -118,8 +119,6 @@ def collectEntries(baseCommit, baseVersion, kind, finalBaseVersion, finalRevDate
revdate = datetime.datetime.now().strftime("%Y%m%d.%H%M%S")+ "." + commit
else:
revdate = finalRevDate
if finalBaseVersion is not None:
baseVersion = finalBaseVersion
entries[-1] = (commit, name, email, date, revdate, subject, baseVersion, kind)
entries.reverse()
@@ -168,10 +167,8 @@ if __name__ == "__main__":
distribution = sys.argv[2]
finalRevDate = sys.argv[3] if len(sys.argv)>3 else None
finalBaseVersion = sys.argv[4] if len(sys.argv)>4 else None
entries = collectEntries(baseCommit, baseVersion, "alpha",
finalBaseVersion, finalRevDate, config)
entries = collectEntries(baseCommit, baseVersion, "alpha", finalRevDate, config)
with open(sys.argv[1], "wt") as f:
(baseVersion, revdate, kind) = genChangeLogEntries(f, entries, distribution)

View File

@@ -34,9 +34,9 @@ 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_INSTALLER_REQUIRE_ADMIN "This installer requires admin access, try again"
StrCpy $INIT_INSTALLER_RUNNING "The installer is already running."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "This uninstaller requires admin access, try again."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "This uninstaller requires admin access, try again"
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
StrCpy $INIT_UNINSTALLER_RUNNING "The uninstaller is already running."
StrCpy $SectionGroup_Shortcuts "Shortcuts"

View File

@@ -0,0 +1,50 @@
# (c) 2014 Copyright ownCloud GmbH
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - Try to find QtKeychain
# Once done this will define
# QTKEYCHAIN_FOUND - System has QtKeychain
# QTKEYCHAIN_INCLUDE_DIRS - The QtKeychain include directories
# QTKEYCHAIN_LIBRARIES - The libraries needed to use QtKeychain
# QTKEYCHAIN_DEFINITIONS - Compiler switches required for using LibXml2
# When we build our own Qt we also need to build QtKeychain with it
# so that it doesn't pull a different Qt version. For that reason
# first look in the Qt lib directory for QtKeychain.
get_target_property(_QTCORE_LIB_PATH Qt5::Core IMPORTED_LOCATION_RELEASE)
# Use PATH here because Debian 7.0 has CMake 2.8.9 and DIRECTORY is only available from 2.8.12+
get_filename_component(QT_LIB_DIR "${_QTCORE_LIB_PATH}" PATH)
find_path(QTKEYCHAIN_INCLUDE_DIR
NAMES
keychain.h
HINTS
${QT_LIB_DIR}/../include
PATH_SUFFIXES
qt5keychain
)
find_library(QTKEYCHAIN_LIBRARY
NAMES
qt5keychain
lib5qtkeychain
HINTS
${QT_LIB_DIR}
PATHS
/usr/lib
/usr/lib/${CMAKE_ARCH_TRIPLET}
/usr/local/lib
/opt/local/lib
${CMAKE_LIBRARY_PATH}
${CMAKE_INSTALL_PREFIX}/lib
)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set QTKEYCHAIN_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(Qt5Keychain DEFAULT_MSG
QTKEYCHAIN_LIBRARY QTKEYCHAIN_INCLUDE_DIR)
mark_as_advanced(QTKEYCHAIN_INCLUDE_DIR QTKEYCHAIN_LIBRARY)

View File

@@ -2,7 +2,8 @@
#
# Once done this will define
# SPARKLE_FOUND - system has Sparkle
# SPARKLE_LIBRARY - The framework needed to use Sparkle
# SPARKLE_INCLUDE_DIR - the Sparkle include directory
# SPARKLE_LIBRARY - The library needed to use Sparkle
# Copyright (c) 2009, Vittorio Giovara <vittorio.giovara@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
@@ -14,8 +15,9 @@
include(FindPackageHandleStandardArgs)
find_path(SPARKLE_INCLUDE_DIR Sparkle.h)
find_library(SPARKLE_LIBRARY NAMES Sparkle)
find_package_handle_standard_args(Sparkle DEFAULT_MSG SPARKLE_LIBRARY)
mark_as_advanced(SPARKLE_LIBRARY)
find_package_handle_standard_args(Sparkle DEFAULT_MSG SPARKLE_INCLUDE_DIR SPARKLE_LIBRARY)
mark_as_advanced(SPARKLE_INCLUDE_DIR SPARKLE_LIBRARY)

View File

@@ -33,31 +33,22 @@ Some interesting values that can be set on the configuration file are:
+---------------------------------+---------------+--------------------------------------------------------------------------------------------------------+
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``[General]`` section |
+=================================+===============+=================================================================================================================+
| Variable | Default | Meaning |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``chunkSize`` | ``10000000`` (10 MB) | Specifies the chunk size of uploaded files in bytes. |
| | | The client will dynamically adjust this size within the maximum and minimum bounds (see below). |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``maxChunkSize`` | ``100000000`` (100 MB) | Specifies the maximum chunk size of uploaded files in bytes. |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``minChunkSize`` | ``1000000`` (1 MB) | Specifies the minimum chunk size of uploaded files in bytes. |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``targetChunkUploadDuration`` | ``6000`` (1 minute) | Target duration in milliseconds for chunk uploads. |
| | | The client adjusts the chunk size until each chunk upload takes approximately this long. |
| | | Set to 0 to disable dynamic chunk sizing. |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``promptDeleteAllFiles`` | ``true`` | If a UI prompt should ask for confirmation if it was detected that all files and folders were deleted. |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``maxLogLines`` | ``20000`` | Specifies the maximum number of log lines displayed in the log window. |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``timeout`` | ``300`` | The timeout for network connections in seconds. |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
| ``moveToTrash`` | ``false`` | If non-locally deleted files should be moved to trash instead of deleting them completely. |
| | | This option only works on linux |
+---------------------------------+------------------------+--------------------------------------------------------------------------------------------------------+
+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``[General]`` section |
+=================================+===============+========================================================================================================+
| Variable | Default | Meaning |
+---------------------------------+---------------+--------------------------------------------------------------------------------------------------------+
| ``chunkSize`` | ``5242880`` | Specifies the chunk size of uploaded files in bytes. |
+---------------------------------+---------------+--------------------------------------------------------------------------------------------------------+
| ``promptDeleteAllFiles`` | ``true`` | If a UI prompt should ask for confirmation if it was detected that all files and folders were deleted. |
+---------------------------------+---------------+--------------------------------------------------------------------------------------------------------+
| ``maxLogLines`` | ``20000`` | Specifies the maximum number of log lines displayed in the log window. |
+---------------------------------+---------------+--------------------------------------------------------------------------------------------------------+
| ``timeout`` | ``300`` | The timeout for network connections in seconds. |
+---------------------------------+---------------+--------------------------------------------------------------------------------------------------------+
| ``moveToTrash`` | ``false`` | If non-locally deleted files should be moved to trash instead of deleting them completely. |
| | | This option only works on linux |
+---------------------------------+---------------+--------------------------------------------------------------------------------------------------------+
+----------------------------------------------------------------------------------------------------------------------------------------------------------+

View File

@@ -153,42 +153,10 @@ Saving Files Directly
The Nextcloud client enables you to save log files directly to a predefined file
or directory. This is a useful option for troubleshooting sporadic issues as
it enables you to log large amounts of data and bypass the limited buffer
it enables you to log large amounts of data and bypasses the limited buffer
settings associated with the log window.
To enable logging to a directory, stop the client and add the following to the General section in the configuration file:
```
[General]
logDebug=true
logExpire=<hours>
logDir=<dir>
```
.. note:: Independent of platform you must use slash (/) as a path reparator:
* Correct: C:/Temp
* Not correct: C:\Temp
As an example, to keep log data for two days in a directory called temp:
```
[General]
logDebug=true
logExpire=48
logDir=C:/Temp
```
Once you restart the client, you will find the log file in the ``<dir>`` defined in ``logDir``.
.. note:: You will find the configuration file in the following locations:
* Microsoft Windows systems: ``%APPDATA%\Nextcloud\nextcloud.cfg``
* macOS systems: ``$HOME/Library/Preferences/Nextcloud/nextcloud.cfg``
* Linux distributions: ``$HOME/.config/Nextcloud/nextcloud.cfg``
Alternatively, you can start the client in the command line with parameters:
To save log files to a file or a directory:
1. To save to a file, start the client using the ``--logfile <file>`` command,
where ``<file>`` is the filename to which you want to save the file.
@@ -209,6 +177,21 @@ issue the following command:
nextcloud --logdir /tmp/nextcloud_logs --logexpire 48
```
Alternatively, you can add the following to the configuration file:
```
logDebug=true
logExpire=<hours>
logDir=<dir>
```
Once you restart the client, you will find the log file in the ``<dir>`` defined in ``logDir``.
.. note:: You will find the configuration file in the following locations:
* Microsoft Windows systems: ``%APPDATA%\Nextcloud\nextcloud.cfg``
* macOS systems: ``$HOME/Library/Preferences/Nextcloud/nextcloud.cfg``
* Linux distributions: ``$HOME/.config/Nextcloud/nextcloud.cfg``
Nextcloud server Log File
~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -5,6 +5,5 @@
<file>src/gui/tray/HeaderButton.qml</file>
<file>theme/Style/Style.qml</file>
<file>theme/Style/qmldir</file>
<file>src/gui/tray/ActivityActionButton.qml</file>
</qresource>
</RCC>

View File

@@ -30,7 +30,7 @@ class OwncloudDolphinPlugin : public KOverlayIconPlugin
Q_PLUGIN_METADATA(IID "com.owncloud.ovarlayiconplugin" FILE "ownclouddolphinoverlayplugin.json")
Q_OBJECT
using StatusMap = QHash<QByteArray, QByteArray>;
typedef QHash<QByteArray, QByteArray> StatusMap;
StatusMap m_status;
public:

View File

@@ -83,7 +83,7 @@ HRESULT NCContextMenuRegHandler::RegisterInprocServer(PCWSTR pszModule, const CL
wchar_t szSubkey[MAX_PATH];
// Create the HKCR\CLSID\{<CLSID>} key.
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), LR"(CLSID\%s)", szCLSID);
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
if (SUCCEEDED(hr))
{
hr = SetHKCRRegistryKeyAndValue(szSubkey, nullptr, pszFriendlyName);
@@ -92,7 +92,7 @@ HRESULT NCContextMenuRegHandler::RegisterInprocServer(PCWSTR pszModule, const CL
if (SUCCEEDED(hr))
{
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
LR"(CLSID\%s\InprocServer32)", szCLSID);
L"CLSID\\%s\\InprocServer32", szCLSID);
if (SUCCEEDED(hr))
{
// Set the default value of the InprocServer32 key to the
@@ -121,7 +121,7 @@ HRESULT NCContextMenuRegHandler::UnregisterInprocServer(const CLSID& clsid)
wchar_t szSubkey[MAX_PATH];
// Delete the HKCR\CLSID\{<CLSID>} key.
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), LR"(CLSID\%s)", szCLSID);
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegDelnode(HKEY_CLASSES_ROOT, szSubkey));
@@ -165,7 +165,7 @@ HRESULT NCContextMenuRegHandler::RegisterShellExtContextMenuHandler(
// Create the key HKCR\<File Type>\shellex\ContextMenuHandlers\{friendlyName>}
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
LR"(%s\shellex\ContextMenuHandlers\%s)", pszFileType, pszFriendlyName);
L"%s\\shellex\\ContextMenuHandlers\\%s", pszFileType, pszFriendlyName);
if (SUCCEEDED(hr))
{
// Set the default value of the key.
@@ -206,7 +206,7 @@ HRESULT NCContextMenuRegHandler::UnregisterShellExtContextMenuHandler(
// Remove the HKCR\<File Type>\shellex\ContextMenuHandlers\{friendlyName} key.
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
LR"(%s\shellex\ContextMenuHandlers\%s)", pszFileType, pszFriendlyName);
L"%s\\shellex\\ContextMenuHandlers\\%s", pszFileType, pszFriendlyName);
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegDelnode(HKEY_CLASSES_ROOT, szSubkey));

View File

@@ -113,23 +113,23 @@ void QProgressIndicator::paintEvent(QPaintEvent * /*event*/)
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
int outerRadius = qRound((width - 1) * 0.5);
int innerRadius = qRound((width - 1) * 0.5 * 0.38);
int outerRadius = (width-1)*0.5;
int innerRadius = (width-1)*0.5*0.38;
int capsuleHeight = outerRadius - innerRadius;
int capsuleWidth = qRound((width > 32 ) ? capsuleHeight * 0.23 : capsuleHeight * 0.35);
int capsuleWidth = (width > 32 ) ? capsuleHeight *.23 : capsuleHeight *.35;
int capsuleRadius = capsuleWidth/2;
for (int i=0; i<12; i++)
{
QColor color = m_color;
color.setAlphaF(1.0f - (static_cast<float>(i) / 12.0f));
color.setAlphaF(1.0f - (i/12.0f));
p.setPen(Qt::NoPen);
p.setBrush(color);
p.save();
p.translate(rect().center());
p.rotate(m_angle - i * 30);
p.drawRoundedRect(qRound(-capsuleWidth * 0.5), -(innerRadius + capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
p.rotate(m_angle - i*30.0f);
p.drawRoundedRect(-capsuleWidth*0.5, -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
p.restore();
}
}

View File

@@ -42,7 +42,7 @@ class QProgressIndicator : public QWidget
Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
Q_PROPERTY(QColor color READ color WRITE setColor)
public:
QProgressIndicator(QWidget* parent = nullptr);
QProgressIndicator(QWidget* parent = 0);
/*! Returns the delay between animation steps.
\return The number of milliseconds between animation steps. By default, the animation delay is set to 40 milliseconds.

View File

@@ -197,9 +197,9 @@ void KMessageWidgetPrivate::applyStyleSheet()
const QColor border = bgBaseColor;
// Generate a final background color from overlaying bgBaseColor over windowColor
const int newRed = qRound(bgBaseColor.red() * bgBaseColorAlpha) + qRound(windowColor.red() * (1 - bgBaseColorAlpha));
const int newGreen = qRound(bgBaseColor.green() * bgBaseColorAlpha) + qRound(windowColor.green() * (1 - bgBaseColorAlpha));
const int newBlue = qRound(bgBaseColor.blue() * bgBaseColorAlpha) + qRound(windowColor.blue() * (1 - bgBaseColorAlpha));
const int newRed = (bgBaseColor.red() * bgBaseColorAlpha) + (windowColor.red() * (1 - bgBaseColorAlpha));
const int newGreen = (bgBaseColor.green() * bgBaseColorAlpha) + (windowColor.green() * (1 - bgBaseColorAlpha));
const int newBlue = (bgBaseColor.blue() * bgBaseColorAlpha) + (windowColor.blue() * (1 - bgBaseColorAlpha));
const QColor bgFinalColor = QColor(newRed, newGreen, newBlue);
@@ -241,7 +241,7 @@ void KMessageWidgetPrivate::updateSnapShot()
void KMessageWidgetPrivate::slotTimeLineChanged(qreal value)
{
q->setFixedHeight(qMin(qRound(value * 2.0), 1) * content->height());
q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height());
q->update();
}

View File

@@ -29,8 +29,8 @@
#include "qtlockedfile.h"
#include <cstring>
#include <cerrno>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

View File

@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
template <class T, class const_iterator>
struct QTokenizerPrivate {
using char_type = typename T::value_type;
typedef typename T::value_type char_type;
struct State {
bool inQuote = false;
@@ -110,10 +110,10 @@ struct QTokenizerPrivate {
bool returnQuotes;
};
template <class T, class const_iterator = typename T::const_iterator>
template <class T, class const_iterator>
class QTokenizer {
public:
using char_type = typename T::value_type;
typedef typename T::value_type char_type;
/*!
\class QTokenizer
@@ -220,7 +220,7 @@ public:
Use \c hasNext() to fetch the next token.
*/
T next() const {
int len = std::distance(d->tokenBegin, d->tokenEnd);
int len = d->tokenEnd-d->tokenBegin;
const_iterator tmpStart = d->tokenBegin;
if (!d->returnQuotes && len > 1 && d->isQuote(*d->tokenBegin)) {
tmpStart++;
@@ -234,7 +234,7 @@ private:
QSharedPointer<QTokenizerPrivate<T, const_iterator> > d;
};
class QStringTokenizer : public QTokenizer<QString> {
class QStringTokenizer : public QTokenizer<QString, QString::const_iterator> {
public:
QStringTokenizer(const QString &string, const QString &delim) :
QTokenizer<QString, QString::const_iterator>(string, delim) {}
@@ -243,9 +243,8 @@ public:
* @return A reference to the token within the string
*/
QStringRef stringRef() {
// If those differences overflow an int we'd have a veeeeeery long string in memory
int begin = std::distance(d->begin, d->tokenBegin);
int end = std::distance(d->tokenBegin, d->tokenEnd);
int begin = d->tokenBegin-d->begin;
int end = d->tokenEnd-d->tokenBegin;
if (!d->returnQuotes && d->isQuote(*d->tokenBegin)) {
begin++;
end -= 2;
@@ -254,9 +253,9 @@ public:
}
};
using QByteArrayTokenizer = QTokenizer<QByteArray>;
using StringTokenizer = QTokenizer<std::string>;
using WStringTokenizer = QTokenizer<std::wstring>;
typedef QTokenizer<QByteArray, QByteArray::const_iterator> QByteArrayTokenizer;
typedef QTokenizer<std::string, std::string::const_iterator> StringTokenizer;
typedef QTokenizer<std::wstring, std::wstring::const_iterator> WStringTokenizer;
QT_END_NAMESPACE

View File

@@ -36,12 +36,12 @@
#if defined(Q_OS_WIN)
#include <QLibrary>
#include <qt_windows.h>
using PProcessIdToSessionId = BOOL (WINAPI*)(DWORD, DWORD*);
typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
static PProcessIdToSessionId pProcessIdToSessionId = 0;
#endif
#if defined(Q_OS_UNIX)
#include <ctime>
#include <time.h>
#include <unistd.h>
#endif

View File

@@ -40,7 +40,7 @@ class QtLocalPeer : public QObject
Q_OBJECT
public:
explicit QtLocalPeer(QObject *parent = nullptr, const QString &appId = QString());
explicit QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
bool isClient();
bool sendMessage(const QString &message, int timeout, bool block);
QString applicationId() const

View File

@@ -293,8 +293,8 @@ void selectiveSyncFixup(OCC::SyncJournalDb *journal, const QStringList &newList)
auto oldBlackListSet = journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok).toSet();
if (ok) {
auto blackListSet = newList.toSet();
const auto changes = (oldBlackListSet - blackListSet) + (blackListSet - oldBlackListSet);
for (const auto &it : changes) {
auto changes = (oldBlackListSet - blackListSet) + (blackListSet - oldBlackListSet);
foreach (const auto &it, changes) {
journal->avoidReadFromDbOnNextSync(it);
}
@@ -499,7 +499,7 @@ restart_sync:
}
Cmd cmd;
QString dbPath = options.source_dir + SyncJournalDb::makeDbName(options.source_dir, credentialFreeUrl, folder, user);
QString dbPath = SyncJournalDb::makeDbName(credentialFreeUrl, folder, user);
SyncJournalDb db(dbPath);
if (!selectiveSyncList.empty()) {

View File

@@ -27,7 +27,7 @@ namespace OCC {
class NetrcParser
{
public:
using LoginPair = QPair<QString, QString>;
typedef QPair<QString, QString> LoginPair;
NetrcParser(const QString &file = QString());
bool parse();

View File

@@ -27,7 +27,7 @@ bool SimpleSslErrorHandler::handleErrors(QList<QSslError> errors, const QSslConf
return false;
}
for (const auto &error : qAsConst(errors)) {
foreach (QSslError error, errors) {
certs->append(error.certificate());
}
return true;

View File

@@ -24,7 +24,7 @@
#ifndef _C_JHASH_H
#define _C_JHASH_H
#include <stdint.h> // NOLINT
#include <stdint.h>
#define c_hashsize(n) ((uint8_t) 1 << (n))
#define c_hashmask(n) (xhashsize(n) - 1)
@@ -57,15 +57,15 @@
*/
#define _c_mix(a,b,c) \
{ \
(a) -= (b); (a) -= (c); (a) ^= ((c)>>13); \
(b) -= (c); (b) -= (a); (b) ^= ((a)<<8); \
(c) -= (a); (c) -= (b); (c) ^= ((b)>>13); \
(a) -= (b); (a) -= (c); (a) ^= ((c)>>12); \
(b) -= (c); (b) -= (a); (b) ^= ((a)<<16); \
(c) -= (a); (c) -= (b); (c) ^= ((b)>>5); \
(a) -= (b); (a) -= (c); (a) ^= ((c)>>3); \
(b) -= (c); (b) -= (a); (b) ^= ((a)<<10); \
(c) -= (a); (c) -= (b); (c) ^= ((b)>>15); \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
/**
@@ -88,18 +88,18 @@
*/
#define _c_mix64(a,b,c) \
{ \
(a) -= (b); (a) -= (c); (a) ^= ((c)>>43); \
(b) -= (c); (b) -= (a); (b) ^= ((a)<<9); \
(c) -= (a); (c) -= (b); (c) ^= ((b)>>8); \
(a) -= (b); (a) -= (c); (a) ^= ((c)>>38); \
(b) -= (c); (b) -= (a); (b) ^= ((a)<<23); \
(c) -= (a); (c) -= (b); (c) ^= ((b)>>5); \
(a) -= (b); (a) -= (c); (a) ^= ((c)>>35); \
(b) -= (c); (b) -= (a); (b) ^= ((a)<<49); \
(c) -= (a); (c) -= (b); (c) ^= ((b)>>11); \
(a) -= (b); (a) -= (c); (a) ^= ((c)>>12); \
(b) -= (c); (b) -= (a); (b) ^= ((a)<<18); \
(c) -= (a); (c) -= (b); (c) ^= ((b)>>22); \
a -= b; a -= c; a ^= (c>>43); \
b -= c; b -= a; b ^= (a<<9); \
c -= a; c -= b; c ^= (b>>8); \
a -= b; a -= c; a ^= (c>>38); \
b -= c; b -= a; b ^= (a<<23); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>35); \
b -= c; b -= a; b ^= (a<<49); \
c -= a; c -= b; c ^= (b>>11); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<18); \
c -= a; c -= b; c ^= (b>>22); \
}
/**

View File

@@ -70,7 +70,7 @@ class OCSYNC_EXPORT ComputeChecksum : public QObject
{
Q_OBJECT
public:
explicit ComputeChecksum(QObject *parent = nullptr);
explicit ComputeChecksum(QObject *parent = 0);
/**
* Sets the checksum type to be used. The default is empty.
@@ -112,7 +112,7 @@ class OCSYNC_EXPORT ValidateChecksumHeader : public QObject
{
Q_OBJECT
public:
explicit ValidateChecksumHeader(QObject *parent = nullptr);
explicit ValidateChecksumHeader(QObject *parent = 0);
/**
* Check a file's actual checksum against the provided checksumHeader

View File

@@ -107,7 +107,7 @@ namespace FileSystem {
* Equivalent to QFile::remove(), except on Windows, where it will also
* successfully remove read-only files.
*/
bool OCSYNC_EXPORT remove(const QString &fileName, QString *errorString = nullptr);
bool OCSYNC_EXPORT remove(const QString &fileName, QString *errorString = 0);
/**
* Move the specified file or folder to the trash. (Only implemented on linux)
@@ -175,10 +175,10 @@ namespace FileSystem {
if( str[0] == '/' || str[0] == '\\' ) {
// Don't prepend if already UNC
if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) {
longStr.append(R"(\\?)");
longStr.append("\\\\?");
}
} else {
longStr.append(R"(\\?\)"); // prepend string by this four magic chars.
longStr.append("\\\\?\\"); // prepend string by this four magic chars.
}
longStr += str;

View File

@@ -43,7 +43,9 @@ namespace OCC {
Q_LOGGING_CATEGORY(lcSql, "nextcloud.sync.database.sql", QtInfoMsg)
SqlDatabase::SqlDatabase() = default;
SqlDatabase::SqlDatabase()
{
}
SqlDatabase::~SqlDatabase()
{
@@ -367,14 +369,14 @@ void SqlQuery::bindValue(int pos, const QVariant &value)
const QDateTime dateTime = value.toDateTime();
const QString str = dateTime.toString(QLatin1String("yyyy-MM-ddThh:mm:ss.zzz"));
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
str.size() * static_cast<int>(sizeof(ushort)), SQLITE_TRANSIENT);
str.size() * sizeof(ushort), SQLITE_TRANSIENT);
break;
}
case QVariant::Time: {
const QTime time = value.toTime();
const QString str = time.toString(QLatin1String("hh:mm:ss.zzz"));
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
str.size() * static_cast<int>(sizeof(ushort)), SQLITE_TRANSIENT);
str.size() * sizeof(ushort), SQLITE_TRANSIENT);
break;
}
case QVariant::String: {
@@ -382,7 +384,7 @@ void SqlQuery::bindValue(int pos, const QVariant &value)
// lifetime of string == lifetime of its qvariant
const auto *str = static_cast<const QString *>(value.constData());
res = sqlite3_bind_text16(_stmt, pos, str->utf16(),
(str->size()) * static_cast<int>(sizeof(QChar)), SQLITE_TRANSIENT);
(str->size()) * sizeof(QChar), SQLITE_TRANSIENT);
} else {
res = sqlite3_bind_null(_stmt, pos);
}
@@ -397,7 +399,7 @@ void SqlQuery::bindValue(int pos, const QVariant &value)
QString str = value.toString();
// SQLITE_TRANSIENT makes sure that sqlite buffers the data
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
(str.size()) * static_cast<int>(sizeof(QChar)), SQLITE_TRANSIENT);
(str.size()) * sizeof(QChar), SQLITE_TRANSIENT);
break;
}
}

View File

@@ -23,6 +23,7 @@
#include <QElapsedTimer>
#include <QUrl>
#include <QDir>
#include <QStandardPaths>
#include <sqlite3.h>
#include "common/syncjournaldb.h"
@@ -103,11 +104,15 @@ SyncJournalDb::SyncJournalDb(const QString &dbFilePath, QObject *parent)
}
}
QString SyncJournalDb::makeDbName(const QString &localPath,
const QUrl &remoteUrl,
QString SyncJournalDb::makeDbName(const QUrl &remoteUrl,
const QString &remotePath,
const QString &user)
{
const QString dbPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if (!QDir(dbPath).exists()) {
QDir().mkdir(dbPath);
}
QString journalPath = QLatin1String("._sync_");
QString key = QString::fromUtf8("%1@%2:%3").arg(user, remoteUrl.toString(), remotePath);
@@ -116,17 +121,16 @@ QString SyncJournalDb::makeDbName(const QString &localPath,
journalPath.append(ba.left(6).toHex());
journalPath.append(".db");
journalPath = dbPath + QLatin1Char('/') + journalPath;
// If the journal doesn't exist and we can't create a file
// at that location, try again with a journal name that doesn't
// have the ._ prefix.
//
// The disadvantage of that filename is that it will only be ignored
// by client versions >2.3.2.
//
// See #5633: "._*" is often forbidden on samba shared folders.
// If it exists already, the path is clearly usable
QFile file(QDir(localPath).filePath(journalPath));
QFile file(QDir(dbPath).filePath(journalPath));
if (file.exists()) {
return journalPath;
}
@@ -141,7 +145,7 @@ QString SyncJournalDb::makeDbName(const QString &localPath,
// Can we create it if we drop the underscore?
QString alternateJournalPath = journalPath.mid(2).prepend(".");
QFile file2(QDir(localPath).filePath(alternateJournalPath));
QFile file2(QDir(dbPath).filePath(alternateJournalPath));
if (file2.open(QIODevice::ReadWrite)) {
// The alternative worked, use it
qCInfo(lcDb) << "Using alternate database path" << alternateJournalPath;
@@ -725,10 +729,10 @@ bool SyncJournalDb::updateMetadataTableStructure()
SqlQuery query(_db);
query.prepare("ALTER TABLE metadata ADD COLUMN isE2eEncrypted INTEGER;");
if (!query.exec()) {
sqlFail("updateMetadataTableStructure: add isE2eEncrypted column", query);
sqlFail("updateMetadataTableStructure: add e2eMangledName column", query);
re = false;
}
commitInternal("update database structure: add isE2eEncrypted col");
commitInternal("update database structure: add e2eMangledName col");
}
if (!tableColumns("uploadinfo").contains("contentChecksum")) {
@@ -1452,7 +1456,7 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString &file)
if (_getUploadInfoQuery.next()) {
bool ok = true;
res._chunk = _getUploadInfoQuery.intValue(0);
res._transferid = _getUploadInfoQuery.int64Value(1);
res._transferid = _getUploadInfoQuery.intValue(1);
res._errorCount = _getUploadInfoQuery.intValue(2);
res._size = _getUploadInfoQuery.int64Value(3);
res._modtime = _getUploadInfoQuery.int64Value(4);
@@ -2027,23 +2031,6 @@ QByteArrayList SyncJournalDb::conflictRecordPaths()
return paths;
}
QByteArray SyncJournalDb::conflictFileBaseName(const QByteArray &conflictName)
{
auto conflict = conflictRecord(conflictName);
QByteArray result;
if (conflict.isValid()) {
getFileRecordsByFileId(conflict.baseFileId, [&result](const SyncJournalFileRecord &record) {
if (!record._path.isEmpty())
result = record._path;
});
}
if (result.isEmpty()) {
result = Utility::conflictFileBaseNameFromPattern(conflictName);
}
return result;
}
void SyncJournalDb::clearFileTable()
{
QMutexLocker lock(&_mutex);

View File

@@ -42,12 +42,11 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject
{
Q_OBJECT
public:
explicit SyncJournalDb(const QString &dbFilePath, QObject *parent = nullptr);
explicit SyncJournalDb(const QString &dbFilePath, QObject *parent = 0);
virtual ~SyncJournalDb();
/// Create a journal path for a specific configuration
static QString makeDbName(const QString &localPath,
const QUrl &remoteUrl,
static QString makeDbName(const QUrl &remoteUrl,
const QString &remotePath,
const QString &user);
@@ -95,7 +94,7 @@ public:
struct UploadInfo
{
int _chunk = 0;
quint64 _transferid = 0;
int _transferid = 0;
quint64 _size = 0; //currently unused
qint64 _modtime = 0;
int _errorCount = 0;
@@ -226,13 +225,6 @@ public:
/// Return all paths of files with a conflict tag in the name and records in the db
QByteArrayList conflictRecordPaths();
/** Find the base name for a conflict file name, using journal or name pattern
*
* The path must be sync-folder relative.
*
* Will return an empty string if it's not even a conflict file by pattern.
*/
QByteArray conflictFileBaseName(const QByteArray &conflictName);
/**
* Delete any file entry. This will force the next sync to re-sync everything as if it was new,

View File

@@ -21,7 +21,9 @@
namespace OCC {
SyncJournalFileRecord::SyncJournalFileRecord() = default;
SyncJournalFileRecord::SyncJournalFileRecord()
{
}
QByteArray SyncJournalFileRecord::numericFileId() const
{

View File

@@ -44,8 +44,8 @@
#include <unistd.h>
#endif
#include <cmath>
#include <cstdarg>
#include <math.h>
#include <stdarg.h>
#include <cstring>
#if defined(Q_OS_WIN)
@@ -190,13 +190,6 @@ QByteArray Utility::userAgentString()
return re.toLatin1();
}
QByteArray Utility::friendlyUserAgentString()
{
const auto pattern = QStringLiteral("%1 (Desktop Client - %2)");
const auto userAgent = pattern.arg(QSysInfo::machineHostName(), platform());
return userAgent.toUtf8();
}
bool Utility::hasLaunchOnStartup(const QString &appName)
{
return hasLaunchOnStartup_private(appName);
@@ -414,7 +407,7 @@ uint Utility::convertSizeToUint(size_t &convertVar)
return static_cast<uint>(convertVar);
}
int Utility::convertSizeToInt(size_t &convertVar)
uint Utility::convertSizeToInt(size_t &convertVar)
{
if (convertVar > INT_MAX) {
//throw std::bad_cast();
@@ -641,7 +634,7 @@ bool Utility::isConflictFile(const QString &name)
return false;
}
QByteArray Utility::conflictFileBaseNameFromPattern(const QByteArray &conflictName)
QByteArray Utility::conflictFileBaseName(const QByteArray &conflictName)
{
// This function must be able to deal with conflict files for conflict files.
// To do this, we scan backwards, for the outermost conflict marker and
@@ -673,7 +666,7 @@ QByteArray Utility::conflictFileBaseNameFromPattern(const QByteArray &conflictNa
QString Utility::sanitizeForFileName(const QString &name)
{
const auto invalid = QStringLiteral(R"(/?<>\:*|")");
const auto invalid = QStringLiteral("/?<>\\:*|\"");
QString result;
result.reserve(name.size());
for (const auto c : name) {

View File

@@ -30,11 +30,11 @@
#include <QMap>
#include <QUrl>
#include <QUrlQuery>
#include <QtQuick/QQuickImageProvider>
#include <functional>
#include <memory>
#ifdef Q_OS_WIN
#include <QRect>
#include <windows.h>
#endif
@@ -42,8 +42,6 @@ class QSettings;
namespace OCC {
class SyncJournal;
Q_DECLARE_LOGGING_CATEGORY(lcUtility)
/** \addtogroup libsync
@@ -57,11 +55,10 @@ namespace Utility {
OCSYNC_EXPORT bool writeRandomFile(const QString &fname, int size = -1);
OCSYNC_EXPORT QString octetsToString(qint64 octets);
OCSYNC_EXPORT QByteArray userAgentString();
OCSYNC_EXPORT QByteArray friendlyUserAgentString();
OCSYNC_EXPORT bool hasLaunchOnStartup(const QString &appName);
OCSYNC_EXPORT void setLaunchOnStartup(const QString &appName, const QString &guiName, bool launch);
OCSYNC_EXPORT uint convertSizeToUint(size_t &convertVar);
OCSYNC_EXPORT int convertSizeToInt(size_t &convertVar);
OCSYNC_EXPORT uint convertSizeToInt(size_t &convertVar);
#ifdef Q_OS_WIN
OCSYNC_EXPORT DWORD convertSizeToDWORD(size_t &convertVar);
@@ -191,7 +188,7 @@ namespace Utility {
/** Returns a new settings pre-set in a specific group. The Settings will be created
with the given parent. If no parent is specified, the caller must destroy the settings */
OCSYNC_EXPORT std::unique_ptr<QSettings> settingsWithGroup(const QString &group, QObject *parent = nullptr);
OCSYNC_EXPORT std::unique_ptr<QSettings> settingsWithGroup(const QString &group, QObject *parent = 0);
/** Sanitizes a string that shall become part of a filename.
*
@@ -217,17 +214,16 @@ namespace Utility {
OCSYNC_EXPORT bool isConflictFile(const char *name);
OCSYNC_EXPORT bool isConflictFile(const QString &name);
/** Find the base name for a conflict file name, using name pattern only
/** Find the base name for a conflict file name
*
* Will return an empty string if it's not a conflict file.
*
* Prefer to use the data from the conflicts table in the journal to determine
* a conflict's base file, see SyncJournal::conflictFileBaseName()
* a conflict's base file.
*/
OCSYNC_EXPORT QByteArray conflictFileBaseNameFromPattern(const QByteArray &conflictName);
OCSYNC_EXPORT QByteArray conflictFileBaseName(const QByteArray &conflictName);
#ifdef Q_OS_WIN
OCSYNC_EXPORT bool registryKeyExists(HKEY hRootKey, const QString &subKey);
OCSYNC_EXPORT QVariant registryGetKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName);
OCSYNC_EXPORT bool registrySetKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName, DWORD type, const QVariant &value);
OCSYNC_EXPORT bool registryDeleteKeyTree(HKEY hRootKey, const QString &subKey);

View File

@@ -24,7 +24,7 @@ namespace OCC {
static void setupFavLink_private(const QString &folder)
{
// Nautilus: add to ~/.gtk-bookmarks
QFile gtkBookmarks(QDir::homePath() + QLatin1String("/.config/gtk-3.0/bookmarks"));
QFile gtkBookmarks(QDir::homePath() + QLatin1String("/.gtk-bookmarks"));
QByteArray folderUrl = "file://" + folder.toUtf8();
if (gtkBookmarks.open(QFile::ReadWrite)) {
QByteArray places = gtkBookmarks.readAll();
@@ -47,7 +47,6 @@ QString getUserAutostartDir_private()
bool hasLaunchOnStartup_private(const QString &appName)
{
Q_UNUSED(appName)
QString desktopFileLocation = getUserAutostartDir_private()
+ QLatin1String(LINUX_APPLICATION_ID)
+ QLatin1String(".desktop");
@@ -56,7 +55,6 @@ bool hasLaunchOnStartup_private(const QString &appName)
void setLaunchOnStartup_private(const QString &appName, const QString &guiName, bool enable)
{
Q_UNUSED(appName)
QString userAutoStartPath = getUserAutostartDir_private();
QString desktopFileLocation = userAutoStartPath
+ QLatin1String(LINUX_APPLICATION_ID)

View File

@@ -25,7 +25,7 @@
#include <string>
#include <QLibrary>
static const char runPathC[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)";
static const char runPathC[] = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
namespace OCC {
@@ -91,7 +91,7 @@ void setLaunchOnStartup_private(const QString &appName, const QString &guiName,
static inline bool hasDarkSystray_private()
{
if(Utility::registryGetKeyValue( HKEY_CURRENT_USER,
R"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)",
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
"SystemUsesLightTheme" ) == 1) {
return false;
}
@@ -114,17 +114,6 @@ QRect Utility::getTaskbarDimensions()
return QRect(barRect.left, barRect.top, (barRect.right - barRect.left), (barRect.bottom - barRect.top));
}
bool Utility::registryKeyExists(HKEY hRootKey, const QString &subKey)
{
HKEY hKey;
REGSAM sam = KEY_READ | KEY_WOW64_64KEY;
LONG result = RegOpenKeyEx(hRootKey, reinterpret_cast<LPCWSTR>(subKey.utf16()), 0, sam, &hKey);
RegCloseKey(hKey);
return result != ERROR_FILE_NOT_FOUND;
}
QVariant Utility::registryGetKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName)
{
QVariant value;

View File

@@ -25,13 +25,13 @@
#define _GNU_SOURCE
#endif
#include <cassert>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <stdbool.h>
#include "c_lib.h"
#include "csync_private.h"
@@ -326,7 +326,7 @@ int csync_abort_requested(CSYNC *ctx)
}
}
std::unique_ptr<csync_file_stat_t> csync_file_stat_t::fromSyncJournalFileRecord(const OCC::SyncJournalFileRecord &rec)
std::unique_ptr<csync_file_stat_t> csync_file_stat_s::fromSyncJournalFileRecord(const OCC::SyncJournalFileRecord &rec)
{
std::unique_ptr<csync_file_stat_t> st(new csync_file_stat_t);
st->path = rec._path;

View File

@@ -36,8 +36,8 @@
#include "ocsynclib.h"
#include <sys/stat.h>
#include <cstdint>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <config_csync.h>
#include <functional>
@@ -59,7 +59,7 @@ class SyncJournalFileRecord;
#define BITFIELD(size) :size
#endif
enum CSYNC_STATUS {
enum csync_status_codes_e {
CSYNC_STATUS_OK = 0,
CSYNC_STATUS_ERROR = 1024, /* don't use this code,
@@ -95,6 +95,8 @@ enum CSYNC_STATUS {
CSYNC_STATUS_INDIVIDUAL_CANNOT_ENCODE
};
typedef enum csync_status_codes_e CSYNC_STATUS;
#ifndef likely
# define likely(x) (x)
#endif
@@ -144,7 +146,9 @@ enum ItemType {
// currently specified at https://github.com/owncloud/core/issues/8322 are 9 to 10
#define REMOTE_PERM_BUF_SIZE 15
struct OCSYNC_EXPORT csync_file_stat_t {
typedef struct csync_file_stat_s csync_file_stat_t;
struct OCSYNC_EXPORT csync_file_stat_s {
time_t modtime = 0;
int64_t size = 0;
uint64_t inode = 0;
@@ -175,7 +179,7 @@ struct OCSYNC_EXPORT csync_file_stat_t {
enum csync_instructions_e instruction = CSYNC_INSTRUCTION_NONE; /* u32 */
csync_file_stat_t()
csync_file_stat_s()
: type(ItemTypeSkip)
, child_modified(false)
, has_ignored_files(false)
@@ -189,19 +193,26 @@ struct OCSYNC_EXPORT csync_file_stat_t {
/**
* csync handle
*/
using CSYNC = struct csync_s;
typedef struct csync_s CSYNC;
using csync_auth_callback = int (*)(const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata);
typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata);
using csync_update_callback = void (*)(bool local, const char *dirUrl, void *userdata);
typedef void (*csync_update_callback) (bool local,
const char *dirUrl,
void *userdata);
using csync_vio_handle_t = void;
using csync_vio_opendir_hook = csync_vio_handle_t *(*)(const char *url, void *userdata);
using csync_vio_readdir_hook = std::unique_ptr<csync_file_stat_t> (*)(csync_vio_handle_t *dhandle, void *userdata);
using csync_vio_closedir_hook = void (*)(csync_vio_handle_t *dhandle, void *userdata);
typedef void csync_vio_handle_t;
typedef csync_vio_handle_t* (*csync_vio_opendir_hook) (const char *url,
void *userdata);
typedef std::unique_ptr<csync_file_stat_t> (*csync_vio_readdir_hook) (csync_vio_handle_t *dhhandle,
void *userdata);
typedef void (*csync_vio_closedir_hook) (csync_vio_handle_t *dhhandle,
void *userdata);
/* Compute the checksum of the given \a checksumTypeId for \a path. */
using csync_checksum_hook = QByteArray (*)(const QByteArray &path, const QByteArray &otherChecksumHeader, void *userdata);
typedef QByteArray (*csync_checksum_hook)(
const QByteArray &path, const QByteArray &otherChecksumHeader, void *userdata);
/**
* @brief Update detection

View File

@@ -317,20 +317,17 @@ bool ExcludedFiles::loadExcludeFile(const QByteArray & basePath, const QString &
if (!f.open(QIODevice::ReadOnly))
return false;
QList<QByteArray> patterns;
while (!f.atEnd()) {
QByteArray line = f.readLine().trimmed();
if (line.isEmpty() || line.startsWith('#'))
continue;
csync_exclude_expand_escapes(line);
patterns.append(line);
_allExcludes[basePath].append(line);
}
_allExcludes.insert(basePath, patterns);
// nothing to prepare if the user decided to not exclude anything
if (!_allExcludes.value(basePath).isEmpty()){
if(_allExcludes.size())
prepare(basePath);
}
return true;
}
@@ -414,12 +411,10 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy
// Directories are guaranteed to be visited before their files
if (filetype == ItemTypeDirectory) {
const auto basePath = QString(_localPath + path + QLatin1Char('/')).toUtf8();
const auto fi = QFileInfo(basePath + QStringLiteral(".sync-exclude.lst"));
QFileInfo fi = QFileInfo(_localPath + path + "/.sync-exclude.lst");
if (fi.isReadable()) {
addInTreeExcludeFilePath(fi.absoluteFilePath());
loadExcludeFile(basePath, fi.absoluteFilePath());
loadExcludeFile(fi.absolutePath().toUtf8(), fi.absoluteFilePath());
}
}

View File

@@ -32,7 +32,7 @@
#include <functional>
enum CSYNC_EXCLUDE_TYPE {
enum csync_exclude_type_e {
CSYNC_NOT_EXCLUDED = 0,
CSYNC_FILE_SILENTLY_EXCLUDED,
CSYNC_FILE_EXCLUDE_AND_REMOVE,
@@ -45,6 +45,7 @@ enum CSYNC_EXCLUDE_TYPE {
CSYNC_FILE_EXCLUDE_CONFLICT,
CSYNC_FILE_EXCLUDE_CANNOT_ENCODE
};
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
class ExcludedFilesTest;

View File

@@ -22,20 +22,20 @@
#ifndef _CSYNC_MACROS_H
#define _CSYNC_MACROS_H
#include <cstdlib>
#include <cstring>
#include <stdlib.h>
#include <string.h>
/* How many elements there are in a static array */
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
/* Some special custom errno values to report bugs properly. The BASE value
* should always be larger than the highest system errno. */
#define CSYNC_CUSTOM_ERRNO_BASE 10000
#define ERRNO_WRONG_CONTENT (CSYNC_CUSTOM_ERRNO_BASE+11)
#define ERRNO_SERVICE_UNAVAILABLE (CSYNC_CUSTOM_ERRNO_BASE+14)
#define ERRNO_STORAGE_UNAVAILABLE (CSYNC_CUSTOM_ERRNO_BASE+17)
#define ERRNO_FORBIDDEN (CSYNC_CUSTOM_ERRNO_BASE+18)
#define ERRNO_WRONG_CONTENT CSYNC_CUSTOM_ERRNO_BASE+11
#define ERRNO_SERVICE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+14
#define ERRNO_STORAGE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+17
#define ERRNO_FORBIDDEN CSYNC_CUSTOM_ERRNO_BASE+18
#endif /* _CSYNC_MACROS_H */
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */

View File

@@ -25,12 +25,12 @@
#define _GNU_SOURCE
#endif
#include <climits>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <cerrno>
#include <errno.h>
#if _WIN32
# ifndef _WIN32_IE

View File

@@ -34,8 +34,8 @@
#include <unordered_map>
#include <QHash>
#include <cstdint>
#include <stdint.h>
#include <stdbool.h>
#include <map>
#include <set>
#include <functional>
@@ -189,7 +189,7 @@ struct OCSYNC_EXPORT csync_s {
csync_file_stat_t *current_fs = nullptr;
/* csync error code */
enum CSYNC_STATUS status_code = CSYNC_STATUS_OK;
enum csync_status_codes_e status_code = CSYNC_STATUS_OK;
char *error_string = nullptr;

View File

@@ -20,7 +20,7 @@
#include "config_csync.h"
#include <cassert>
#include <assert.h>
#include "csync_private.h"
#include "csync_reconcile.h"
#include "csync_util.h"
@@ -34,7 +34,7 @@ Q_LOGGING_CATEGORY(lcReconcile, "nextcloud.sync.csync.reconciler", QtInfoMsg)
// Needed for PRIu64 on MinGW in C++ mode.
#define __STDC_FORMAT_MACROS
#include <cinttypes>
#include "inttypes.h"
/* Check if a file is ignored because one parent is ignored.
* return the node of the ignored directoy if it's the case, or \c nullptr if it is not ignored */
@@ -188,12 +188,11 @@ static void _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx)
}();
auto curParent = our_tree->findFile(curParentPath);
if (!other
|| !other->e2eMangledName.isEmpty()
|| (curParent && curParent->isE2eEncrypted)) {
// Stick with the NEW since there's no "other" file
// or if there's an "other" file it involves E2EE and
// we want to always issue delete + upload in such cases
if(!other) {
// Stick with the NEW
return;
} else if (!other->e2eMangledName.isEmpty() || (curParent && curParent->isE2eEncrypted)) {
// Stick with the NEW as well, we want to always issue delete + upload in such cases
return;
} else if (other->instruction == CSYNC_INSTRUCTION_RENAME) {
// Some other EVAL_RENAME already claimed other.
@@ -344,9 +343,7 @@ static void _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx)
auto remoteNode = ctx->current == REMOTE_REPLICA ? cur : other;
auto localNode = ctx->current == REMOTE_REPLICA ? other : cur;
remoteNode->instruction = CSYNC_INSTRUCTION_NONE;
localNode->instruction = up._modtime == localNode->modtime && up._size == localNode->size ?
CSYNC_INSTRUCTION_UPDATE_METADATA : CSYNC_INSTRUCTION_SYNC;
localNode->instruction = up._modtime == localNode->modtime ? CSYNC_INSTRUCTION_UPDATE_METADATA : CSYNC_INSTRUCTION_SYNC;
// Update the etag and other server metadata in the journal already
// (We can't use a typical CSYNC_INSTRUCTION_UPDATE_METADATA because
// we must not store the size/modtime from the file system)

View File

@@ -25,11 +25,11 @@
#define _GNU_SOURCE
#endif
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cmath>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include "c_lib.h"
@@ -50,7 +50,7 @@
// Needed for PRIu64 on MinGW in C++ mode.
#define __STDC_FORMAT_MACROS
#include <cinttypes>
#include <inttypes.h>
Q_LOGGING_CATEGORY(lcUpdate, "nextcloud.sync.csync.updater", QtInfoMsg)

View File

@@ -37,7 +37,7 @@
* @{
*/
using csync_walker_fn = int (*)(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> fs);
typedef int (*csync_walker_fn) (CSYNC *ctx, std::unique_ptr<csync_file_stat_t> fs);
/**
* @brief The walker function to use in the file tree walker.

View File

@@ -25,10 +25,10 @@
#define _GNU_SOURCE
#endif
#include <cerrno>
#include <climits>
#include <cstdio>
#include <ctime>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <time.h>
#include "common/c_jhash.h"
#include "csync_util.h"
@@ -37,10 +37,10 @@
Q_LOGGING_CATEGORY(lcCSyncUtils, "nextcloud.sync.csync.utils", QtInfoMsg)
struct _instr_code_struct {
typedef struct {
const char *instr_str;
enum csync_instructions_e instr_code;
};
} _instr_code_struct;
static const _instr_code_struct _instr[] =
{

View File

@@ -22,7 +22,7 @@
#ifndef _CSYNC_UTIL_H
#define _CSYNC_UTIL_H
#include <cstdint>
#include <stdint.h>
#include "csync_private.h"

View File

@@ -38,7 +38,7 @@
extern "C" {
#endif
#include <stdlib.h> // NOLINT this is sometimes compiled in C mode
#include <stdlib.h>
#include "c_macro.h"

View File

@@ -18,8 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h> // NOLINT this is sometimes compiled in C mode
#include <string.h> // NOLINT this is sometimes compiled in C mode
#include <stdlib.h>
#include <string.h>
#include "c_macro.h"
#include "c_alloc.h"

View File

@@ -31,8 +31,8 @@
#ifndef _C_MACRO_H
#define _C_MACRO_H
#include <stdint.h> // NOLINT this is sometimes compiled in C mode
#include <string.h> // NOLINT this is sometimes compiled in C mode
#include <stdint.h>
#include <string.h>
#define INT_TO_POINTER(i) (void *) i
#define POINTER_TO_INT(p) *((int *) (p))
@@ -44,7 +44,7 @@
#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
/** Free memory and zero the pointer */
#define SAFE_FREE(x) do { if ((x) != NULL) {free((void*)(x)); (x)=NULL;} } while(0)
#define SAFE_FREE(x) do { if ((x) != NULL) {free((void*)x); x=NULL;} } while(0)
/** Get the smaller value */
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -53,7 +53,7 @@
#define MAX(a,b) ((a) < (b) ? (b) : (a))
/** Get the size of an array */
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
/**
* This is a hack to fix warnings. The idea is to use this everywhere that we

View File

@@ -39,7 +39,7 @@
#include <unistd.h>
#endif
#include <errno.h> // NOLINT this is sometimes compiled in C mode
#include <errno.h>
#ifdef __MINGW32__
#define EDQUOT 0
@@ -80,10 +80,10 @@
#ifdef _WIN32
typedef struct stat64 csync_stat_t; // NOLINT this is sometimes compiled in C mode
typedef struct stat64 csync_stat_t;
#define _FILE_OFFSET_BITS 64
#else
typedef struct stat csync_stat_t; // NOLINT this is sometimes compiled in C mode
typedef struct stat csync_stat_t;
#endif
#ifndef O_NOATIME
@@ -112,7 +112,7 @@ typedef struct stat csync_stat_t; // NOLINT this is sometimes compiled in C mode
#endif
#if defined _WIN32 && defined _UNICODE
typedef wchar_t mbchar_t; // NOLINT this is sometimes compiled in C mode
typedef wchar_t mbchar_t;
#define _topen _wopen
#define _tdirent _wdirent
#define _topendir _wopendir
@@ -133,7 +133,7 @@ typedef wchar_t mbchar_t; // NOLINT this is sometimes compiled in C mod
#define _tchdir _wchdir
#define _tgetcwd _wgetcwd
#else
typedef char mbchar_t; // NOLINT this is sometimes compiled in C mode
typedef char mbchar_t;
#define _tdirent dirent
#define _topen open
#define _topendir opendir

View File

@@ -39,7 +39,7 @@ extern "C" {
#include "c_private.h"
#include "c_macro.h"
#include <stdlib.h> // NOLINT this is sometimes compiled in C mode
#include <stdlib.h>
/**
* @brief Compare to strings case insensitively.

View File

@@ -22,8 +22,8 @@
#define _GNU_SOURCE
#endif
#include <cerrno>
#include <cstdio>
#include <errno.h>
#include <stdio.h>
#include "common/asserts.h"
#include "csync_private.h"

View File

@@ -28,9 +28,9 @@
#include "csync.h"
#include "csync_private.h"
struct fhandle_t {
typedef struct fhandle_s {
int fd;
};
} fhandle_t;
csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name);
int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle);

View File

@@ -19,12 +19,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <cerrno>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <cstdio>
#include <stdio.h>
#include <memory>
@@ -43,10 +43,10 @@ Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "nextcloud.sync.csync.vio_local", QtInfoMsg)
* directory functions
*/
struct dhandle_t {
typedef struct dhandle_s {
DIR *dh;
char *path;
};
} dhandle_t;
static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf);

View File

@@ -43,12 +43,12 @@ Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "nextcloud.sync.csync.vio_local", QtInfoMsg)
* directory functions
*/
struct dhandle_t {
typedef struct dhandle_s {
WIN32_FIND_DATA ffd;
HANDLE hFind;
int firstFind;
mbchar_t *path; // Always ends with '\'
};
} dhandle_t;
static int _csync_vio_local_stat_mb(const mbchar_t *uri, csync_file_stat_t *buf);

View File

@@ -4,10 +4,6 @@ set(CMAKE_AUTOMOC TRUE)
set(CMAKE_AUTOUIC TRUE)
set(CMAKE_AUTORCC TRUE)
if(CMAKE_BUILD_TYPE MATCHES Debug)
add_definitions(-DQT_QML_DEBUG)
endif()
IF(BUILD_UPDATER)
add_subdirectory(updater)
endif()
@@ -25,7 +21,6 @@ endif()
set(client_UI_SRCS
accountsettings.ui
conflictdialog.ui
folderwizardsourcepage.ui
folderwizardtargetpage.ui
generalsettings.ui
@@ -43,7 +38,6 @@ set(client_UI_SRCS
addcertificatedialog.ui
proxyauthdialog.ui
mnemonicdialog.ui
tray/ActivityActionButton.qml
tray/Window.qml
tray/UserLine.qml
wizard/flow2authwidget.ui
@@ -60,8 +54,6 @@ set(client_SRCS
accountmanager.cpp
accountsettings.cpp
application.cpp
conflictdialog.cpp
conflictsolver.cpp
connectionvalidator.cpp
folder.cpp
folderman.cpp
@@ -162,16 +154,9 @@ IF( APPLE )
list(APPEND client_SRCS systray.mm)
if(SPARKLE_FOUND AND BUILD_UPDATER)
# Define this, we need to check in updater.cpp
add_definitions(-DHAVE_SPARKLE)
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm updater/sparkleupdater.h)
list(APPEND updater_DEPS ${SPARKLE_LIBRARY})
# Sparkle.framework is installed from here because macdeployqt's CopyFramework breaks on this bundle
# as its logic is tightly tailored around Qt5 frameworks
install(DIRECTORY "${SPARKLE_LIBRARY}"
DESTINATION "${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks" USE_SOURCE_PERMISSIONS)
# Define this, we need to check in updater.cpp
add_definitions( -DHAVE_SPARKLE )
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm)
endif()
ENDIF()
@@ -239,8 +224,9 @@ set( final_src
${3rdparty_MOC}
)
if(Qt5Keychain_FOUND)
list(APPEND libsync_LINK_TARGETS qt5keychain)
if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND)
list(APPEND libsync_LINK_TARGETS ${QTKEYCHAIN_LIBRARY})
include_directories(${QTKEYCHAIN_INCLUDE_DIR})
endif()
# add executable icon on windows and osx
@@ -317,7 +303,7 @@ endif()
IF(BUILD_UPDATER)
add_library(updater STATIC ${updater_SRCS})
target_link_libraries(updater ${synclib_NAME} ${updater_DEPS} Qt5::Widgets Qt5::Svg Qt5::Network Qt5::Xml)
target_link_libraries(updater ${synclib_NAME} Qt5::Widgets Qt5::Svg Qt5::Network Qt5::Xml)
target_include_directories(updater PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
endif()
@@ -328,7 +314,7 @@ set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" )
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::Widgets Qt5::GuiPrivate Qt5::Svg Qt5::Network Qt5::Xml Qt5::Qml Qt5::Quick Qt5::QuickControls2 Qt5::WebEngineWidgets)
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::Widgets Qt5::Svg Qt5::Network Qt5::Xml Qt5::Qml Qt5::Quick Qt5::QuickControls2 Qt5::WebEngineWidgets)
target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
IF(BUILD_UPDATER)
target_link_libraries( ${APPLICATION_EXECUTABLE} updater )

View File

@@ -65,7 +65,7 @@ bool AccountManager::restore()
return true;
}
for (const auto &accountId : settings->childGroups()) {
foreach (const auto &accountId, settings->childGroups()) {
settings->beginGroup(accountId);
if (auto acc = loadAccountHelper(*settings)) {
acc->_id = accountId;
@@ -140,7 +140,7 @@ void AccountManager::save(bool saveCredentials)
{
auto settings = ConfigFile::settingsWithGroup(QLatin1String(accountsC));
settings->setValue(QLatin1String(versionC), 2);
for (const auto &acc : qAsConst(_accounts)) {
foreach (const auto &acc, _accounts) {
settings->beginGroup(acc->account()->id());
saveAccountHelper(acc->account().data(), *settings, saveCredentials);
acc->writeToSettings(*settings);
@@ -187,7 +187,7 @@ void AccountManager::saveAccountHelper(Account *acc, QSettings &settings, bool s
// re-persisting them)
acc->_credentials->persist();
}
for (const auto &key : acc->_settingsMap.keys()) {
Q_FOREACH (QString key, acc->_settingsMap.keys()) {
settings.setValue(key, acc->_settingsMap.value(key));
}
settings.setValue(QLatin1String(authTypeC), acc->_credentials->authType());
@@ -201,7 +201,7 @@ void AccountManager::saveAccountHelper(Account *acc, QSettings &settings, bool s
settings.beginGroup(QLatin1String("General"));
qCInfo(lcAccountManager) << "Saving " << acc->approvedCerts().count() << " unknown certs.";
QByteArray certs;
for (const auto &cert : acc->approvedCerts()) {
Q_FOREACH (const QSslCertificate &cert, acc->approvedCerts()) {
certs += cert.toPem() + '\n';
}
if (!certs.isEmpty()) {
@@ -258,7 +258,7 @@ AccountPtr AccountManager::loadAccountHelper(QSettings &settings)
authType = "webflow";
settings.setValue(QLatin1String(authTypeC), authType);
for (const QString &key : settings.childKeys()) {
foreach(QString key, settings.childKeys()) {
if (!key.startsWith("http_"))
continue;
auto newkey = QString::fromLatin1("webflow_").append(key.mid(5));
@@ -274,7 +274,7 @@ AccountPtr AccountManager::loadAccountHelper(QSettings &settings)
// We want to only restore settings for that auth type and the user value
acc->_settingsMap.insert(QLatin1String(userC), settings.value(userC));
QString authTypePrefix = authType + "_";
for (const auto &key : settings.childKeys()) {
Q_FOREACH (QString key, settings.childKeys()) {
if (!key.startsWith(authTypePrefix))
continue;
acc->_settingsMap.insert(key, settings.value(key));
@@ -292,10 +292,12 @@ AccountPtr AccountManager::loadAccountHelper(QSettings &settings)
AccountStatePtr AccountManager::account(const QString &name)
{
const auto it = std::find_if(_accounts.cbegin(), _accounts.cend(), [name](const auto &acc) {
return acc->account()->displayName() == name;
});
return it != _accounts.cend() ? *it : AccountStatePtr();
foreach (const auto &acc, _accounts) {
if (acc->account()->displayName() == name) {
return acc;
}
}
return AccountStatePtr();
}
AccountState *AccountManager::addAccount(const AccountPtr &newAccount)
@@ -362,9 +364,9 @@ void AccountManager::displayMnemonic(const QString& mnemonic)
void AccountManager::shutdown()
{
const auto accountsCopy = _accounts;
auto accountsCopy = _accounts;
_accounts.clear();
for (const auto &acc : accountsCopy) {
foreach (const auto &acc, accountsCopy) {
emit accountRemoved(acc.data());
emit removeAccountFolders(acc.data());
}
@@ -372,9 +374,12 @@ void AccountManager::shutdown()
bool AccountManager::isAccountIdAvailable(const QString &id) const
{
return std::none_of(_accounts.cbegin(), _accounts.cend(), [id](const auto &acc) {
return acc->account()->id() == id;
});
foreach (const auto &acc, _accounts) {
if (acc->account()->id() == id) {
return false;
}
}
return true;
}
QString AccountManager::generateFreeAccountId() const

View File

@@ -28,7 +28,7 @@ class AccountManager : public QObject
Q_OBJECT
public:
static AccountManager *instance();
~AccountManager() = default;
~AccountManager() {}
/**
* Saves the accounts to a given settings file
@@ -89,7 +89,7 @@ private:
// Adds an account to the tracked list, emitting accountAdded()
void addAccountState(AccountState *accountState);
AccountManager() = default;
AccountManager() {}
QList<AccountStatePtr> _accounts;
public slots:

View File

@@ -37,7 +37,7 @@
#include "syncresult.h"
#include "ignorelisttablewidget.h"
#include <cmath>
#include <math.h>
#include <QDesktopServices>
#include <QDialogButtonBox>
@@ -761,8 +761,8 @@ void AccountSettings::slotAccountStateChanged()
AccountPtr account = _accountState->account();
QUrl safeUrl(account->url());
safeUrl.setPassword(QString()); // Remove the password from the URL to avoid showing it in the UI
const auto folders = FolderMan::instance()->map().values();
for (Folder *folder : folders) {
FolderMan *folderMan = FolderMan::instance();
foreach (Folder *folder, folderMan->map().values()) {
_model->slotUpdateFolderState(folder);
}
@@ -894,16 +894,15 @@ void AccountSettings::refreshSelectiveSyncStatus()
QString msg;
int cnt = 0;
const auto folders = FolderMan::instance()->map().values();
for (Folder *folder : folders) {
foreach (Folder *folder, FolderMan::instance()->map().values()) {
if (folder->accountState() != _accountState) {
continue;
}
bool ok = false;
const auto undecidedList = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, &ok);
auto undecidedList = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, &ok);
QString p;
for (const auto &it : undecidedList) {
foreach (const auto &it, undecidedList) {
// FIXME: add the folder alias in a hoover hint.
// folder->alias() + QLatin1String("/")
if (cnt++) {

View File

@@ -54,13 +54,6 @@ AccountState::AccountState(AccountPtr account)
connect(account.data(), &Account::credentialsAsked,
this, &AccountState::slotCredentialsAsked);
_timeSinceLastETagCheck.invalidate();
connect(this, &AccountState::isConnectedChanged, [=]{
// Get the Apps available on the server if we're now connected.
if (isConnected()) {
fetchNavigationApps();
}
});
}
AccountState::~AccountState() = default;
@@ -243,6 +236,9 @@ void AccountState::checkConnectivity()
// Use a small authed propfind as a minimal ping when we're
// already connected.
conValidator->checkAuthentication();
// Get the Apps available on the server.
fetchNavigationApps();
} else {
// Check the server and then the auth.
@@ -445,10 +441,10 @@ void AccountState::slotNavigationAppsFetched(const QJsonDocument &reply, int sta
if(!reply.isEmpty()){
auto element = reply.object().value("ocs").toObject().value("data");
const auto navLinks = element.toArray();
auto navLinks = element.toArray();
if(navLinks.size() > 0){
for (const QJsonValue &value : navLinks) {
foreach (const QJsonValue &value, navLinks) {
auto navLink = value.toObject();
auto *app = new AccountApp(navLink.value("name").toString(), QUrl(navLink.value("href").toString()),
@@ -472,12 +468,9 @@ AccountAppList AccountState::appList() const
AccountApp* AccountState::findApp(const QString &appId) const
{
if(!appId.isEmpty()) {
const auto apps = appList();
const auto it = std::find_if(apps.cbegin(), apps.cend(), [appId](const auto &app) {
return app->id() == appId;
});
if (it != apps.cend()) {
return *it;
foreach(AccountApp *app, appList()) {
if(app->id() == appId)
return app;
}
}

View File

@@ -32,8 +32,8 @@ class Account;
class AccountApp;
class RemoteWipe;
using AccountStatePtr = QExplicitlySharedDataPointer<AccountState>;
using AccountAppList = QList<AccountApp *>;
typedef QExplicitlySharedDataPointer<AccountState> AccountStatePtr;
typedef QList<AccountApp*> AccountAppList;
/**
* @brief Extra info about an ownCloud server account.
@@ -75,7 +75,7 @@ public:
};
/// The actual current connectivity status.
using ConnectionStatus = ConnectionValidator::Status;
typedef ConnectionValidator::Status ConnectionStatus;
/// Use the account as parent
explicit AccountState(AccountPtr account);
@@ -229,7 +229,7 @@ class AccountApp : public QObject
public:
AccountApp(const QString &name, const QUrl &url,
const QString &id, const QUrl &iconUrl,
QObject* parent = nullptr);
QObject* parent = 0);
QString name() const;
QUrl url() const;

View File

@@ -241,7 +241,7 @@ Application::Application(int &argc, char **argv)
this, &Application::slotAccountStateAdded);
connect(AccountManager::instance(), &AccountManager::accountRemoved,
this, &Application::slotAccountStateRemoved);
for (const auto &ai : AccountManager::instance()->accounts()) {
foreach (auto ai, AccountManager::instance()->accounts()) {
slotAccountStateAdded(ai.data());
}
@@ -349,8 +349,8 @@ void Application::slotSystemOnlineConfigurationChanged(QNetworkConfiguration cnf
void Application::slotCheckConnection()
{
const auto list = AccountManager::instance()->accounts();
for (const auto &accountState : list) {
auto list = AccountManager::instance()->accounts();
foreach (const auto &accountState, list) {
AccountState::State state = accountState->state();
// Don't check if we're manually signed out or
@@ -408,9 +408,7 @@ void Application::setupLogging()
// might be called from second instance
auto logger = Logger::instance();
logger->setLogFile(_logFile);
if (_logFile.isEmpty()) {
logger->setLogDir(_logDir.isEmpty() ? ConfigFile().logDir() : _logDir);
}
logger->setLogDir(!_logDir.isEmpty() ? _logDir : ConfigFile().logDir());
logger->setLogExpire(_logExpire > 0 ? _logExpire : ConfigFile().logExpire());
logger->setLogFlush(_logFlush || ConfigFile().logFlush());
logger->setLogDebug(_logDebug || ConfigFile().logDebug());
@@ -614,7 +612,7 @@ void Application::setupTranslations()
auto *qtTranslator = new QTranslator(this);
auto *qtkeychainTranslator = new QTranslator(this);
for (QString lang : qAsConst(uiLanguages)) {
foreach (QString lang, uiLanguages) {
lang.replace(QLatin1Char('-'), QLatin1Char('_')); // work around QTBUG-25973
lang = substLang(lang);
const QString trPath = applicationTrPath();

View File

@@ -20,17 +20,17 @@
/* Forward declaration required since gio header files interfere with QObject headers */
struct _CloudProvidersProviderExporter;
using CloudProvidersProviderExporter = _CloudProvidersProviderExporter;
typedef _CloudProvidersProviderExporter CloudProvidersProviderExporter;
struct _CloudProvidersAccountExporter;
using CloudProvidersAccountExporter = _CloudProvidersAccountExporter;
typedef _CloudProvidersAccountExporter CloudProvidersAccountExporter;
struct _GMenuModel;
using GMenuModel = _GMenuModel;
typedef _GMenuModel GMenuModel;
struct _GMenu;
using GMenu = _GMenu;
typedef _GMenu GMenu;
struct _GActionGroup;
using GActionGroup = _GActionGroup;
using gchar = char;
using gpointer = void*;
typedef _GActionGroup GActionGroup;
typedef char gchar;
typedef void* gpointer;
using namespace OCC;

View File

@@ -1,181 +0,0 @@
/*
* Copyright (C) by Kevin Ottens <kevin.ottens@nextcloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "conflictdialog.h"
#include "ui_conflictdialog.h"
#include "conflictsolver.h"
#include <QDateTime>
#include <QDebug>
#include <QDesktopServices>
#include <QFileInfo>
#include <QMimeDatabase>
#include <QPushButton>
#include <QUrl>
namespace {
void forceHeaderFont(QWidget *widget)
{
auto font = widget->font();
font.setPointSizeF(font.pointSizeF() * 1.5);
widget->setFont(font);
}
void setBoldFont(QWidget *widget, bool bold)
{
auto font = widget->font();
font.setBold(bold);
widget->setFont(font);
}
}
namespace OCC {
ConflictDialog::ConflictDialog(QWidget *parent)
: QDialog(parent)
, _ui(new Ui::ConflictDialog)
, _solver(new ConflictSolver(this))
{
_ui->setupUi(this);
forceHeaderFont(_ui->conflictMessage);
_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Keep selected version"));
connect(_ui->localVersionRadio, &QCheckBox::toggled, this, &ConflictDialog::updateButtonStates);
connect(_ui->localVersionButton, &QToolButton::clicked, this, [=] {
QDesktopServices::openUrl(QUrl::fromLocalFile(_solver->localVersionFilename()));
});
connect(_ui->remoteVersionRadio, &QCheckBox::toggled, this, &ConflictDialog::updateButtonStates);
connect(_ui->remoteVersionButton, &QToolButton::clicked, this, [=] {
QDesktopServices::openUrl(QUrl::fromLocalFile(_solver->remoteVersionFilename()));
});
connect(_solver, &ConflictSolver::localVersionFilenameChanged, this, &ConflictDialog::updateWidgets);
connect(_solver, &ConflictSolver::remoteVersionFilenameChanged, this, &ConflictDialog::updateWidgets);
}
QString ConflictDialog::baseFilename() const
{
return _baseFilename;
}
ConflictDialog::~ConflictDialog() = default;
QString ConflictDialog::localVersionFilename() const
{
return _solver->localVersionFilename();
}
QString ConflictDialog::remoteVersionFilename() const
{
return _solver->remoteVersionFilename();
}
void ConflictDialog::setBaseFilename(const QString &baseFilename)
{
if (_baseFilename == baseFilename) {
return;
}
_baseFilename = baseFilename;
_ui->conflictMessage->setText(tr("Conflicting versions of %1.").arg(_baseFilename));
}
void ConflictDialog::setLocalVersionFilename(const QString &localVersionFilename)
{
_solver->setLocalVersionFilename(localVersionFilename);
}
void ConflictDialog::setRemoteVersionFilename(const QString &remoteVersionFilename)
{
_solver->setRemoteVersionFilename(remoteVersionFilename);
}
void ConflictDialog::accept()
{
const auto isLocalPicked = _ui->localVersionRadio->isChecked();
const auto isRemotePicked = _ui->remoteVersionRadio->isChecked();
Q_ASSERT(isLocalPicked || isRemotePicked);
if (!isLocalPicked && !isRemotePicked) {
return;
}
const auto solution = isLocalPicked && isRemotePicked ? ConflictSolver::KeepBothVersions
: isLocalPicked ? ConflictSolver::KeepLocalVersion
: ConflictSolver::KeepRemoteVersion;
if (_solver->exec(solution)) {
QDialog::accept();
}
}
void ConflictDialog::updateWidgets()
{
QMimeDatabase mimeDb;
const auto updateGroup = [this, &mimeDb](const QString &filename, QLabel *linkLabel, const QString &linkText, QLabel *mtimeLabel, QLabel *sizeLabel, QToolButton *button) {
const auto fileUrl = QUrl::fromLocalFile(filename).toString();
linkLabel->setText(QStringLiteral("<a href='%1'>%2</a>").arg(fileUrl).arg(linkText));
const auto info = QFileInfo(filename);
mtimeLabel->setText(info.lastModified().toString());
sizeLabel->setText(locale().formattedDataSize(info.size()));
const auto mime = mimeDb.mimeTypeForFile(filename);
if (QIcon::hasThemeIcon(mime.iconName())) {
button->setIcon(QIcon::fromTheme(mime.iconName()));
} else {
button->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/file-128.png"));
}
};
const auto localVersion = _solver->localVersionFilename();
updateGroup(localVersion,
_ui->localVersionLink,
tr("Open local version"),
_ui->localVersionMtime,
_ui->localVersionSize,
_ui->localVersionButton);
const auto remoteVersion = _solver->remoteVersionFilename();
updateGroup(remoteVersion,
_ui->remoteVersionLink,
tr("Open server version"),
_ui->remoteVersionMtime,
_ui->remoteVersionSize,
_ui->remoteVersionButton);
const auto localMtime = QFileInfo(localVersion).lastModified();
const auto remoteMtime = QFileInfo(remoteVersion).lastModified();
setBoldFont(_ui->localVersionMtime, localMtime > remoteMtime);
setBoldFont(_ui->remoteVersionMtime, remoteMtime > localMtime);
}
void ConflictDialog::updateButtonStates()
{
const auto isLocalPicked = _ui->localVersionRadio->isChecked();
const auto isRemotePicked = _ui->remoteVersionRadio->isChecked();
_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isLocalPicked || isRemotePicked);
const auto text = isLocalPicked && isRemotePicked ? tr("Keep both versions")
: isLocalPicked ? tr("Keep local version")
: isRemotePicked ? tr("Keep server version")
: tr("Keep selected version");
_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(text);
}
} // namespace OCC

View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) by Kevin Ottens <kevin.ottens@nextcloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef CONFLICTDIALOG_H
#define CONFLICTDIALOG_H
#include <QDialog>
namespace OCC {
class ConflictSolver;
namespace Ui {
class ConflictDialog;
}
class ConflictDialog : public QDialog
{
Q_OBJECT
public:
explicit ConflictDialog(QWidget *parent = nullptr);
~ConflictDialog() override;
QString baseFilename() const;
QString localVersionFilename() const;
QString remoteVersionFilename() const;
public slots:
void setBaseFilename(const QString &baseFilename);
void setLocalVersionFilename(const QString &localVersionFilename);
void setRemoteVersionFilename(const QString &remoteVersionFilename);
void accept() override;
private:
void updateWidgets();
void updateButtonStates();
QString _baseFilename;
QScopedPointer<Ui::ConflictDialog> _ui;
ConflictSolver *_solver;
};
} // namespace OCC
#endif // CONFLICTDIALOG_H

View File

@@ -1,305 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OCC::ConflictDialog</class>
<widget class="QDialog" name="OCC::ConflictDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>504</width>
<height>407</height>
</rect>
</property>
<property name="windowTitle">
<string>Sync Conflict</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="conflictMessage">
<property name="text">
<string>Conflicting versions of %1.</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>16</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Which version of the file do you want to keep?&lt;br/&gt;If you select both versions, the local file will have a number added to its name.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>16</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QCheckBox" name="localVersionRadio">
<property name="text">
<string>Local version</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QToolButton" name="localVersionButton">
<property name="toolTip">
<string>Click to open the file</string>
</property>
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,0,1">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="localVersionMtime">
<property name="text">
<string>today</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="localVersionSize">
<property name="text">
<string>0 byte</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="localVersionLink">
<property name="text">
<string>&lt;a href=&quot;%1&quot;&gt;Open local version&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QCheckBox" name="remoteVersionRadio">
<property name="text">
<string>Server version</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QToolButton" name="remoteVersionButton">
<property name="toolTip">
<string>Click to open the file</string>
</property>
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,1">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="remoteVersionMtime">
<property name="text">
<string>today</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="remoteVersionSize">
<property name="text">
<string>0 byte</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="remoteVersionLink">
<property name="text">
<string>&lt;a href=&quot;%1&quot;&gt;Open server version&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>OCC::ConflictDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>123</x>
<y>218</y>
</hint>
<hint type="destinationlabel">
<x>148</x>
<y>248</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>OCC::ConflictDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>181</x>
<y>215</y>
</hint>
<hint type="destinationlabel">
<x>240</x>
<y>254</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,164 +0,0 @@
/*
* Copyright (C) by Kevin Ottens <kevin.ottens@nextcloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "conflictsolver.h"
#include <QFileDialog>
#include <QMessageBox>
#include "common/utility.h"
#include "filesystem.h"
namespace OCC {
Q_LOGGING_CATEGORY(lcConflict, "nextcloud.gui.conflictsolver", QtInfoMsg)
ConflictSolver::ConflictSolver(QWidget *parent)
: QObject(parent)
, _parentWidget(parent)
{
}
QString ConflictSolver::localVersionFilename() const
{
return _localVersionFilename;
}
QString ConflictSolver::remoteVersionFilename() const
{
return _remoteVersionFilename;
}
bool ConflictSolver::exec(ConflictSolver::Solution solution)
{
switch (solution) {
case KeepLocalVersion:
return overwriteRemoteVersion();
case KeepRemoteVersion:
return deleteLocalVersion();
case KeepBothVersions:
return renameLocalVersion();
}
Q_UNREACHABLE();
return false;
}
void ConflictSolver::setLocalVersionFilename(const QString &localVersionFilename)
{
if (_localVersionFilename == localVersionFilename) {
return;
}
_localVersionFilename = localVersionFilename;
emit localVersionFilenameChanged();
}
void ConflictSolver::setRemoteVersionFilename(const QString &remoteVersionFilename)
{
if (_remoteVersionFilename == remoteVersionFilename) {
return;
}
_remoteVersionFilename = remoteVersionFilename;
emit remoteVersionFilenameChanged();
}
bool ConflictSolver::deleteLocalVersion()
{
if (_localVersionFilename.isEmpty()) {
return false;
}
QFileInfo info(_localVersionFilename);
if (!info.exists()) {
return false;
}
const auto message = info.isDir() ? tr("Do you want to delete the directory <i>%1</i> and all its contents permanently?").arg(info.dir().dirName())
: tr("Do you want to delete the file <i>%1</i> permanently?").arg(info.fileName());
const auto result = QMessageBox::question(_parentWidget, tr("Confirm deletion"), message, QMessageBox::Yes, QMessageBox::No);
if (result != QMessageBox::Yes)
return false;
if (info.isDir()) {
return FileSystem::removeRecursively(_localVersionFilename);
} else {
return QFile(_localVersionFilename).remove();
}
}
bool ConflictSolver::renameLocalVersion()
{
if (_localVersionFilename.isEmpty()) {
return false;
}
QFileInfo info(_localVersionFilename);
if (!info.exists()) {
return false;
}
const auto renamePattern = [=] {
auto result = QString::fromUtf8(OCC::Utility::conflictFileBaseNameFromPattern(_localVersionFilename.toUtf8()));
const auto dotIndex = result.lastIndexOf('.');
return QString(result.left(dotIndex) + "_%1" + result.mid(dotIndex));
}();
const auto targetFilename = [=] {
uint i = 1;
auto result = renamePattern.arg(i);
while (QFileInfo::exists(result)) {
Q_ASSERT(i > 0);
i++;
result = renamePattern.arg(i);
}
return result;
}();
QString error;
if (FileSystem::uncheckedRenameReplace(_localVersionFilename, targetFilename, &error)) {
return true;
} else {
qCWarning(lcConflict) << "Rename error:" << error;
QMessageBox::warning(_parentWidget, tr("Error"), tr("Moving file failed:\n\n%1").arg(error));
return false;
}
}
bool ConflictSolver::overwriteRemoteVersion()
{
if (_localVersionFilename.isEmpty()) {
return false;
}
if (_remoteVersionFilename.isEmpty()) {
return false;
}
QFileInfo info(_localVersionFilename);
if (!info.exists()) {
return false;
}
QString error;
if (FileSystem::uncheckedRenameReplace(_localVersionFilename, _remoteVersionFilename, &error)) {
return true;
} else {
qCWarning(lcConflict) << "Rename error:" << error;
QMessageBox::warning(_parentWidget, tr("Error"), tr("Moving file failed:\n\n%1").arg(error));
return false;
}
}
} // namespace OCC

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) by Kevin Ottens <kevin.ottens@nextcloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef CONFLICTSOLVER_H
#define CONFLICTSOLVER_H
#include <QObject>
class QWidget;
namespace OCC {
class ConflictSolver : public QObject
{
Q_OBJECT
Q_PROPERTY(QString localVersionFilename READ localVersionFilename WRITE setLocalVersionFilename NOTIFY localVersionFilenameChanged)
Q_PROPERTY(QString remoteVersionFilename READ remoteVersionFilename WRITE setRemoteVersionFilename NOTIFY remoteVersionFilenameChanged)
public:
enum Solution {
KeepLocalVersion,
KeepRemoteVersion,
KeepBothVersions
};
explicit ConflictSolver(QWidget *parent = nullptr);
QString localVersionFilename() const;
QString remoteVersionFilename() const;
bool exec(Solution solution);
public slots:
void setLocalVersionFilename(const QString &localVersionFilename);
void setRemoteVersionFilename(const QString &remoteVersionFilename);
signals:
void localVersionFilenameChanged();
void remoteVersionFilenameChanged();
private:
bool deleteLocalVersion();
bool renameLocalVersion();
bool overwriteRemoteVersion();
QWidget *_parentWidget;
QString _localVersionFilename;
QString _remoteVersionFilename;
};
} // namespace OCC
#endif // CONFLICTSOLVER_H

View File

@@ -82,7 +82,6 @@ void Flow2Auth::fetchNewToken(const TokenAction action)
// add 'Content-Length: 0' header (see https://github.com/nextcloud/desktop/issues/1473)
QNetworkRequest req;
req.setHeader(QNetworkRequest::ContentLengthHeader, "0");
req.setHeader(QNetworkRequest::UserAgentHeader, Utility::friendlyUserAgentString());
auto job = _account->sendRequest("POST", url, req);
job->setTimeout(qMin(30 * 1000ll, job->timeoutMsec()));

View File

@@ -77,8 +77,8 @@ private:
QString _pollToken;
QString _pollEndpoint;
QTimer _pollTimer;
qint64 _secondsLeft;
qint64 _secondsInterval;
int _secondsLeft;
int _secondsInterval;
bool _isBusy;
bool _hasToken;
};

View File

@@ -33,7 +33,7 @@
#include "owncloudgui.h"
#include "syncengine.h"
#include <qt5keychain/keychain.h>
#include <keychain.h>
using namespace QKeychain;

View File

@@ -85,7 +85,10 @@ static void addSettingsToJob(Account *account, QKeychain::Job *job)
}
#endif
WebFlowCredentials::WebFlowCredentials() = default;
WebFlowCredentials::WebFlowCredentials()
{
}
WebFlowCredentials::WebFlowCredentials(const QString &user, const QString &password, const QSslCertificate &certificate, const QSslKey &key, const QList<QSslCertificate> &caCertificates)
: _user(user)
@@ -249,7 +252,6 @@ void WebFlowCredentials::persist() {
void WebFlowCredentials::slotWriteClientCertPEMJobDone(KeychainChunk::WriteJob *writeJob)
{
Q_UNUSED(writeJob)
// write ssl key if there is one
if (!_clientSslKey.isNull()) {
auto job = new KeychainChunk::WriteJob(_account,
@@ -296,7 +298,6 @@ void WebFlowCredentials::writeSingleClientCaCertPEM()
void WebFlowCredentials::slotWriteClientKeyPEMJobDone(KeychainChunk::WriteJob *writeJob)
{
Q_UNUSED(writeJob)
_clientSslCaCertificatesWriteQueue.clear();
// write ca certs if there are any

View File

@@ -159,7 +159,6 @@ void WebFlowCredentialsDialog::slotShowSettingsDialog()
void WebFlowCredentialsDialog::slotFlow2AuthResult(Flow2Auth::Result r, const QString &errorString, const QString &user, const QString &appPassword)
{
Q_UNUSED(errorString)
if(r == Flow2Auth::LoggedIn) {
emit urlCatched(user, appPassword, QString());
} else {

View File

@@ -441,7 +441,7 @@ int Folder::slotDiscardDownloadProgress()
QSet<QString> keep_nothing;
const QVector<SyncJournalDb::DownloadInfo> deleted_infos =
_journal.getAndDeleteStaleDownloadInfos(keep_nothing);
for (const auto &deleted_info : deleted_infos) {
foreach (const SyncJournalDb::DownloadInfo &deleted_info, deleted_infos) {
const QString tmppath = folderpath.filePath(deleted_info._tmpfile);
qCInfo(lcFolder) << "Deleting temporary file: " << tmppath;
FileSystem::remove(tmppath);
@@ -528,10 +528,13 @@ void Folder::saveToSettings() const
// This ensures that older clients will not read a configuration
// where two folders for different accounts point at the same
// local folders.
const auto folderMap = FolderMan::instance()->map();
const auto oneAccountOnly = std::none_of(folderMap.cbegin(), folderMap.cend(), [this](const auto *other) {
return other != this && other->cleanPath() == this->cleanPath();
});
bool oneAccountOnly = true;
foreach (Folder *other, FolderMan::instance()->map()) {
if (other != this && other->cleanPath() == this->cleanPath()) {
oneAccountOnly = false;
break;
}
}
bool compatible = _saveBackwardsCompatible || oneAccountOnly;
@@ -898,6 +901,43 @@ void Folder::slotItemCompleted(const SyncFileItemPtr &item)
return;
}
// add new directories or remove gone away dirs to the watcher
if (_folderWatcher && item->isDirectory()) {
switch (item->_instruction) {
case CSYNC_INSTRUCTION_NEW:
_folderWatcher->addPath(path() + item->_file);
break;
case CSYNC_INSTRUCTION_REMOVE:
_folderWatcher->removePath(path() + item->_file);
break;
case CSYNC_INSTRUCTION_RENAME:
_folderWatcher->removePath(path() + item->_file);
_folderWatcher->addPath(path() + item->destination());
break;
default:
break;
}
}
// Success and failure of sync items adjust what the next sync is
// supposed to do.
//
// For successes, we want to wipe the file from the list to ensure we don't
// rediscover it even if this overall sync fails.
//
// For failures, we want to add the file to the list so the next sync
// will be able to retry it.
if (item->_status == SyncFileItem::Success
|| item->_status == SyncFileItem::FileIgnored
|| item->_status == SyncFileItem::Restoration
|| item->_status == SyncFileItem::Conflict) {
if (_previousLocalDiscoveryPaths.erase(item->_file.toUtf8()))
qCDebug(lcFolder) << "local discovery: wiped" << item->_file;
} else {
_localDiscoveryPaths.insert(item->_file.toUtf8());
qCDebug(lcFolder) << "local discovery: inserted" << item->_file << "due to sync failure";
}
_syncResult.processCompletedItem(item);
_fileLog->logItem(*item);
@@ -1040,7 +1080,6 @@ void Folder::registerFolderWatcher()
connect(_folderWatcher.data(), &FolderWatcher::becameUnreliable,
this, &Folder::slotWatcherUnreliable);
_folderWatcher->init(path());
_folderWatcher->startNotificatonTest(path() + QLatin1String(".owncloudsync.log"));
}
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction dir, bool *cancel)
@@ -1168,7 +1207,7 @@ QString FolderDefinition::absoluteJournalPath() const
QString FolderDefinition::defaultJournalPath(AccountPtr account)
{
return SyncJournalDb::makeDbName(localPath, account->url(), targetPath, account->credentials()->user());
return SyncJournalDb::makeDbName(account->url(), targetPath, account->credentials()->user());
}
} // namespace OCC

View File

@@ -51,7 +51,7 @@ public:
QString alias;
/// path on local machine
QString localPath;
/// path to the journal, usually relative to localPath
/// path to the journal, usually in QStandardPaths::AppDataLocation
QString journalPath;
/// path on remote
QString targetPath;
@@ -95,8 +95,8 @@ public:
~Folder();
using Map = QMap<QString, Folder *>;
using MapIterator = QMapIterator<QString, Folder *>;
typedef QMap<QString, Folder *> Map;
typedef QMapIterator<QString, Folder *> MapIterator;
/**
* The account the folder is configured on.

View File

@@ -171,7 +171,7 @@ int FolderMan::setupFolders()
qCInfo(lcFolderMan) << "Setup folders from settings file";
for (const auto &account : AccountManager::instance()->accounts()) {
foreach (const auto &account, AccountManager::instance()->accounts()) {
const auto id = account->account()->id();
if (!accountsWithSettings.contains(id)) {
continue;
@@ -197,7 +197,7 @@ int FolderMan::setupFolders()
void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account, bool backwardsCompatible)
{
for (const auto &folderAlias : settings.childGroups()) {
foreach (const auto &folderAlias, settings.childGroups()) {
FolderDefinition folderDefinition;
if (FolderDefinition::load(settings, folderAlias, &folderDefinition)) {
auto defaultJournalPath = folderDefinition.defaultJournalPath(account->account());
@@ -207,11 +207,11 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account,
folderDefinition.journalPath = defaultJournalPath;
}
// Migration #2: journalPath might be absolute (in DataAppDir most likely) move it back to the root of local tree
if (folderDefinition.journalPath.at(0) != QChar('.')) {
QFile oldJournal(folderDefinition.journalPath);
QFile oldJournalShm(folderDefinition.journalPath + QStringLiteral("-shm"));
QFile oldJournalWal(folderDefinition.journalPath + QStringLiteral("-wal"));
// Migration #2: journalPath now in DataAppDir, not root of local tree (cross-platform persistent user roaming files)
if (folderDefinition.journalPath.at(0) == QChar('.')) {
QFile oldJournal(folderDefinition.localPath + "/" + folderDefinition.journalPath);
QFile oldJournalShm(folderDefinition.localPath + "/" + folderDefinition.journalPath.append("-shm"));
QFile oldJournalWal(folderDefinition.localPath + "/" + folderDefinition.journalPath.append("-wal"));
folderDefinition.journalPath = defaultJournalPath;
@@ -221,17 +221,17 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account,
auto journalFileMoveSuccess = true;
// Due to db logic can't be sure which of these file exist.
if (oldJournal.exists()) {
journalFileMoveSuccess &= oldJournal.rename(folderDefinition.localPath + "/" + folderDefinition.journalPath);
journalFileMoveSuccess &= oldJournal.rename(folderDefinition.journalPath);
}
if (oldJournalShm.exists()) {
journalFileMoveSuccess &= oldJournalShm.rename(folderDefinition.localPath + "/" + folderDefinition.journalPath + QStringLiteral("-shm"));
journalFileMoveSuccess &= oldJournalShm.rename(folderDefinition.journalPath.append("-shm"));
}
if (oldJournalWal.exists()) {
journalFileMoveSuccess &= oldJournalWal.rename(folderDefinition.localPath + "/" + folderDefinition.journalPath + QStringLiteral("-wal"));
journalFileMoveSuccess &= oldJournalWal.rename(folderDefinition.journalPath.append("-wal"));
}
if (!journalFileMoveSuccess) {
qCWarning(lcFolderMan) << "Wasn't able to move 3.0 syncjournal database files to new location. One-time loss off sync settings possible.";
qCWarning(lcFolderMan) << "Wasn't able to move pre-2.7 syncjournal database files to new location. One-time loss off sync settings possible.";
} else {
qCInfo(lcFolderMan) << "Successfully migrated syncjournal database.";
}
@@ -280,11 +280,11 @@ int FolderMan::setupFoldersMigration()
QDir dir(_folderConfigPath);
//We need to include hidden files just in case the alias starts with '.'
dir.setFilter(QDir::Files | QDir::Hidden);
const auto list = dir.entryList();
QStringList list = dir.entryList();
// Normally there should be only one account when migrating.
AccountState *accountState = AccountManager::instance()->accounts().value(0).data();
for (const auto &alias : list) {
foreach (const QString &alias, list) {
Folder *f = setupFolderFromOldConfigFile(alias, accountState);
if (f) {
scheduleFolder(f);
@@ -508,7 +508,7 @@ Folder *FolderMan::folder(const QString &alias)
void FolderMan::scheduleAllFolders()
{
for (Folder *f : _folderMap.values()) {
foreach (Folder *f, _folderMap.values()) {
if (f && f->canSync()) {
scheduleFolder(f);
}
@@ -595,7 +595,7 @@ void FolderMan::slotRunOneEtagJob()
{
if (_currentEtagJob.isNull()) {
Folder *folder = nullptr;
for (Folder *f : qAsConst(_folderMap)) {
foreach (Folder *f, _folderMap) {
if (f->etagJob()) {
// Caveat: always grabs the first folder with a job, but we think this is Ok for now and avoids us having a seperate queue.
_currentEtagJob = f->etagJob();
@@ -628,7 +628,7 @@ void FolderMan::slotAccountStateChanged()
if (accountState->isConnected()) {
qCInfo(lcFolderMan) << "Account" << accountName << "connected, scheduling its folders";
for (Folder *f : _folderMap.values()) {
foreach (Folder *f, _folderMap.values()) {
if (f
&& f->canSync()
&& f->accountState() == accountState) {
@@ -758,7 +758,7 @@ void FolderMan::slotEtagPollTimerTimeout()
ConfigFile cfg;
auto polltime = cfg.remotePollInterval();
for (Folder *f : qAsConst(_folderMap)) {
foreach (Folder *f, _folderMap) {
if (!f) {
continue;
}
@@ -793,7 +793,7 @@ void FolderMan::slotRemoveFoldersForAccount(AccountState *accountState)
}
}
for (const auto &f : qAsConst(foldersToRemove)) {
foreach (const auto &f, foldersToRemove) {
removeFolder(f);
}
emit folderListChanged(_folderMap);
@@ -813,7 +813,7 @@ void FolderMan::slotServerVersionChanged(Account *account)
qCWarning(lcFolderMan) << "The server version is unsupported:" << account->serverVersion()
<< "pausing all folders on the account";
for (auto &f : qAsConst(_folderMap)) {
foreach (auto &f, _folderMap) {
if (f->accountState()->account().data() == account) {
f->setSyncPaused(true);
}
@@ -830,7 +830,7 @@ void FolderMan::slotWatchedFileUnlocked(const QString &path)
void FolderMan::slotScheduleFolderByTime()
{
for (const auto &f : qAsConst(_folderMap)) {
foreach (auto &f, _folderMap) {
// Never schedule if syncing is disabled or when we're currently
// querying the server for etags
if (!f->canSync() || f->etagJob()) {
@@ -913,11 +913,13 @@ Folder *FolderMan::addFolder(AccountState *accountState, const FolderDefinition
// Migration: The first account that's configured for a local folder shall
// be saved in a backwards-compatible way.
const auto folderList = FolderMan::instance()->map();
const auto oneAccountOnly = std::none_of(folderList.cbegin(), folderList.cend(), [this, folder](const auto *other) {
return other != folder && other->cleanPath() == folder->cleanPath();
});
bool oneAccountOnly = true;
foreach (Folder *other, FolderMan::instance()->map()) {
if (other != folder && other->cleanPath() == folder->cleanPath()) {
oneAccountOnly = false;
break;
}
}
folder->setSaveBackwardsCompatible(oneAccountOnly);
if (folder) {
@@ -974,20 +976,22 @@ Folder *FolderMan::folderForPath(const QString &path)
{
QString absolutePath = QDir::cleanPath(path) + QLatin1Char('/');
const auto folders = this->map().values();
const auto it = std::find_if(folders.cbegin(), folders.cend(), [absolutePath](const auto *folder) {
foreach (Folder *folder, this->map().values()) {
const QString folderPath = folder->cleanPath() + QLatin1Char('/');
return absolutePath.startsWith(folderPath, (Utility::isWindows() || Utility::isMac()) ? Qt::CaseInsensitive : Qt::CaseSensitive);
});
return it != folders.cend() ? *it : nullptr;
if (absolutePath.startsWith(folderPath, (Utility::isWindows() || Utility::isMac()) ? Qt::CaseInsensitive : Qt::CaseSensitive)) {
return folder;
}
}
return nullptr;
}
QStringList FolderMan::findFileInLocalFolders(const QString &relPath, const AccountPtr acc)
{
QStringList re;
for (Folder *folder : this->map().values()) {
foreach (Folder *folder, this->map().values()) {
if (acc && folder->accountState()->account() != acc) {
continue;
}
@@ -1130,7 +1134,7 @@ void FolderMan::slotWipeFolderForAccount(AccountState *accountState)
}
bool success = false;
for (const auto &f : qAsConst(foldersToRemove)) {
foreach (const auto &f, foldersToRemove) {
if (!f) {
qCCritical(lcFolderMan) << "Can not remove null folder";
return;
@@ -1186,7 +1190,7 @@ void FolderMan::slotWipeFolderForAccount(AccountState *accountState)
void FolderMan::setDirtyProxy()
{
for (const Folder *f : _folderMap.values()) {
foreach (Folder *f, _folderMap.values()) {
if (f) {
if (f->accountState() && f->accountState()->account()
&& f->accountState()->account()->networkAccessManager()) {
@@ -1200,7 +1204,7 @@ void FolderMan::setDirtyProxy()
void FolderMan::setDirtyNetworkLimits()
{
for (Folder *f : _folderMap.values()) {
foreach (Folder *f, _folderMap.values()) {
// set only in busy folders. Otherwise they read the config anyway.
if (f && f->isBusy()) {
f->setDirtyNetworkLimits();
@@ -1251,7 +1255,7 @@ void FolderMan::trayOverallStatus(const QList<Folder *> &folders,
int runSeen = 0;
int various = 0;
for (const Folder *folder : qAsConst(folders)) {
foreach (Folder *folder, folders) {
SyncResult folderResult = folder->syncResult();
if (folder->syncPaused()) {
abortOrPausedSeen++;
@@ -1474,7 +1478,7 @@ void FolderMan::setIgnoreHiddenFiles(bool ignore)
{
// Note that the setting will revert to 'true' if all folders
// are deleted...
for (Folder *folder : qAsConst(_folderMap)) {
foreach (Folder *folder, _folderMap) {
folder->setIgnoreHiddenFiles(ignore);
folder->saveToSettings();
}

View File

@@ -102,7 +102,7 @@ void FolderStatusModel::setAccountState(const AccountState *accountState)
Qt::ItemFlags FolderStatusModel::flags(const QModelIndex &index) const
{
if (!_accountState) {
return {};
return nullptr;
}
switch (classify(index)) {
case AddButton: {
@@ -120,7 +120,7 @@ Qt::ItemFlags FolderStatusModel::flags(const QModelIndex &index) const
case SubFolder:
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
}
return {};
return nullptr;
}
QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
@@ -250,7 +250,9 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
if (f->syncPaused()) {
return theme->folderDisabledIcon();
} else {
if (status == SyncResult::SyncPrepare || status == SyncResult::Undefined) {
if (status == SyncResult::SyncPrepare) {
return theme->syncStateIcon(SyncResult::SyncRunning);
} else if (status == SyncResult::Undefined) {
return theme->syncStateIcon(SyncResult::SyncRunning);
} else {
// The "Problem" *result* just means some files weren't
@@ -407,6 +409,24 @@ FolderStatusModel::SubFolderInfo *FolderStatusModel::infoForIndex(const QModelIn
}
}
/* Recursivelly traverse the file info looking for the id */
FolderStatusModel::SubFolderInfo *FolderStatusModel::infoForFileId(const QByteArray& fileId, SubFolderInfo* info) const
{
const QVector<SubFolderInfo>& infoVec = info ? info->_subs : _folders;
for(int i = 0, end = infoVec.size(); i < end; i++) {
auto *info = const_cast<SubFolderInfo *>(&infoVec[i]);
if (info->_fileId == fileId) {
return info;
} else if (info->_subs.size()) {
if (auto *subInfo = infoForFileId(fileId, info)) {
return subInfo;
}
}
}
return nullptr;
}
QModelIndex FolderStatusModel::indexForPath(Folder *f, const QString &path) const
{
if (!f) {
@@ -728,8 +748,8 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
endInsertRows();
}
for (int undecidedIndex : qAsConst(undecidedIndexes)) {
suggestExpand(index(undecidedIndex, 0, idx));
for (auto it = undecidedIndexes.begin(); it != undecidedIndexes.end(); ++it) {
suggestExpand(index(*it, 0, idx));
}
/* We need lambda function for the following code.
@@ -1070,7 +1090,7 @@ void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
auto &pi = _folders[folderIndex]._progress;
SyncResult::Status state = f->syncResult().status();
if (!f->canSync() || state == SyncResult::Problem || state == SyncResult::Success || state == SyncResult::Error) {
if (!f->canSync()) {
// Reset progress info.
pi = SubFolderInfo::Progress();
} else if (state == SyncResult::NotYetStarted) {
@@ -1091,6 +1111,11 @@ void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
} else if (state == SyncResult::SyncPrepare) {
pi = SubFolderInfo::Progress();
pi._overallSyncString = tr("Preparing to sync …");
} else if (state == SyncResult::Problem || state == SyncResult::Success) {
// Reset the progress info after a sync.
pi = SubFolderInfo::Progress();
} else if (state == SyncResult::Error) {
pi = SubFolderInfo::Progress();
}
// update the icon etc. now

View File

@@ -105,6 +105,7 @@ public:
FetchLabel };
ItemType classify(const QModelIndex &index) const;
SubFolderInfo *infoForIndex(const QModelIndex &index) const;
SubFolderInfo *infoForFileId(const QByteArray &fileId, SubFolderInfo *info = nullptr) const;
// If the selective sync check boxes were changed
bool isDirty() { return _dirty; }

View File

@@ -15,7 +15,7 @@
// event masks
#include "folderwatcher.h"
#include <cstdint>
#include <stdint.h>
#include <QFileInfo>
#include <QFlags>
@@ -33,7 +33,6 @@
#endif
#include "folder.h"
#include "filesystem.h"
namespace OCC {
@@ -61,7 +60,7 @@ bool FolderWatcher::pathIsIgnored(const QString &path)
return false;
#ifndef OWNCLOUD_TEST
if (_folder->isFileExcludedAbsolute(path) && !Utility::isConflictFile(path)) {
if (_folder->isFileExcludedAbsolute(path)) {
qCDebug(lcFolderWatcher) << "* Ignoring file" << path;
return true;
}
@@ -87,57 +86,6 @@ void FolderWatcher::appendSubPaths(QDir dir, QStringList& subPaths) {
}
}
void FolderWatcher::startNotificatonTest(const QString &path)
{
#ifdef Q_OS_MAC
// Testing the folder watcher on OSX is harder because the watcher
// automatically discards changes that were performed by our process.
// It would still be useful to test but the OSX implementation
// is deferred until later.
return;
#endif
Q_ASSERT(_testNotificationPath.isEmpty());
_testNotificationPath = path;
// Don't do the local file modification immediately:
// wait for FolderWatchPrivate::_ready
startNotificationTestWhenReady();
}
void FolderWatcher::startNotificationTestWhenReady()
{
if (!_d->_ready) {
QTimer::singleShot(1000, this, &FolderWatcher::startNotificationTestWhenReady);
return;
}
auto path = _testNotificationPath;
if (QFile::exists(path)) {
auto mtime = FileSystem::getModTime(path);
FileSystem::setModTime(path, mtime + 1);
} else {
QFile f(path);
f.open(QIODevice::WriteOnly | QIODevice::Append);
}
QTimer::singleShot(5000, this, [this]() {
if (!_testNotificationPath.isEmpty())
emit becameUnreliable(tr("The watcher did not receive a test notification."));
_testNotificationPath.clear();
});
}
int FolderWatcher::testLinuxWatchCount() const
{
#ifdef Q_OS_LINUX
return _d->testWatchCount();
#else
return -1;
#endif
}
void FolderWatcher::changeDetected(const QString &path)
{
QFileInfo fileInfo(path);
@@ -170,10 +118,6 @@ void FolderWatcher::changeDetected(const QStringList &paths)
// ------- handle ignores:
for (int i = 0; i < paths.size(); ++i) {
QString path = paths[i];
if (!_testNotificationPath.isEmpty()
&& Utility::fileNamesEqual(path, _testNotificationPath)) {
_testNotificationPath.clear();
}
if (pathIsIgnored(path)) {
continue;
}
@@ -190,4 +134,15 @@ void FolderWatcher::changeDetected(const QStringList &paths)
}
}
void FolderWatcher::addPath(const QString &path)
{
_d->addPath(path);
}
void FolderWatcher::removePath(const QString &path)
{
_d->removePath(path);
}
} // namespace OCC

View File

@@ -22,7 +22,7 @@
#include <QObject>
#include <QString>
#include <QStringList>
#include <QElapsedTimer>
#include <QTime>
#include <QHash>
#include <QScopedPointer>
#include <QSet>
@@ -44,6 +44,11 @@ class Folder;
* for changes in the local file system. Changes are signalled
* through the pathChanged() signal.
*
* Note that if new folders are created, this folderwatcher class
* does not automatically add them to the list of monitored
* dirs. That is the responsibility of the user of this class to
* call addPath() with the new dir.
*
* @ingroup gui
*/
@@ -60,6 +65,14 @@ public:
*/
void init(const QString &root);
/**
* Not all backends are recursive by default.
* Those need to be notified when a directory is added or removed while the watcher is disabled.
* This is a no-op for backends that are recursive
*/
void addPath(const QString &);
void removePath(const QString &);
/* Check if the path is ignored. */
bool pathIsIgnored(const QString &path);
@@ -72,17 +85,6 @@ public:
*/
bool isReliable() const;
/**
* Triggers a change in the path and verifies a notification arrives.
*
* If no notification is seen, the folderwatcher marks itself as unreliable.
* The path must be ignored by the watcher.
*/
void startNotificatonTest(const QString &path);
/// For testing linux behavior only
int testLinuxWatchCount() const;
signals:
/** Emitted when one of the watched directories or one
* of the contained files is changed. */
@@ -109,24 +111,18 @@ protected slots:
void changeDetected(const QString &path);
void changeDetected(const QStringList &paths);
private slots:
void startNotificationTestWhenReady();
protected:
QHash<QString, int> _pendingPathes;
private:
QScopedPointer<FolderWatcherPrivate> _d;
QElapsedTimer _timer;
QTime _timer;
QSet<QString> _lastPaths;
Folder *_folder;
bool _isReliable = true;
void appendSubPaths(QDir dir, QStringList& subPaths);
/** Path of the expected test notification */
QString _testNotificationPath;
friend class FolderWatcherPrivate;
};
}

View File

@@ -71,37 +71,34 @@ bool FolderWatcherPrivate::findFoldersBelow(const QDir &dir, QStringList &fullLi
void FolderWatcherPrivate::inotifyRegisterPath(const QString &path)
{
if (path.isEmpty())
return;
int wd = inotify_add_watch(_fd, path.toUtf8().constData(),
IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_ONLYDIR);
if (wd > -1) {
_watchToPath.insert(wd, path);
_pathToWatch.insert(path, wd);
} else {
// If we're running out of memory or inotify watches, become
// unreliable.
if (_parent->_isReliable && (errno == ENOMEM || errno == ENOSPC)) {
_parent->_isReliable = false;
emit _parent->becameUnreliable(
tr("This problem usually happens when the inotify watches are exhausted. "
"Check the FAQ for details."));
if (!path.isEmpty()) {
int wd = inotify_add_watch(_fd, path.toUtf8().constData(),
IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_ONLYDIR);
if (wd > -1) {
_watches.insert(wd, path);
} else {
// If we're running out of memory or inotify watches, become
// unreliable.
if (_parent->_isReliable && (errno == ENOMEM || errno == ENOSPC)) {
_parent->_isReliable = false;
emit _parent->becameUnreliable(
tr("This problem usually happens when the inotify watches are exhausted. "
"Check the FAQ for details."));
}
}
}
}
void FolderWatcherPrivate::slotAddFolderRecursive(const QString &path)
{
if (_pathToWatch.contains(path))
return;
int subdirs = 0;
qCDebug(lcFolderWatcher) << "(+) Watcher:" << path;
QDir inPath(path);
inotifyRegisterPath(inPath.absolutePath());
const QStringList watchedFolders = _watches.values();
QStringList allSubfolders;
if (!findFoldersBelow(QDir(path), allSubfolders)) {
qCWarning(lcFolderWatcher) << "Could not traverse all sub folders";
@@ -110,7 +107,7 @@ void FolderWatcherPrivate::slotAddFolderRecursive(const QString &path)
while (subfoldersIt.hasNext()) {
QString subfolder = subfoldersIt.next();
QDir folder(subfolder);
if (folder.exists() && !_pathToWatch.contains(folder.absolutePath())) {
if (folder.exists() && !watchedFolders.contains(folder.absolutePath())) {
subdirs++;
if (_parent->pathIsIgnored(subfolder)) {
qCDebug(lcFolderWatcher) << "* Not adding" << folder.path();
@@ -131,89 +128,81 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
{
int len = 0;
struct inotify_event *event = nullptr;
size_t i = 0;
int i = 0;
int error = 0;
QVarLengthArray<char, 2048> buffer(2048);
len = read(fd, buffer.data(), buffer.size());
error = errno;
/**
* From inotify documentation:
*
* The behavior when the buffer given to read(2) is too
* small to return information about the next event
* depends on the kernel version: in kernels before 2.6.21,
* read(2) returns 0; since kernel 2.6.21, read(2) fails with
* the error EINVAL.
*/
while (len < 0 && error == EINVAL) {
// double the buffer size
buffer.resize(buffer.size() * 2);
/* and try again ... */
do {
len = read(fd, buffer.data(), buffer.size());
error = errno;
}
/**
* From inotify documentation:
*
* The behavior when the buffer given to read(2) is too
* small to return information about the next event
* depends on the kernel version: in kernels before 2.6.21,
* read(2) returns 0; since kernel 2.6.21, read(2) fails with
* the error EINVAL.
*/
if (len < 0 && error == EINVAL) {
// double the buffer size
buffer.resize(buffer.size() * 2);
/* and try again ... */
continue;
}
} while (false);
// iterate events in buffer
unsigned int ulen = len;
for (i = 0; i + sizeof(inotify_event) < ulen; i += sizeof(inotify_event) + (event ? event->len : 0)) {
// reset counter
i = 0;
// while there are enough events in the buffer
while (i + sizeof(struct inotify_event) < static_cast<unsigned int>(len)) {
// cast an inotify_event
event = (struct inotify_event *)&buffer[i];
if (!event) {
qCDebug(lcFolderWatcher) << "NULL event";
i += sizeof(struct inotify_event);
continue;
}
// Fire event for the path that was changed.
if (event->len == 0 || event->wd <= -1)
continue;
QByteArray fileName(event->name);
// Filter out journal changes - redundant with filtering in
// FolderWatcher::pathIsIgnored.
if (fileName.startsWith("._sync_")
|| fileName.startsWith(".csync_journal.db")
|| fileName.startsWith(".sync_")) {
continue;
if (event->len > 0 && event->wd > -1) {
QByteArray fileName(event->name);
if (fileName.startsWith("._sync_")
|| fileName.startsWith(".csync_journal.db")
|| fileName.startsWith(".owncloudsync.log")
|| fileName.startsWith(".sync_")) {
} else {
const QString p = _watches[event->wd] + '/' + fileName;
_parent->changeDetected(p);
}
}
const QString p = _watchToPath[event->wd] + '/' + fileName;
_parent->changeDetected(p);
if ((event->mask & (IN_MOVED_TO | IN_CREATE))
&& QFileInfo(p).isDir()
&& !_parent->pathIsIgnored(p)) {
slotAddFolderRecursive(p);
}
if (event->mask & (IN_MOVED_FROM | IN_DELETE)) {
removeFoldersBelow(p);
}
// increment counter
i += sizeof(struct inotify_event) + event->len;
}
}
void FolderWatcherPrivate::removeFoldersBelow(const QString &path)
void FolderWatcherPrivate::addPath(const QString &path)
{
auto it = _pathToWatch.find(path);
if (it == _pathToWatch.end())
return;
slotAddFolderRecursive(path);
}
QString pathSlash = path + '/';
void FolderWatcherPrivate::removePath(const QString &path)
{
int wid = -1;
// Remove the inotify watch.
QHash<int, QString>::const_iterator i = _watches.constBegin();
// Remove the entry and all subentries
while (it != _pathToWatch.end()) {
auto itPath = it.key();
if (!itPath.startsWith(path))
while (i != _watches.constEnd()) {
if (i.value() == path) {
wid = i.key();
break;
if (itPath != path && !itPath.startsWith(pathSlash)) {
// order is 'foo', 'foo bar', 'foo/bar'
++it;
continue;
}
auto wid = it.value();
++i;
}
if (wid > -1) {
inotify_rm_watch(_fd, wid);
_watchToPath.remove(wid);
it = _pathToWatch.erase(it);
qCDebug(lcFolderWatcher) << "Removed watch for" << itPath;
_watches.remove(wid);
}
}

View File

@@ -23,8 +23,6 @@
#include "folderwatcher.h"
class QTimer;
namespace OCC {
/**
@@ -35,14 +33,12 @@ class FolderWatcherPrivate : public QObject
{
Q_OBJECT
public:
FolderWatcherPrivate() = default;
FolderWatcherPrivate() {}
FolderWatcherPrivate(FolderWatcher *p, const QString &path);
~FolderWatcherPrivate();
int testWatchCount() const { return _pathToWatch.size(); }
/// On linux the watcher is ready when the ctor finished.
bool _ready = true;
void addPath(const QString &path);
void removePath(const QString &);
protected slots:
void slotReceivedNotification(int fd);
@@ -51,14 +47,12 @@ protected slots:
protected:
bool findFoldersBelow(const QDir &dir, QStringList &fullList);
void inotifyRegisterPath(const QString &path);
void removeFoldersBelow(const QString &path);
private:
FolderWatcher *_parent;
QString _folder;
QHash<int, QString> _watchToPath;
QMap<QString, int> _pathToWatch;
QHash<int, QString> _watches;
QScopedPointer<QSocketNotifier> _socket;
int _fd;
};

View File

@@ -33,13 +33,13 @@ public:
FolderWatcherPrivate(FolderWatcher *p, const QString &path);
~FolderWatcherPrivate();
void addPath(const QString &) {}
void removePath(const QString &) {}
void startWatching();
QStringList addCoalescedPaths(const QStringList &) const;
void doNotifyParent(const QStringList &);
/// On OSX the watcher is ready when the ctor finished.
bool _ready = true;
private:
FolderWatcher *_parent;

View File

@@ -84,8 +84,6 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
break;
}
emit ready();
HANDLE handles[] = { _resultEvent, _stopEvent };
DWORD result = WaitForMultipleObjects(
2, handles,
@@ -141,8 +139,6 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
if (!skip) {
emit changed(longfile);
} else {
qCDebug(lcFolderWatcher) << "Skipping syncing of" << longfile;
}
if (curEntry->NextEntryOffset == 0) {
@@ -208,8 +204,6 @@ FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p, const QString &path
_parent, SLOT(changeDetected(const QString &)));
connect(_thread, SIGNAL(lostChanges()),
_parent, SIGNAL(lostChanges()));
connect(_thread, &WatcherThread::ready,
this, [this]() { _ready = 1; });
_thread->start();
}

View File

@@ -54,7 +54,6 @@ protected:
signals:
void changed(const QString &path);
void lostChanges();
void ready();
private:
QString _path;
@@ -75,8 +74,8 @@ public:
FolderWatcherPrivate(FolderWatcher *p, const QString &path);
~FolderWatcherPrivate();
/// Set to non-zero once the WatcherThread is capturing events.
QAtomicInt _ready;
void addPath(const QString &) {}
void removePath(const QString &) {}
private:
FolderWatcher *_parent;

View File

@@ -37,7 +37,7 @@
#include <QVBoxLayout>
#include <QEvent>
#include <cstdlib>
#include <stdlib.h>
namespace OCC {

View File

@@ -26,28 +26,18 @@
#if defined(BUILD_UPDATER)
#include "updater/updater.h"
#include "updater/ocupdater.h"
#ifdef Q_OS_MAC
// FIXME We should unify those, but Sparkle does everything behind the scene transparently
#include "updater/sparkleupdater.h"
#endif
#endif
#include "ignorelisteditor.h"
#include "common/utility.h"
#include "logger.h"
#include "config.h"
#include "legalnotice.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QNetworkProxy>
#include <QDir>
#include <QScopedValueRollback>
#include <QMessageBox>
#include <private/qzipwriter_p.h>
#define QTLEGACY (QT_VERSION < QT_VERSION_CHECK(5,9,0))
@@ -55,87 +45,6 @@
#include <QOperatingSystemVersion>
#endif
namespace {
struct ZipEntry {
QString localFilename;
QString zipFilename;
};
ZipEntry fileInfoToZipEntry(const QFileInfo &info)
{
return {
info.absoluteFilePath(),
info.fileName()
};
}
ZipEntry fileInfoToLogZipEntry(const QFileInfo &info)
{
auto entry = fileInfoToZipEntry(info);
entry.zipFilename.prepend(QStringLiteral("logs/"));
return entry;
}
ZipEntry syncFolderToZipEntry(OCC::Folder *f)
{
const auto journalPath = f->journalDb()->databaseFilePath();
const auto journalInfo = QFileInfo(journalPath);
return fileInfoToZipEntry(journalInfo);
}
QVector<ZipEntry> createFileList()
{
auto list = QVector<ZipEntry>();
OCC::ConfigFile cfg;
list.append(fileInfoToZipEntry(QFileInfo(cfg.configFile())));
const auto logger = OCC::Logger::instance();
if (!logger->logDir().isEmpty()) {
list.append({QString(), QStringLiteral("logs")});
QDir dir(logger->logDir());
const auto infoList = dir.entryInfoList(QDir::Files);
std::transform(std::cbegin(infoList), std::cend(infoList),
std::back_inserter(list),
fileInfoToLogZipEntry);
} else if (!logger->logFile().isEmpty()) {
list.append(fileInfoToZipEntry(QFileInfo(logger->logFile())));
}
const auto folders = OCC::FolderMan::instance()->map().values();
std::transform(std::cbegin(folders), std::cend(folders),
std::back_inserter(list),
syncFolderToZipEntry);
return list;
}
void createDebugArchive(const QString &filename)
{
const auto entries = createFileList();
QZipWriter zip(filename);
for (const auto &entry : entries) {
if (entry.localFilename.isEmpty()) {
zip.addDirectory(entry.zipFilename);
} else {
QFile file(entry.localFilename);
if (!file.open(QFile::ReadOnly)) {
continue;
}
zip.addFile(entry.zipFilename, &file);
}
}
zip.addFile("__nextcloud_client_parameters.txt", QCoreApplication::arguments().join(' ').toUtf8());
const auto buildInfo = QString(OCC::Theme::instance()->about() + "\n\n" + OCC::Theme::instance()->aboutDetails());
zip.addFile("__nextcloud_client_buildinfo.txt", buildInfo.toUtf8());
}
}
namespace OCC {
GeneralSettings::GeneralSettings(QWidget *parent)
@@ -213,7 +122,6 @@ GeneralSettings::GeneralSettings(QWidget *parent)
_ui->monoIconsCheckBox->setVisible(Theme::instance()->monoIconsAvailable());
connect(_ui->ignoredFilesButton, &QAbstractButton::clicked, this, &GeneralSettings::slotIgnoreFilesEditor);
connect(_ui->debugArchiveButton, &QAbstractButton::clicked, this, &GeneralSettings::slotCreateDebugArchive);
// accountAdded means the wizard was finished and the wizard might change some options.
connect(AccountManager::instance(), &AccountManager::accountAdded, this, &GeneralSettings::loadMiscSettings);
@@ -253,88 +161,34 @@ void GeneralSettings::loadMiscSettings()
#if defined(BUILD_UPDATER)
void GeneralSettings::slotUpdateInfo()
{
if (ConfigFile().skipUpdateCheck() || !Updater::instance()) {
// updater disabled on compile
_ui->updatesGroupBox->setVisible(false);
return;
// Note: the sparkle-updater is not an OCUpdater
auto *updater = qobject_cast<OCUpdater *>(Updater::instance());
if (ConfigFile().skipUpdateCheck()) {
updater = nullptr; // don't show update info if updates are disabled
}
// Note: the sparkle-updater is not an OCUpdater
auto *ocupdater = qobject_cast<OCUpdater *>(Updater::instance());
if (ocupdater) {
connect(ocupdater, &OCUpdater::downloadStateChanged, this, &GeneralSettings::slotUpdateInfo, Qt::UniqueConnection);
connect(_ui->restartButton, &QAbstractButton::clicked, ocupdater, &OCUpdater::slotStartInstaller, Qt::UniqueConnection);
if (updater) {
connect(updater, &OCUpdater::downloadStateChanged, this, &GeneralSettings::slotUpdateInfo, Qt::UniqueConnection);
connect(_ui->restartButton, &QAbstractButton::clicked, updater, &OCUpdater::slotStartInstaller, Qt::UniqueConnection);
connect(_ui->restartButton, &QAbstractButton::clicked, qApp, &QApplication::quit, Qt::UniqueConnection);
connect(_ui->updateButton, &QAbstractButton::clicked, this, &GeneralSettings::slotUpdateCheckNow, Qt::UniqueConnection);
connect(_ui->autoCheckForUpdatesCheckBox, &QAbstractButton::toggled, this, &GeneralSettings::slotToggleAutoUpdateCheck);
QString status = ocupdater->statusString();
QString status = updater->statusString();
Theme::replaceLinkColorStringBackgroundAware(status);
_ui->updateStateLabel->setText(status);
_ui->restartButton->setVisible(ocupdater->downloadState() == OCUpdater::DownloadComplete);
_ui->restartButton->setVisible(updater->downloadState() == OCUpdater::DownloadComplete);
_ui->updateButton->setEnabled(ocupdater->downloadState() != OCUpdater::CheckingServer &&
ocupdater->downloadState() != OCUpdater::Downloading &&
ocupdater->downloadState() != OCUpdater::DownloadComplete);
_ui->updateButton->setEnabled(updater->downloadState() != OCUpdater::CheckingServer &&
updater->downloadState() != OCUpdater::Downloading &&
updater->downloadState() != OCUpdater::DownloadComplete);
_ui->autoCheckForUpdatesCheckBox->setChecked(ConfigFile().autoUpdateCheck());
} else {
// can't have those infos from sparkle currently
_ui->updatesGroupBox->setVisible(false);
}
#if defined(Q_OS_MAC) && defined(HAVE_SPARKLE)
else if (auto sparkleUpdater = qobject_cast<SparkleUpdater *>(Updater::instance())) {
_ui->updateStateLabel->setText(sparkleUpdater->statusString());
_ui->restartButton->setVisible(false);
}
#endif
// Channel selection
_ui->updateChannel->setCurrentIndex(ConfigFile().updateChannel() == "beta" ? 1 : 0);
connect(_ui->updateChannel, &QComboBox::currentTextChanged,
this, &GeneralSettings::slotUpdateChannelChanged, Qt::UniqueConnection);
}
void GeneralSettings::slotUpdateChannelChanged(const QString &channel)
{
if (channel == ConfigFile().updateChannel())
return;
auto msgBox = new QMessageBox(
QMessageBox::Warning,
tr("Change update channel?"),
tr("The update channel determines which client updates will be offered "
"for installation. The \"stable\" channel contains only upgrades that "
"are considered reliable, while the versions in the \"beta\" channel "
"may contain newer features and bugfixes, but have not yet been tested "
"thoroughly."
"\n\n"
"Note that this selects only what pool upgrades are taken from, and that "
"there are no downgrades: So going back from the beta channel to "
"the stable channel usually cannot be done immediately and means waiting "
"for a stable version that is newer than the currently installed beta "
"version."),
QMessageBox::NoButton,
this);
msgBox->addButton(tr("Change update channel"), QMessageBox::AcceptRole);
msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
connect(msgBox, &QMessageBox::finished, msgBox, [this, channel, msgBox](int result) {
msgBox->deleteLater();
if (result == QMessageBox::AcceptRole) {
ConfigFile().setUpdateChannel(channel);
if (auto updater = qobject_cast<OCUpdater *>(Updater::instance())) {
updater->setUpdateUrl(Updater::updateUrl());
updater->checkForUpdate();
}
#if defined(Q_OS_MAC) && defined(HAVE_SPARKLE)
else if (auto updater = qobject_cast<SparkleUpdater *>(Updater::instance())) {
updater->setUpdateUrl(Updater::updateUrl());
updater->checkForUpdate();
}
#endif
} else {
_ui->updateChannel->setCurrentText(ConfigFile().updateChannel());
}
});
msgBox->open();
}
void GeneralSettings::slotUpdateCheckNow()
@@ -406,17 +260,6 @@ void GeneralSettings::slotIgnoreFilesEditor()
}
}
void GeneralSettings::slotCreateDebugArchive()
{
const auto filename = QFileDialog::getSaveFileName(this, tr("Create Debug Archive"), QString(), tr("Zip Archives") + " (*.zip)");
if (filename.isEmpty()) {
return;
}
createDebugArchive(filename);
QMessageBox::information(this, tr("Debug Archive Created"), tr("Debug archive is created at %1").arg(filename));
}
void GeneralSettings::slotShowLegalNotice()
{
auto notice = new LegalNotice();

View File

@@ -48,12 +48,10 @@ private slots:
void slotToggleOptionalServerNotifications(bool);
void slotShowInExplorerNavigationPane(bool);
void slotIgnoreFilesEditor();
void slotCreateDebugArchive();
void loadMiscSettings();
void slotShowLegalNotice();
#if defined(BUILD_UPDATER)
void slotUpdateInfo();
void slotUpdateChannelChanged(const QString &channel);
void slotUpdateCheckNow();
void slotToggleAutoUpdateCheck();
#endif

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>553</width>
<height>558</height>
<width>516</width>
<height>523</height>
</rect>
</property>
<property name="windowTitle">
@@ -124,46 +124,26 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="updateChannelLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Channel</string>
</property>
<property name="buddy">
<cstring>updateChannel</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="updateChannel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>stable</string>
</property>
</item>
<item>
<property name="text">
<string>beta</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="updateStateLabel">
<property name="text">
@@ -190,6 +170,22 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
@@ -223,13 +219,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="debugArchiveButton">
<property name="text">
<string>Create Debug Archive …</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">

View File

@@ -73,7 +73,7 @@ class HeaderBanner : public QWidget
{
Q_OBJECT
public:
HeaderBanner(QWidget *parent = nullptr);
HeaderBanner(QWidget *parent = 0);
void setup(const QString &title, const QPixmap &logo, const QPixmap &banner,
const Qt::TextFormat titleFormat, const QString &styleSheet);

View File

@@ -14,7 +14,7 @@
#include "logbrowser.h"
#include <cstdio>
#include "stdio.h"
#include <iostream>
#include <QDialogButtonBox>

View File

@@ -15,7 +15,7 @@
#include <QtGlobal>
#include <cmath>
#include <csignal>
#include <signal.h>
#ifdef Q_OS_UNIX
#include <sys/time.h>

View File

@@ -66,18 +66,17 @@ void NavigationPaneHelper::updateCloudStorageRegistry()
// that matches ours when we saved.
QVector<QUuid> entriesToRemove;
#ifdef Q_OS_WIN
QString nameSpaceKey = QStringLiteral(R"(Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace)");
if (Utility::registryKeyExists(HKEY_CURRENT_USER, nameSpaceKey)) {
Utility::registryWalkSubKeys(HKEY_CURRENT_USER, nameSpaceKey,
[&entriesToRemove](HKEY key, const QString &subKey) {
QVariant appName = Utility::registryGetKeyValue(key, subKey, QStringLiteral("ApplicationName"));
if (appName.toString() == QLatin1String(APPLICATION_NAME)) {
QUuid clsid{ subKey };
Q_ASSERT(!clsid.isNull());
entriesToRemove.append(clsid);
}
});
}
Utility::registryWalkSubKeys(
HKEY_CURRENT_USER,
QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace"),
[&entriesToRemove](HKEY key, const QString &subKey) {
QVariant appName = Utility::registryGetKeyValue(key, subKey, QStringLiteral("ApplicationName"));
if (appName.toString() == QLatin1String(APPLICATION_NAME)) {
QUuid clsid{ subKey };
Q_ASSERT(!clsid.isNull());
entriesToRemove.append(clsid);
}
});
#endif
// Only save folder entries if the option is enabled.
@@ -139,7 +138,7 @@ void NavigationPaneHelper::updateCloudStorageRegistry()
// Step 11: Register your extension in the namespace root
Utility::registrySetKeyValue(HKEY_CURRENT_USER, namespacePath, QString(), REG_SZ, title);
// Step 12: Hide your extension from the Desktop
Utility::registrySetKeyValue(HKEY_CURRENT_USER, QStringLiteral(R"(Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel)"), clsidStr, REG_DWORD, 0x1);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\HideDesktopIcons\\NewStartPanel"), clsidStr, REG_DWORD, 0x1);
// For us, to later be able to iterate and find our own namespace entries and associated CLSID.
// Use the macro instead of the theme to make sure it matches with the uninstaller.

View File

@@ -28,8 +28,7 @@ OcsShareeJob::OcsShareeJob(AccountPtr account)
void OcsShareeJob::getSharees(const QString &search,
const QString &itemType,
int page,
int perPage,
bool lookup)
int perPage)
{
setVerb("GET");
@@ -37,7 +36,6 @@ void OcsShareeJob::getSharees(const QString &search,
addParam(QString::fromLatin1("itemType"), itemType);
addParam(QString::fromLatin1("page"), QString::number(page));
addParam(QString::fromLatin1("perPage"), QString::number(perPage));
addParam(QString::fromLatin1("lookup"), QVariant(lookup).toString());
start();
}

View File

@@ -38,7 +38,7 @@ public:
*
* @param path Path to request shares for (default all shares)
*/
void getSharees(const QString &search, const QString &itemType, int page = 1, int perPage = 50, bool lookup = false);
void getSharees(const QString &search, const QString &itemType, int page = 1, int perPage = 50);
signals:
/**
* Result of the OCS request

View File

@@ -144,7 +144,6 @@ void OcsShareJob::createShare(const QString &path,
const QString &shareWith,
const Share::Permissions permissions)
{
Q_UNUSED(permissions)
setVerb("POST");
addParam(QString::fromLatin1("path"), path);

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